@wix/himalaya-cli 0.1309.0 → 0.1311.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/delivery-contract.d.ts +3 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/delivery.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/host-session.d.ts +31 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/index.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-contract.d.ts +39 -15
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-wire.d.ts +2 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments.d.ts +11 -12
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +13 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/apple-iap-contract.d.ts +17 -9
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/iap-order-backend.d.ts +6 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap-checkout.mjs +119 -65
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap.mjs +125 -35
- package/dist/cli.mjs +1286 -677
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/himi-json-output.md +29 -1
- package/guides/iap-products.md +51 -2
- package/guides/qa-builds.md +16 -12
- package/guides/sdk-reference.json +80 -26
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -2554,7 +2554,7 @@ function commitChange(repo, base, branch, rel, body) {
|
|
|
2554
2554
|
return validationDiffHash(repo);
|
|
2555
2555
|
}
|
|
2556
2556
|
function runSelfTest() {
|
|
2557
|
-
let
|
|
2557
|
+
let failed3 = 0;
|
|
2558
2558
|
for (const testCase of SELF_TEST_CASES) {
|
|
2559
2559
|
let ok2 = false;
|
|
2560
2560
|
let thrown = null;
|
|
@@ -2568,12 +2568,12 @@ function runSelfTest() {
|
|
|
2568
2568
|
`);
|
|
2569
2569
|
continue;
|
|
2570
2570
|
}
|
|
2571
|
-
|
|
2571
|
+
failed3++;
|
|
2572
2572
|
process.stderr.write(` \u2717 ${testCase.name}
|
|
2573
2573
|
${thrown ?? testCase.reason}
|
|
2574
2574
|
`);
|
|
2575
2575
|
}
|
|
2576
|
-
return
|
|
2576
|
+
return failed3;
|
|
2577
2577
|
}
|
|
2578
2578
|
var VALIDATION_METADATA, SELF_TEST_CASES;
|
|
2579
2579
|
var init_diff_hash = __esm({
|
|
@@ -2653,10 +2653,10 @@ var init_diff_hash = __esm({
|
|
|
2653
2653
|
if (process.argv[1] && basename(process.argv[1]) === "diff-hash.mjs" && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
2654
2654
|
if (process.argv.slice(2).includes("--self-test")) {
|
|
2655
2655
|
process.stdout.write("\u25B8 diff-hash --self-test: proving the identity can change, and can hold\n");
|
|
2656
|
-
const
|
|
2657
|
-
if (
|
|
2656
|
+
const failed3 = runSelfTest();
|
|
2657
|
+
if (failed3) {
|
|
2658
2658
|
process.stderr.write(
|
|
2659
|
-
`\u2717 diff-hash self-test FAILED (${
|
|
2659
|
+
`\u2717 diff-hash self-test FAILED (${failed3} case(s)) \u2014 the evidence record's diff identity cannot be trusted
|
|
2660
2660
|
`
|
|
2661
2661
|
);
|
|
2662
2662
|
process.exit(1);
|
|
@@ -3854,10 +3854,10 @@ ${trimmed.slice(0, 300)}` : "It printed nothing.";
|
|
|
3854
3854
|
function mintHelp(label2, detail) {
|
|
3855
3855
|
return `could not run \`${label2}\` (${detail}). Install the Wix CLI and log in (\`npm i -g @wix/cli && wix login\`), or, with no browser, export WIX_API_KEY (manage.wix.com/account/api-keys).`;
|
|
3856
3856
|
}
|
|
3857
|
-
function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2) {
|
|
3857
|
+
function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2, mint = siteToken) {
|
|
3858
3858
|
return async (method, path2, body) => {
|
|
3859
3859
|
const headers2 = {
|
|
3860
|
-
Authorization: await
|
|
3860
|
+
Authorization: await mint(msid),
|
|
3861
3861
|
"wix-site-id": msid,
|
|
3862
3862
|
Accept: "application/json"
|
|
3863
3863
|
};
|
|
@@ -4756,8 +4756,8 @@ function tsExtResolvePlugin() {
|
|
|
4756
4756
|
setup(b2) {
|
|
4757
4757
|
b2.onResolve({ filter: /\.js$/ }, (args) => {
|
|
4758
4758
|
if (args.kind === "entry-point" || !args.path.startsWith(".")) return void 0;
|
|
4759
|
-
const
|
|
4760
|
-
return existsSync8(
|
|
4759
|
+
const ts10 = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
|
|
4760
|
+
return existsSync8(ts10) ? { path: ts10 } : void 0;
|
|
4761
4761
|
});
|
|
4762
4762
|
}
|
|
4763
4763
|
};
|
|
@@ -5492,7 +5492,7 @@ function bundleFor(file2) {
|
|
|
5492
5492
|
const match = /^tier5-src\/([^/]+)\//.exec(file2);
|
|
5493
5493
|
return match?.[1] ?? "_shared";
|
|
5494
5494
|
}
|
|
5495
|
-
function toIssue(
|
|
5495
|
+
function toIssue(ts10, contentDir2, diagnostic) {
|
|
5496
5496
|
const file2 = diagnostic.file ? relativeFile(contentDir2, diagnostic.file.fileName) : void 0;
|
|
5497
5497
|
const position = diagnostic.file && diagnostic.start !== void 0 ? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start) : void 0;
|
|
5498
5498
|
return {
|
|
@@ -5500,13 +5500,13 @@ function toIssue(ts8, contentDir2, diagnostic) {
|
|
|
5500
5500
|
...file2 ? { file: file2 } : {},
|
|
5501
5501
|
...position ? { line: position.line + 1, column: position.character + 1 } : {},
|
|
5502
5502
|
code: `TS${diagnostic.code}`,
|
|
5503
|
-
message:
|
|
5503
|
+
message: ts10.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
5504
5504
|
};
|
|
5505
5505
|
}
|
|
5506
|
-
function confinedHost(
|
|
5506
|
+
function confinedHost(ts10, contentDir2, options) {
|
|
5507
5507
|
if (!buildConfinementRequired()) return void 0;
|
|
5508
|
-
const host =
|
|
5509
|
-
const libDir = resolve10(
|
|
5508
|
+
const host = ts10.createCompilerHost(options);
|
|
5509
|
+
const libDir = resolve10(ts10.getDefaultLibFilePath(options), "..");
|
|
5510
5510
|
const allows = confinementMatcher(contentDir2, [libDir]);
|
|
5511
5511
|
const getSourceFile = host.getSourceFile.bind(host);
|
|
5512
5512
|
const readFile3 = host.readFile.bind(host);
|
|
@@ -5535,7 +5535,7 @@ function confinedHost(ts8, contentDir2, options) {
|
|
|
5535
5535
|
}
|
|
5536
5536
|
async function typecheckContentWorkers(contentDir2, options) {
|
|
5537
5537
|
if (!existsSync9(resolve10(contentDir2, "tier5-src"))) return [];
|
|
5538
|
-
const
|
|
5538
|
+
const ts10 = await compiler2();
|
|
5539
5539
|
const config = {
|
|
5540
5540
|
compilerOptions: {
|
|
5541
5541
|
...CONTENT_WORKER_COMPILER_OPTIONS,
|
|
@@ -5544,18 +5544,18 @@ async function typecheckContentWorkers(contentDir2, options) {
|
|
|
5544
5544
|
// The deployed authoring runtime stages TypeScript 6, which requires an explicit
|
|
5545
5545
|
// acknowledgement for this compatibility `baseUrl`; the repository's TypeScript 5 lane
|
|
5546
5546
|
// rejects that 6.0 value, so keep it specific to the compiler that needs it.
|
|
5547
|
-
...Number.parseInt(
|
|
5547
|
+
...Number.parseInt(ts10.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
|
|
5548
5548
|
},
|
|
5549
5549
|
include: ["tier5-src/*/index.ts", "tier5-src/_shared/**/*.ts"]
|
|
5550
5550
|
};
|
|
5551
|
-
const parsed =
|
|
5551
|
+
const parsed = ts10.parseJsonConfigFileContent(config, ts10.sys, contentDir2);
|
|
5552
5552
|
if (parsed.fileNames.length === 0) return [];
|
|
5553
|
-
const program =
|
|
5553
|
+
const program = ts10.createProgram({
|
|
5554
5554
|
rootNames: parsed.fileNames,
|
|
5555
5555
|
options: parsed.options,
|
|
5556
|
-
host: confinedHost(
|
|
5556
|
+
host: confinedHost(ts10, contentDir2, parsed.options)
|
|
5557
5557
|
});
|
|
5558
|
-
return [...parsed.errors, ...
|
|
5558
|
+
return [...parsed.errors, ...ts10.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts10.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts10, contentDir2, diagnostic));
|
|
5559
5559
|
}
|
|
5560
5560
|
var compilerPromise;
|
|
5561
5561
|
var init_tier5_typecheck = __esm({
|
|
@@ -5571,8 +5571,8 @@ var init_catalog_v2 = __esm({
|
|
|
5571
5571
|
"../html-to-t5/catalog.v2.json"() {
|
|
5572
5572
|
catalog_v2_default = {
|
|
5573
5573
|
encoding: "gzip-base64",
|
|
5574
|
-
sha256: "
|
|
5575
|
-
data: "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"
|
|
5574
|
+
sha256: "3e517791a3f58cb9af631aac85b57c7e4230d8b7fa9a406768f85b031b70b548",
|
|
5575
|
+
data: "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"
|
|
5576
5576
|
};
|
|
5577
5577
|
}
|
|
5578
5578
|
});
|
|
@@ -7530,7 +7530,6 @@ function buttonVariant(style) {
|
|
|
7530
7530
|
var SYSTEM_FONT_FAMILY, TONAL_ELEVATION_ALPHA, BUTTON_MIN_HIT_TARGET, nonNegative, nonEmpty, own, COLOR_TOKEN_PROPS, TYPOGRAPHY_TOKEN_PROPS, BUTTON_VARIANTS;
|
|
7531
7531
|
var init_tokens = __esm({
|
|
7532
7532
|
"../../core/ts/src/tokens.ts"() {
|
|
7533
|
-
"use strict";
|
|
7534
7533
|
SYSTEM_FONT_FAMILY = "$system";
|
|
7535
7534
|
TONAL_ELEVATION_ALPHA = [0, 0.05, 0.08, 0.11, 0.12, 0.14];
|
|
7536
7535
|
BUTTON_MIN_HIT_TARGET = 44;
|
|
@@ -10356,11 +10355,11 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
10356
10355
|
}
|
|
10357
10356
|
message = typeof asJson === "string" ? asJson : String(raw);
|
|
10358
10357
|
} else message = String(raw);
|
|
10359
|
-
const
|
|
10360
|
-
if (prev.status === "loading")
|
|
10361
|
-
if (prev.loading === true)
|
|
10362
|
-
if (typeof prev.error === "string")
|
|
10363
|
-
def.state =
|
|
10358
|
+
const failed3 = { ...prev, _error: message };
|
|
10359
|
+
if (prev.status === "loading") failed3.status = "error";
|
|
10360
|
+
if (prev.loading === true) failed3.loading = false;
|
|
10361
|
+
if (typeof prev.error === "string") failed3.error = message;
|
|
10362
|
+
def.state = failed3;
|
|
10364
10363
|
};
|
|
10365
10364
|
const runAction = async (def, label2, fn2, args) => {
|
|
10366
10365
|
let timer;
|
|
@@ -18562,9 +18561,9 @@ async function offRepoFontBytes(plan, opts = {}) {
|
|
|
18562
18561
|
out2.hostProvided.push(r2.family);
|
|
18563
18562
|
continue;
|
|
18564
18563
|
}
|
|
18565
|
-
const
|
|
18566
|
-
if (
|
|
18567
|
-
out2.unavailable.push({ family: r2.family, reason:
|
|
18564
|
+
const failed3 = r2.faces.find((f2) => !f2.got.ok);
|
|
18565
|
+
if (failed3 && !failed3.got.ok) {
|
|
18566
|
+
out2.unavailable.push({ family: r2.family, reason: failed3.got.reason });
|
|
18568
18567
|
continue;
|
|
18569
18568
|
}
|
|
18570
18569
|
out2.ready.push({
|
|
@@ -37155,9 +37154,9 @@ var init_presigned_upload_policy = __esm({
|
|
|
37155
37154
|
function mediaFieldName(label2) {
|
|
37156
37155
|
return typeof label2 === "string" && label2.trim() !== "" ? label2 : MEDIA_FIELD_DEFAULT_LABEL;
|
|
37157
37156
|
}
|
|
37158
|
-
function mediaFieldState(uploading, hasPhoto,
|
|
37157
|
+
function mediaFieldState(uploading, hasPhoto, failed3 = false) {
|
|
37159
37158
|
if (uploading) return "Uploading";
|
|
37160
|
-
if (
|
|
37159
|
+
if (failed3) return MEDIA_FIELD_UPLOAD_FAILED;
|
|
37161
37160
|
return hasPhoto ? "Photo added" : void 0;
|
|
37162
37161
|
}
|
|
37163
37162
|
function mediaFieldServicePath(valuePath) {
|
|
@@ -42269,7 +42268,7 @@ var init_pdf = __esm({
|
|
|
42269
42268
|
var defineProperty = Object.defineProperty;
|
|
42270
42269
|
var stringSlice = uncurryThis("".slice);
|
|
42271
42270
|
var replace = uncurryThis("".replace);
|
|
42272
|
-
var
|
|
42271
|
+
var join82 = uncurryThis([].join);
|
|
42273
42272
|
var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
|
|
42274
42273
|
return defineProperty(function() {
|
|
42275
42274
|
}, "length", { value: 8 }).length !== 8;
|
|
@@ -42296,7 +42295,7 @@ var init_pdf = __esm({
|
|
|
42296
42295
|
}
|
|
42297
42296
|
var state = enforceInternalState(value);
|
|
42298
42297
|
if (!hasOwn(state, "source")) {
|
|
42299
|
-
state.source =
|
|
42298
|
+
state.source = join82(TEMPLATE, typeof name == "string" ? name : "");
|
|
42300
42299
|
}
|
|
42301
42300
|
return value;
|
|
42302
42301
|
};
|
|
@@ -44819,7 +44818,7 @@ var init_pdf = __esm({
|
|
|
44819
44818
|
var charAt = uncurryThis("".charAt);
|
|
44820
44819
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
44821
44820
|
var $Array = globalThis2.Array;
|
|
44822
|
-
var
|
|
44821
|
+
var join82 = uncurryThis([].join);
|
|
44823
44822
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toBase64 || !(function() {
|
|
44824
44823
|
try {
|
|
44825
44824
|
var target = new Uint8Array2();
|
|
@@ -44865,7 +44864,7 @@ var init_pdf = __esm({
|
|
|
44865
44864
|
result[written++] = "=";
|
|
44866
44865
|
}
|
|
44867
44866
|
}
|
|
44868
|
-
return
|
|
44867
|
+
return join82(result, "");
|
|
44869
44868
|
}
|
|
44870
44869
|
});
|
|
44871
44870
|
},
|
|
@@ -44877,7 +44876,7 @@ var init_pdf = __esm({
|
|
|
44877
44876
|
var anUint8Array = __webpack_require__3(4154);
|
|
44878
44877
|
var notDetached = __webpack_require__3(5169);
|
|
44879
44878
|
var numberToString2 = uncurryThis(1.1.toString);
|
|
44880
|
-
var
|
|
44879
|
+
var join82 = uncurryThis([].join);
|
|
44881
44880
|
var $Array = Array;
|
|
44882
44881
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
44883
44882
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toHex || !(function() {
|
|
@@ -44897,7 +44896,7 @@ var init_pdf = __esm({
|
|
|
44897
44896
|
var hex2 = numberToString2(this[i2], 16);
|
|
44898
44897
|
result[i2] = hex2.length === 1 ? "0" + hex2 : hex2;
|
|
44899
44898
|
}
|
|
44900
|
-
return
|
|
44899
|
+
return join82(result, "");
|
|
44901
44900
|
}
|
|
44902
44901
|
});
|
|
44903
44902
|
},
|
|
@@ -119636,7 +119635,7 @@ function PdfDocument({ src, nativeSrc, title, height, startPage, zoomPercent, st
|
|
|
119636
119635
|
const [pages2, setPages] = React8.useState(0);
|
|
119637
119636
|
const [failedRequest, setFailedRequest] = React8.useState(null);
|
|
119638
119637
|
const request = JSON.stringify([src, startPage, zoomPercent]);
|
|
119639
|
-
const
|
|
119638
|
+
const failed3 = failedRequest === request;
|
|
119640
119639
|
const containerRef = React8.useRef(null);
|
|
119641
119640
|
React8.useEffect(() => {
|
|
119642
119641
|
let live3 = true;
|
|
@@ -119680,7 +119679,7 @@ function PdfDocument({ src, nativeSrc, title, height, startPage, zoomPercent, st
|
|
|
119680
119679
|
// PDF pages need their own scroll viewport so every page remains reachable.
|
|
119681
119680
|
overflow: "auto"
|
|
119682
119681
|
};
|
|
119683
|
-
if (
|
|
119682
|
+
if (failed3) {
|
|
119684
119683
|
return /* @__PURE__ */ jsx9("object", { "data-himalaya-pdf": "native-fallback", "data-himalaya-pdf-zoom": zoomPercent ?? 100, data: nativeSrc, type: "application/pdf", "aria-label": title, style: frame });
|
|
119685
119684
|
}
|
|
119686
119685
|
return /* @__PURE__ */ jsxs6("div", { "data-himalaya-pdf": "canvas-document", "data-himalaya-pdf-src": src, "data-himalaya-pdf-zoom": zoomPercent ?? 100, role: "group", "aria-label": title, "aria-busy": pages2 === 0, style: frame, children: [
|
|
@@ -122775,12 +122774,12 @@ var init_renderNode = __esm({
|
|
|
122775
122774
|
const bound = useBoundValue(ctx, servicePathStr ? String(props.valuePath) : "");
|
|
122776
122775
|
const imageUrl = typeof bound === "string" ? bound : "";
|
|
122777
122776
|
const [uploading, setUploading] = React9.useState(false);
|
|
122778
|
-
const [
|
|
122777
|
+
const [failed3, setFailed] = React9.useState(false);
|
|
122779
122778
|
const fileRef = React9.useRef(null);
|
|
122780
122779
|
const uploadService = typeof props.uploadService === "string" ? props.uploadService : "";
|
|
122781
122780
|
const resolvedLabel = asText2(resolveScalarStatic(props.label, ctx));
|
|
122782
122781
|
const name = mediaFieldName(resolvedLabel);
|
|
122783
|
-
const state = mediaFieldState(uploading, imageUrl !== "",
|
|
122782
|
+
const state = mediaFieldState(uploading, imageUrl !== "", failed3);
|
|
122784
122783
|
const open = () => {
|
|
122785
122784
|
if (!uploading) fileRef.current?.click();
|
|
122786
122785
|
};
|
|
@@ -122836,7 +122835,7 @@ var init_renderNode = __esm({
|
|
|
122836
122835
|
/* @__PURE__ */ jsx10("span", { style: { fontFamily: fontStack(f2.family, ctx.idiom), fontWeight: f2.weight, fontSize: f2.remSize }, children: name })
|
|
122837
122836
|
] }),
|
|
122838
122837
|
uploading ? /* @__PURE__ */ jsx10("div", { "aria-hidden": "true", "data-media-uploading": "true", style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.35)" } }) : null,
|
|
122839
|
-
|
|
122838
|
+
failed3 && !uploading ? /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", "data-media-upload-error": "true", style: { position: "absolute", left: 8, right: 8, bottom: 8, textAlign: "center", fontSize: pxToRem(13), color: C2("danger", "#E62214") }, children: MEDIA_FIELD_UPLOAD_FAILED }) : null
|
|
122840
122839
|
]
|
|
122841
122840
|
}
|
|
122842
122841
|
);
|
|
@@ -127769,13 +127768,13 @@ async function pngFontFaceCss(tokens2, opts = {}) {
|
|
|
127769
127768
|
for (const [name, family] of Object.entries(catalog3.bundled)) {
|
|
127770
127769
|
for (const face of family.faces) want(name, face, family.variable);
|
|
127771
127770
|
}
|
|
127772
|
-
let
|
|
127771
|
+
let planned2 = [];
|
|
127773
127772
|
try {
|
|
127774
|
-
|
|
127773
|
+
planned2 = planFonts(tokens2 ?? {}, { families: declaredFamilies(tokens2) }, catalog3).families;
|
|
127775
127774
|
} catch {
|
|
127776
|
-
|
|
127775
|
+
planned2 = [];
|
|
127777
127776
|
}
|
|
127778
|
-
for (const family of
|
|
127777
|
+
for (const family of planned2) {
|
|
127779
127778
|
if (family.builtin) continue;
|
|
127780
127779
|
for (const face of family.faces) want(family.name, face, family.variable);
|
|
127781
127780
|
}
|
|
@@ -137293,9 +137292,9 @@ function stateOf(view) {
|
|
|
137293
137292
|
build: b2 && view.live ? { ok: b2.ok, ms: b2.ms, screens: b2.screens, at: b2.at, run: view.live.runId } : null
|
|
137294
137293
|
};
|
|
137295
137294
|
}
|
|
137296
|
-
function frameFor(state, prev,
|
|
137297
|
-
if (key2 || !prev) return { ts:
|
|
137298
|
-
const f2 = { ts:
|
|
137295
|
+
function frameFor(state, prev, ts10, v2, key2) {
|
|
137296
|
+
if (key2 || !prev) return { ts: ts10, v: v2, key: true, ...state };
|
|
137297
|
+
const f2 = { ts: ts10, v: v2 };
|
|
137299
137298
|
if (!same2(state.step, prev.step)) f2.step = state.step;
|
|
137300
137299
|
if (!same2(state.now, prev.now)) f2.now = state.now;
|
|
137301
137300
|
const screens = {};
|
|
@@ -145718,6 +145717,137 @@ var init_hosted_owner = __esm({
|
|
|
145718
145717
|
}
|
|
145719
145718
|
});
|
|
145720
145719
|
|
|
145720
|
+
// src/config-source-edit.ts
|
|
145721
|
+
import { lstatSync as lstatSync14 } from "node:fs";
|
|
145722
|
+
import { join as join50 } from "node:path";
|
|
145723
|
+
import ts5 from "typescript";
|
|
145724
|
+
function defineAppLiteral(file2) {
|
|
145725
|
+
for (const statement of file2.statements) {
|
|
145726
|
+
if (!ts5.isExportAssignment(statement)) continue;
|
|
145727
|
+
const exported = localValue(file2, unwrap(statement.expression));
|
|
145728
|
+
if (ts5.isObjectLiteralExpression(exported)) return exported;
|
|
145729
|
+
const [first] = ts5.isCallExpression(exported) ? exported.arguments : [];
|
|
145730
|
+
return first && ts5.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
|
|
145731
|
+
}
|
|
145732
|
+
return void 0;
|
|
145733
|
+
}
|
|
145734
|
+
function loginOf(app) {
|
|
145735
|
+
const auth = lookup2(app, "auth");
|
|
145736
|
+
if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
|
|
145737
|
+
const value = unwrap(auth.node.initializer);
|
|
145738
|
+
if (ts5.isObjectLiteralExpression(value)) return { kind: "other" };
|
|
145739
|
+
if (!ts5.isCallExpression(value)) return { kind: "opaque" };
|
|
145740
|
+
const provider = calleeName(value);
|
|
145741
|
+
if (provider === "WixOwnerAuthProvider" || provider === "WixAuthProvider") return { kind: "owner" };
|
|
145742
|
+
if (provider === "WixNativeAuthProvider") return nativeMode(value) === "owner" ? { kind: "owner" } : { kind: "other" };
|
|
145743
|
+
if (provider !== "WixConsumerAuthProvider") return { kind: "other" };
|
|
145744
|
+
const [first] = value.arguments;
|
|
145745
|
+
return first && ts5.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
|
|
145746
|
+
}
|
|
145747
|
+
function nativeMode(call) {
|
|
145748
|
+
const [first] = call.arguments;
|
|
145749
|
+
return first && ts5.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
|
|
145750
|
+
}
|
|
145751
|
+
function calleeName(call) {
|
|
145752
|
+
const callee = call.expression;
|
|
145753
|
+
if (ts5.isIdentifier(callee)) return callee.text;
|
|
145754
|
+
return ts5.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
|
|
145755
|
+
}
|
|
145756
|
+
function unwrap(node) {
|
|
145757
|
+
let current = node;
|
|
145758
|
+
while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current)) {
|
|
145759
|
+
current = current.expression;
|
|
145760
|
+
}
|
|
145761
|
+
return current;
|
|
145762
|
+
}
|
|
145763
|
+
function lookup2(literal, name) {
|
|
145764
|
+
let found = { kind: "absent" };
|
|
145765
|
+
for (const p2 of literal.properties) {
|
|
145766
|
+
const key2 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
|
|
145767
|
+
if (ts5.isPropertyAssignment(p2) && key2 === name) found = { kind: "written", node: p2 };
|
|
145768
|
+
else if (ts5.isSpreadAssignment(p2) || p2.name && ts5.isComputedPropertyName(p2.name) || key2 === name) found = { kind: "opaque" };
|
|
145769
|
+
}
|
|
145770
|
+
return found;
|
|
145771
|
+
}
|
|
145772
|
+
function stringValue(node, name) {
|
|
145773
|
+
const literal = unwrap(node);
|
|
145774
|
+
const found = ts5.isObjectLiteralExpression(literal) ? lookup2(literal, name) : void 0;
|
|
145775
|
+
const value = found?.kind === "written" ? found.node.initializer : void 0;
|
|
145776
|
+
return value && ts5.isStringLiteralLike(value) ? value.text : void 0;
|
|
145777
|
+
}
|
|
145778
|
+
function appendProperties(literal, file2, lines) {
|
|
145779
|
+
const inline = () => lines.filter((line) => !line.trimStart().startsWith("//")).join(" ");
|
|
145780
|
+
if (literal.properties.length === 0) {
|
|
145781
|
+
const at3 = literal.getStart(file2) + 1;
|
|
145782
|
+
return { at: at3, end: literal.end - 1, text: ` ${inline().replace(/,$/, "")} ` };
|
|
145783
|
+
}
|
|
145784
|
+
const last = literal.properties[literal.properties.length - 1];
|
|
145785
|
+
const trailing = literal.properties.hasTrailingComma;
|
|
145786
|
+
const at2 = trailing ? literal.properties.end : last.end;
|
|
145787
|
+
const lead = trailing ? "" : ",";
|
|
145788
|
+
if (onOneLine(literal, file2)) {
|
|
145789
|
+
const text9 = inline();
|
|
145790
|
+
return { at: at2, end: at2, text: `${lead} ${trailing ? text9 : text9.replace(/,$/, "")}` };
|
|
145791
|
+
}
|
|
145792
|
+
const indent = lineIndent2(file2.text, last.getStart(file2));
|
|
145793
|
+
return { at: at2, end: at2, text: lead + lines.map((line) => `
|
|
145794
|
+
${indent}${line}`).join("") };
|
|
145795
|
+
}
|
|
145796
|
+
function onOneLine(node, file2) {
|
|
145797
|
+
const line = (position) => file2.getLineAndCharacterOfPosition(position).line;
|
|
145798
|
+
return line(node.getStart(file2)) === line(node.getEnd());
|
|
145799
|
+
}
|
|
145800
|
+
function lineIndent2(text9, position) {
|
|
145801
|
+
const lineStart = text9.lastIndexOf("\n", position - 1) + 1;
|
|
145802
|
+
return /^[ \t]*/.exec(text9.slice(lineStart))[0];
|
|
145803
|
+
}
|
|
145804
|
+
function applySplices(source, splices) {
|
|
145805
|
+
return [...splices].sort((a2, b2) => b2.at - a2.at).reduce((out2, s2) => out2.slice(0, s2.at) + s2.text + out2.slice(s2.end), source);
|
|
145806
|
+
}
|
|
145807
|
+
function localValue(file2, node) {
|
|
145808
|
+
if (!ts5.isIdentifier(node)) return node;
|
|
145809
|
+
for (const statement of file2.statements) {
|
|
145810
|
+
if (!ts5.isVariableStatement(statement) || !(statement.declarationList.flags & ts5.NodeFlags.Const)) continue;
|
|
145811
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
145812
|
+
if (ts5.isIdentifier(declaration.name) && declaration.name.text === node.text && declaration.initializer) return unwrap(declaration.initializer);
|
|
145813
|
+
}
|
|
145814
|
+
}
|
|
145815
|
+
return node;
|
|
145816
|
+
}
|
|
145817
|
+
function backUpConfig(dir, folder, fileName, original) {
|
|
145818
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
145819
|
+
const backupDir = realDirIn(dir, `.himi/${folder}/${stamp}`);
|
|
145820
|
+
if (!backupDir) return void 0;
|
|
145821
|
+
const backup = join50(backupDir, fileName);
|
|
145822
|
+
writeFileAtomic(backup, original);
|
|
145823
|
+
return backup;
|
|
145824
|
+
}
|
|
145825
|
+
function isSymlink2(path2) {
|
|
145826
|
+
try {
|
|
145827
|
+
return lstatSync14(path2).isSymbolicLink();
|
|
145828
|
+
} catch {
|
|
145829
|
+
return false;
|
|
145830
|
+
}
|
|
145831
|
+
}
|
|
145832
|
+
async function introducedErrors(dir, validate4, file2, isOwnFinding) {
|
|
145833
|
+
const edited = await validate4(dir, { fresh: true });
|
|
145834
|
+
if (edited.code === 0) return void 0;
|
|
145835
|
+
if (!comparable(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
|
|
145836
|
+
if (edited.errors.every((e2) => isOwnFinding(e2.ruleCode))) return void 0;
|
|
145837
|
+
file2.restore();
|
|
145838
|
+
const baseline = await validate4(dir, { fresh: true });
|
|
145839
|
+
file2.reapply();
|
|
145840
|
+
if (!comparable(baseline)) return "himi validate could not check the original config.ts to compare against";
|
|
145841
|
+
const introduced = compareErrors(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isOwnFinding(e2.ruleCode));
|
|
145842
|
+
return introduced.length ? `the edit introduced ${introduced.length === 1 ? "an error" : `${introduced.length} errors`}: ` + introduced.map((e2) => e2.message).join("; ") : void 0;
|
|
145843
|
+
}
|
|
145844
|
+
var init_config_source_edit = __esm({
|
|
145845
|
+
"src/config-source-edit.ts"() {
|
|
145846
|
+
init_progress();
|
|
145847
|
+
init_template_trim();
|
|
145848
|
+
}
|
|
145849
|
+
});
|
|
145850
|
+
|
|
145721
145851
|
// src/config-push-edit.ts
|
|
145722
145852
|
var config_push_edit_exports = {};
|
|
145723
145853
|
__export(config_push_edit_exports, {
|
|
@@ -145725,14 +145855,14 @@ __export(config_push_edit_exports, {
|
|
|
145725
145855
|
enablePushInConfig: () => enablePushInConfig,
|
|
145726
145856
|
previewPushConfigEdit: () => previewPushConfigEdit
|
|
145727
145857
|
});
|
|
145728
|
-
import {
|
|
145729
|
-
import { basename as basename13
|
|
145730
|
-
import
|
|
145858
|
+
import { readFileSync as readFileSync58 } from "node:fs";
|
|
145859
|
+
import { basename as basename13 } from "node:path";
|
|
145860
|
+
import ts6 from "typescript";
|
|
145731
145861
|
function enablePushInConfig(source, options) {
|
|
145732
145862
|
const pingAppName = DEFAULT_PING_APP_NAME;
|
|
145733
145863
|
const fileName = options.fileName ?? "config.ts";
|
|
145734
|
-
const kind = fileName.endsWith(".ts") ?
|
|
145735
|
-
const file2 =
|
|
145864
|
+
const kind = fileName.endsWith(".ts") ? ts6.ScriptKind.TS : ts6.ScriptKind.JS;
|
|
145865
|
+
const file2 = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true, kind);
|
|
145736
145866
|
const app = defineAppLiteral(file2);
|
|
145737
145867
|
const named = (instruction) => instruction.replaceAll("config.ts", fileName);
|
|
145738
145868
|
const unchanged = (instruction) => ({ source, changed: false, applied: [], instructions: [named(instruction)], pushOn: false });
|
|
@@ -145784,9 +145914,9 @@ function planPush(app, pingAppName, plan) {
|
|
|
145784
145914
|
}
|
|
145785
145915
|
function planRetiredFamily(block, plan) {
|
|
145786
145916
|
const literal = unwrap(block);
|
|
145787
|
-
const found =
|
|
145917
|
+
const found = ts6.isObjectLiteralExpression(literal) ? lookup2(literal, "pingAppName") : void 0;
|
|
145788
145918
|
const value = found?.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
145789
|
-
const replacement = value &&
|
|
145919
|
+
const replacement = value && ts6.isStringLiteralLike(value) ? replacementPingFamily(value.text) : void 0;
|
|
145790
145920
|
if (!value || !replacement) return;
|
|
145791
145921
|
plan.splices.push({ at: value.getStart(), end: value.end, text: JSON.stringify(replacement) });
|
|
145792
145922
|
plan.applied.push(`pingAppName ${JSON.stringify(replacement)} in place of ${value.getText()}`);
|
|
@@ -145799,11 +145929,11 @@ function planCapability(app, plan) {
|
|
|
145799
145929
|
return;
|
|
145800
145930
|
}
|
|
145801
145931
|
const list = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
|
|
145802
|
-
if (!list || !
|
|
145932
|
+
if (!list || !ts6.isArrayLiteralExpression(list)) {
|
|
145803
145933
|
plan.instructions.push('Add "push" to capabilities: Wix push needs the push capability, and config.ts does not list it inline.');
|
|
145804
145934
|
return;
|
|
145805
145935
|
}
|
|
145806
|
-
if (list.elements.some((e2) =>
|
|
145936
|
+
if (list.elements.some((e2) => ts6.isStringLiteralLike(e2) && e2.text === "push")) return;
|
|
145807
145937
|
const last = list.elements[list.elements.length - 1];
|
|
145808
145938
|
plan.splices.push(last ? { at: last.end, end: last.end, text: ', "push"' } : { at: list.getStart(), end: list.end, text: '["push"]' });
|
|
145809
145939
|
plan.applied.push("push capability");
|
|
@@ -145831,7 +145961,7 @@ function planAuthSite(login, file2, site, plan) {
|
|
|
145831
145961
|
const current = siteId.kind === "written" ? unwrap(siteId.node.initializer) : void 0;
|
|
145832
145962
|
if (!current) {
|
|
145833
145963
|
plan.instructions.push(`auth may get its siteId from elsewhere, so none was added. Wix push needs ${wanted}.`);
|
|
145834
|
-
} else if (!
|
|
145964
|
+
} else if (!ts6.isStringLiteralLike(current)) {
|
|
145835
145965
|
plan.instructions.push(`auth's siteId is computed, so it was not checked: make sure it evaluates to ${JSON.stringify(site)}.`);
|
|
145836
145966
|
} else if (current.text !== site) {
|
|
145837
145967
|
plan.instructions.push(
|
|
@@ -145842,89 +145972,6 @@ function planAuthSite(login, file2, site, plan) {
|
|
|
145842
145972
|
function noLiteralInstruction(pingAppName) {
|
|
145843
145973
|
return `config.ts does not default-export a defineApp({ \u2026 }) object literal, so it was not edited. Add push: { registrar: "wix-ping", pingAppName: ${JSON.stringify(pingAppName)}, requestPermissionOnLaunch: true, payloadAdapter: "wix-ping" } and "push" in capabilities to the app's config.`;
|
|
145844
145974
|
}
|
|
145845
|
-
function defineAppLiteral(file2) {
|
|
145846
|
-
for (const statement of file2.statements) {
|
|
145847
|
-
if (!ts5.isExportAssignment(statement)) continue;
|
|
145848
|
-
const exported = unwrap(statement.expression);
|
|
145849
|
-
if (ts5.isObjectLiteralExpression(exported)) return exported;
|
|
145850
|
-
const [first] = ts5.isCallExpression(exported) ? exported.arguments : [];
|
|
145851
|
-
return first && ts5.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
|
|
145852
|
-
}
|
|
145853
|
-
return void 0;
|
|
145854
|
-
}
|
|
145855
|
-
function loginOf(app) {
|
|
145856
|
-
const auth = lookup2(app, "auth");
|
|
145857
|
-
if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
|
|
145858
|
-
const value = unwrap(auth.node.initializer);
|
|
145859
|
-
if (ts5.isObjectLiteralExpression(value)) return { kind: "other" };
|
|
145860
|
-
if (!ts5.isCallExpression(value)) return { kind: "opaque" };
|
|
145861
|
-
const provider = calleeName(value);
|
|
145862
|
-
if (provider === "WixOwnerAuthProvider" || provider === "WixAuthProvider") return { kind: "owner" };
|
|
145863
|
-
if (provider === "WixNativeAuthProvider") return nativeMode(value) === "owner" ? { kind: "owner" } : { kind: "other" };
|
|
145864
|
-
if (provider !== "WixConsumerAuthProvider") return { kind: "other" };
|
|
145865
|
-
const [first] = value.arguments;
|
|
145866
|
-
return first && ts5.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
|
|
145867
|
-
}
|
|
145868
|
-
function nativeMode(call) {
|
|
145869
|
-
const [first] = call.arguments;
|
|
145870
|
-
return first && ts5.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
|
|
145871
|
-
}
|
|
145872
|
-
function calleeName(call) {
|
|
145873
|
-
const callee = call.expression;
|
|
145874
|
-
if (ts5.isIdentifier(callee)) return callee.text;
|
|
145875
|
-
return ts5.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
|
|
145876
|
-
}
|
|
145877
|
-
function unwrap(node) {
|
|
145878
|
-
let current = node;
|
|
145879
|
-
while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current)) {
|
|
145880
|
-
current = current.expression;
|
|
145881
|
-
}
|
|
145882
|
-
return current;
|
|
145883
|
-
}
|
|
145884
|
-
function lookup2(literal, name) {
|
|
145885
|
-
let found = { kind: "absent" };
|
|
145886
|
-
for (const p2 of literal.properties) {
|
|
145887
|
-
const key2 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
|
|
145888
|
-
if (ts5.isPropertyAssignment(p2) && key2 === name) found = { kind: "written", node: p2 };
|
|
145889
|
-
else if (ts5.isSpreadAssignment(p2) || p2.name && ts5.isComputedPropertyName(p2.name) || key2 === name) found = { kind: "opaque" };
|
|
145890
|
-
}
|
|
145891
|
-
return found;
|
|
145892
|
-
}
|
|
145893
|
-
function stringValue(node, name) {
|
|
145894
|
-
const literal = unwrap(node);
|
|
145895
|
-
const found = ts5.isObjectLiteralExpression(literal) ? lookup2(literal, name) : void 0;
|
|
145896
|
-
const value = found?.kind === "written" ? found.node.initializer : void 0;
|
|
145897
|
-
return value && ts5.isStringLiteralLike(value) ? value.text : void 0;
|
|
145898
|
-
}
|
|
145899
|
-
function appendProperties(literal, file2, lines) {
|
|
145900
|
-
const inline = () => lines.filter((line) => !line.trimStart().startsWith("//")).join(" ");
|
|
145901
|
-
if (literal.properties.length === 0) {
|
|
145902
|
-
const at3 = literal.getStart(file2) + 1;
|
|
145903
|
-
return { at: at3, end: literal.end - 1, text: ` ${inline().replace(/,$/, "")} ` };
|
|
145904
|
-
}
|
|
145905
|
-
const last = literal.properties[literal.properties.length - 1];
|
|
145906
|
-
const trailing = literal.properties.hasTrailingComma;
|
|
145907
|
-
const at2 = trailing ? literal.properties.end : last.end;
|
|
145908
|
-
const lead = trailing ? "" : ",";
|
|
145909
|
-
if (onOneLine(literal, file2)) {
|
|
145910
|
-
const text9 = inline();
|
|
145911
|
-
return { at: at2, end: at2, text: `${lead} ${trailing ? text9 : text9.replace(/,$/, "")}` };
|
|
145912
|
-
}
|
|
145913
|
-
const indent = lineIndent2(file2.text, last.getStart(file2));
|
|
145914
|
-
return { at: at2, end: at2, text: lead + lines.map((line) => `
|
|
145915
|
-
${indent}${line}`).join("") };
|
|
145916
|
-
}
|
|
145917
|
-
function onOneLine(node, file2) {
|
|
145918
|
-
const line = (position) => file2.getLineAndCharacterOfPosition(position).line;
|
|
145919
|
-
return line(node.getStart(file2)) === line(node.getEnd());
|
|
145920
|
-
}
|
|
145921
|
-
function lineIndent2(text9, position) {
|
|
145922
|
-
const lineStart = text9.lastIndexOf("\n", position - 1) + 1;
|
|
145923
|
-
return /^[ \t]*/.exec(text9.slice(lineStart))[0];
|
|
145924
|
-
}
|
|
145925
|
-
function applySplices(source, splices) {
|
|
145926
|
-
return [...splices].sort((a2, b2) => b2.at - a2.at).reduce((out2, s2) => out2.slice(0, s2.at) + s2.text + out2.slice(s2.end), source);
|
|
145927
|
-
}
|
|
145928
145975
|
function previewPushConfigEdit(dir, options) {
|
|
145929
145976
|
const path2 = configEntry(dir);
|
|
145930
145977
|
if (!path2) return void 0;
|
|
@@ -145941,13 +145988,13 @@ async function applyPushConfigEdit(dir, options, validate4) {
|
|
|
145941
145988
|
const edit = enablePushInConfig(original, { ...options, fileName });
|
|
145942
145989
|
const { applied, instructions, pushOn } = edit;
|
|
145943
145990
|
if (!edit.changed) return { changed: false, pushOn, applied, instructions };
|
|
145944
|
-
const backup =
|
|
145991
|
+
const backup = backUpConfig(dir, "notify-setup-backup", fileName, original);
|
|
145945
145992
|
if (!backup) return refuse7(`.himi is not a plain directory in this package (a symlink?), so ${fileName} was not edited.`);
|
|
145946
145993
|
writeFileAtomic(path2, edit.source);
|
|
145947
145994
|
const introduced = await introducedErrors(dir, validate4, {
|
|
145948
145995
|
restore: () => writeFileAtomic(path2, original),
|
|
145949
145996
|
reapply: () => writeFileAtomic(path2, edit.source)
|
|
145950
|
-
}).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
145997
|
+
}, isPushFinding).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
145951
145998
|
if (introduced) {
|
|
145952
145999
|
writeFileAtomic(path2, original);
|
|
145953
146000
|
const byHand = `Add to ${fileName} by hand: ${applied.join(", ")}.`;
|
|
@@ -145955,40 +146002,13 @@ async function applyPushConfigEdit(dir, options, validate4) {
|
|
|
145955
146002
|
}
|
|
145956
146003
|
return { changed: true, pushOn, applied, instructions, backup };
|
|
145957
146004
|
}
|
|
145958
|
-
function backUp(dir, fileName, original) {
|
|
145959
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
145960
|
-
const backupDir = realDirIn(dir, `.himi/notify-setup-backup/${stamp}`);
|
|
145961
|
-
if (!backupDir) return void 0;
|
|
145962
|
-
const backup = join50(backupDir, fileName);
|
|
145963
|
-
writeFileAtomic(backup, original);
|
|
145964
|
-
return backup;
|
|
145965
|
-
}
|
|
145966
|
-
function isSymlink2(path2) {
|
|
145967
|
-
try {
|
|
145968
|
-
return lstatSync14(path2).isSymbolicLink();
|
|
145969
|
-
} catch {
|
|
145970
|
-
return false;
|
|
145971
|
-
}
|
|
145972
|
-
}
|
|
145973
|
-
async function introducedErrors(dir, validate4, file2) {
|
|
145974
|
-
const edited = await validate4(dir, { fresh: true });
|
|
145975
|
-
if (edited.code === 0) return void 0;
|
|
145976
|
-
if (!comparable(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
|
|
145977
|
-
if (edited.errors.every((e2) => isPushFinding(e2.ruleCode))) return void 0;
|
|
145978
|
-
file2.restore();
|
|
145979
|
-
const baseline = await validate4(dir, { fresh: true });
|
|
145980
|
-
file2.reapply();
|
|
145981
|
-
if (!comparable(baseline)) return "himi validate could not check the original config.ts to compare against";
|
|
145982
|
-
const introduced = compareErrors(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isPushFinding(e2.ruleCode));
|
|
145983
|
-
return introduced.length ? `the edit introduced ${introduced.length === 1 ? "an error" : `${introduced.length} errors`}: ` + introduced.map((e2) => e2.message).join("; ") : void 0;
|
|
145984
|
-
}
|
|
145985
146005
|
var ROUTES_COMMENT, OWNER_INSTRUCTION, isPushFinding;
|
|
145986
146006
|
var init_config_push_edit = __esm({
|
|
145987
146007
|
"src/config-push-edit.ts"() {
|
|
145988
146008
|
init_wix_push_links();
|
|
145989
146009
|
init_app_config_loader();
|
|
146010
|
+
init_config_source_edit();
|
|
145990
146011
|
init_progress();
|
|
145991
|
-
init_template_trim();
|
|
145992
146012
|
ROUTES_COMMENT = "// Routes are derived at build time from provisioning.json and your screens; see himi validate.";
|
|
145993
146013
|
OWNER_INSTRUCTION = "config.ts was not edited: this app signs in a site owner, and Wix sends owner notifications only to Wix's own apps. Member push needs a member login (WixConsumerAuthProvider).";
|
|
145994
146014
|
isPushFinding = (ruleCode) => ruleCode?.startsWith("push-") === true;
|
|
@@ -147081,8 +147101,8 @@ function watchFlagConflict(opts) {
|
|
|
147081
147101
|
return null;
|
|
147082
147102
|
}
|
|
147083
147103
|
function rebuildBlocker(outcome, servedMissing) {
|
|
147084
|
-
const
|
|
147085
|
-
if (
|
|
147104
|
+
const failed3 = outcome.failedToBuild[0];
|
|
147105
|
+
if (failed3) return `${failed3.screenId}: ${failed3.error.split("\n")[0]}`;
|
|
147086
147106
|
const had = new Set(servedMissing.map((m2) => `${m2.screen}\0${m2.bundle}`));
|
|
147087
147107
|
const lost = outcome.missingBundles.find((m2) => !had.has(`${m2.screen}\0${m2.bundle}`));
|
|
147088
147108
|
if (lost) return `${lost.screen}: its worker bundle "${lost.bundle}" is referenced but was not built`;
|
|
@@ -147425,15 +147445,15 @@ function loadMemory2(dir) {
|
|
|
147425
147445
|
for (const t2 of m2.timeline) {
|
|
147426
147446
|
if (!isObj3(t2)) continue;
|
|
147427
147447
|
const file2 = historyName(t2.sha, t2.ext);
|
|
147428
|
-
const
|
|
147448
|
+
const ts10 = str4(t2.ts);
|
|
147429
147449
|
const id = str4(t2.id);
|
|
147430
|
-
if (file2 &&
|
|
147450
|
+
if (file2 && ts10 && id) timeline.push({ ts: ts10, id, file: file2 });
|
|
147431
147451
|
}
|
|
147432
147452
|
return { createdAt: str4(m2.createdAt), shots, timeline };
|
|
147433
147453
|
}
|
|
147434
|
-
function captionAt(entries,
|
|
147454
|
+
function captionAt(entries, ts10) {
|
|
147435
147455
|
let best = null;
|
|
147436
|
-
for (const e2 of entries) if (e2.ts <=
|
|
147456
|
+
for (const e2 of entries) if (e2.ts <= ts10) best = e2;
|
|
147437
147457
|
return best ? best.message : null;
|
|
147438
147458
|
}
|
|
147439
147459
|
function thin(items, max) {
|
|
@@ -147553,13 +147573,13 @@ function duration(ms2) {
|
|
|
147553
147573
|
const m2 = Math.round(ms2 / 6e4);
|
|
147554
147574
|
return m2 < 60 ? `${m2} min` : `${Math.floor(m2 / 60)} h ${m2 % 60} min`;
|
|
147555
147575
|
}
|
|
147556
|
-
function utcDay(
|
|
147557
|
-
const d2 = new Date(
|
|
147576
|
+
function utcDay(ts10) {
|
|
147577
|
+
const d2 = new Date(ts10);
|
|
147558
147578
|
return Number.isNaN(d2.getTime()) ? "" : `${d2.toUTCString().slice(0, 16)} (UTC)`;
|
|
147559
147579
|
}
|
|
147560
|
-
function sinceStart(start,
|
|
147580
|
+
function sinceStart(start, ts10) {
|
|
147561
147581
|
if (!start) return "";
|
|
147562
|
-
const s2 = Math.max(0, Math.round((Date.parse(
|
|
147582
|
+
const s2 = Math.max(0, Math.round((Date.parse(ts10) - Date.parse(start)) / 1e3));
|
|
147563
147583
|
const h2 = Math.floor(s2 / 3600);
|
|
147564
147584
|
const m2 = Math.floor(s2 % 3600 / 60);
|
|
147565
147585
|
const sec = String(s2 % 60).padStart(2, "0");
|
|
@@ -147569,7 +147589,7 @@ function renderReel(plan, images) {
|
|
|
147569
147589
|
const img = (f2, alt, cls = "") => f2 && images.has(f2) ? `<img class="${cls}" src="${images.get(f2)}" alt="${escapeHtml(alt)}">` : "";
|
|
147570
147590
|
const count2 = (n2) => escapeHtml(String(Number.isSafeInteger(n2) && n2 >= 0 ? n2 : 0));
|
|
147571
147591
|
const accent = ACCENT.test(plan.accent) ? plan.accent : DEFAULT_ACCENT;
|
|
147572
|
-
const clock = (
|
|
147592
|
+
const clock = (ts10) => sinceStart(plan.startedAt, ts10);
|
|
147573
147593
|
const frames = plan.frames.filter((f2) => images.has(f2.file));
|
|
147574
147594
|
const flip = frames.length ? `<section class="flip"><div class="phone">${frames.map((f2, i2) => `<img class="fr${i2 === 0 ? " on" : ""}" src="${images.get(f2.file)}" alt="${escapeHtml(plan.focusId ?? "")} at ${clock(f2.ts)}">`).join("")}</div>
|
|
147575
147595
|
<div class="flipcap"><div class="t" id="ft">${frames[0] ? clock(frames[0].ts) : ""}</div><div id="fc">${escapeHtml(frames[0]?.caption ?? "")}</div><div class="bar"><div id="fb"></div></div></div></section>` : `<p class="muted">No screen versions were recorded \u2014 open the build board with <code>himi studio</code> before building to capture them.</p>`;
|
|
@@ -148446,17 +148466,17 @@ __export(template_sweep_exports, {
|
|
|
148446
148466
|
});
|
|
148447
148467
|
import { readFileSync as readFileSync65, writeFileSync as writeFileSync24 } from "node:fs";
|
|
148448
148468
|
import { join as join57 } from "node:path";
|
|
148449
|
-
import
|
|
148469
|
+
import ts7 from "typescript";
|
|
148450
148470
|
function isCopy(node, file2) {
|
|
148451
148471
|
const parent = node.parent;
|
|
148452
|
-
if (
|
|
148453
|
-
if (
|
|
148454
|
-
if (
|
|
148455
|
-
if (
|
|
148472
|
+
if (ts7.isPropertyAssignment(parent) && parent.name === node) return false;
|
|
148473
|
+
if (ts7.isImportDeclaration(parent) || ts7.isExportDeclaration(parent) || ts7.isExternalModuleReference(parent)) return false;
|
|
148474
|
+
if (ts7.isLiteralTypeNode(parent) || ts7.isImportTypeNode(parent)) return false;
|
|
148475
|
+
if (ts7.isCallExpression(parent) && ts7.isIdentifier(parent.expression) && parent.expression.text === "require") return false;
|
|
148456
148476
|
const value = node.text;
|
|
148457
148477
|
if (/\s/.test(value) || PLACEHOLDER.test(value)) return true;
|
|
148458
148478
|
if (ID_LIKE.test(value)) return false;
|
|
148459
|
-
const key2 =
|
|
148479
|
+
const key2 = ts7.isPropertyAssignment(parent) ? propName4(parent.name) : void 0;
|
|
148460
148480
|
if (!key2) return false;
|
|
148461
148481
|
return COPY_KEYS.has(key2) || key2 === "name" && file2 === "config.ts";
|
|
148462
148482
|
}
|
|
@@ -148474,8 +148494,8 @@ function syntaxErrors(file2, text9) {
|
|
|
148474
148494
|
return [e2.message];
|
|
148475
148495
|
}
|
|
148476
148496
|
}
|
|
148477
|
-
const out2 =
|
|
148478
|
-
return (out2.diagnostics ?? []).map((d2) =>
|
|
148497
|
+
const out2 = ts7.transpileModule(text9, { fileName: file2, reportDiagnostics: true, compilerOptions: { target: ts7.ScriptTarget.ES2022 } });
|
|
148498
|
+
return (out2.diagnostics ?? []).map((d2) => ts7.flattenDiagnosticMessageText(d2.messageText, "\n"));
|
|
148479
148499
|
}
|
|
148480
148500
|
function sweepCopy(dir, pairs, dryRun) {
|
|
148481
148501
|
for (const [from] of pairs) {
|
|
@@ -148488,11 +148508,11 @@ function sweepCopy(dir, pairs, dryRun) {
|
|
|
148488
148508
|
for (const f2 of files) {
|
|
148489
148509
|
const text9 = readFileSync65(join57(dir, f2), "utf8");
|
|
148490
148510
|
if (!pairs.some(([from]) => text9.includes(from) || text9.includes(JSON.stringify(from).slice(1, -1)))) continue;
|
|
148491
|
-
const kind = f2.endsWith(".json") ?
|
|
148492
|
-
const sf2 =
|
|
148511
|
+
const kind = f2.endsWith(".json") ? ts7.ScriptKind.JSON : f2.endsWith("x") ? ts7.ScriptKind.TSX : ts7.ScriptKind.TS;
|
|
148512
|
+
const sf2 = ts7.createSourceFile(f2, text9, ts7.ScriptTarget.Latest, true, kind);
|
|
148493
148513
|
const edits = [];
|
|
148494
148514
|
const visit = (node) => {
|
|
148495
|
-
if ((
|
|
148515
|
+
if ((ts7.isStringLiteral(node) || ts7.isNoSubstitutionTemplateLiteral(node)) && isCopy(node, f2)) {
|
|
148496
148516
|
let value = node.text;
|
|
148497
148517
|
pairs.forEach(([from, to2], i2) => {
|
|
148498
148518
|
const n2 = value.split(from).length - 1;
|
|
@@ -148505,7 +148525,7 @@ function sweepCopy(dir, pairs, dryRun) {
|
|
|
148505
148525
|
edits.push({ start, end: node.end, text: encode(value, text9[start]) });
|
|
148506
148526
|
}
|
|
148507
148527
|
}
|
|
148508
|
-
|
|
148528
|
+
ts7.forEachChild(node, visit);
|
|
148509
148529
|
};
|
|
148510
148530
|
visit(sf2);
|
|
148511
148531
|
if (!edits.length) continue;
|
|
@@ -148577,7 +148597,7 @@ var init_template_sweep = __esm({
|
|
|
148577
148597
|
"appName",
|
|
148578
148598
|
"displayName"
|
|
148579
148599
|
]);
|
|
148580
|
-
propName4 = (n2) =>
|
|
148600
|
+
propName4 = (n2) => ts7.isIdentifier(n2) || ts7.isStringLiteral(n2) || ts7.isNoSubstitutionTemplateLiteral(n2) ? n2.text : void 0;
|
|
148581
148601
|
}
|
|
148582
148602
|
});
|
|
148583
148603
|
|
|
@@ -152329,7 +152349,7 @@ function fileTools() {
|
|
|
152329
152349
|
if (typeof app !== "string") return app;
|
|
152330
152350
|
const files = Array.isArray(a2.files) ? a2.files : [];
|
|
152331
152351
|
if (!files.length || files.length > MAX_FILES_PER_WRITE) return refuse5("bad_request", `between 1 and ${MAX_FILES_PER_WRITE} files per call`);
|
|
152332
|
-
const
|
|
152352
|
+
const planned2 = [];
|
|
152333
152353
|
const refused2 = [];
|
|
152334
152354
|
for (const f2 of files) {
|
|
152335
152355
|
const p2 = confinedPath(app, f2.path);
|
|
@@ -152337,12 +152357,12 @@ function fileTools() {
|
|
|
152337
152357
|
else if (typeof f2.content !== "string") refused2.push({ path: f2.path, error: "content must be text" });
|
|
152338
152358
|
else if (Buffer.byteLength(f2.content) > MAX_FILE_BYTES) refused2.push({ path: f2.path, error: `over the ${MAX_FILE_BYTES}-byte limit` });
|
|
152339
152359
|
else if (existsSync63(p2) && !lstatSync20(p2).isFile()) refused2.push({ path: f2.path, error: "not a regular file" });
|
|
152340
|
-
else if (
|
|
152341
|
-
else
|
|
152360
|
+
else if (planned2.some((q2) => q2.abs === p2)) refused2.push({ path: f2.path, error: "the same file twice in one call" });
|
|
152361
|
+
else planned2.push({ abs: p2, rel: String(f2.path), content: f2.content });
|
|
152342
152362
|
}
|
|
152343
152363
|
if (refused2.length) return { ...ok({ ok: false, error: "refused", written: [], refused: refused2 }), isError: true };
|
|
152344
152364
|
const written = [];
|
|
152345
|
-
for (const f2 of
|
|
152365
|
+
for (const f2 of planned2) {
|
|
152346
152366
|
try {
|
|
152347
152367
|
writeNoFollow2(app, f2.abs, f2.content);
|
|
152348
152368
|
written.push(f2.rel);
|
|
@@ -152363,7 +152383,7 @@ function fileTools() {
|
|
|
152363
152383
|
const app = await confinedAppDir(a2, d2);
|
|
152364
152384
|
if (typeof app !== "string") return app;
|
|
152365
152385
|
const paths = Array.isArray(a2.paths) ? a2.paths : [];
|
|
152366
|
-
const
|
|
152386
|
+
const planned2 = [];
|
|
152367
152387
|
const deleted = [];
|
|
152368
152388
|
const refused2 = [];
|
|
152369
152389
|
for (const rel of paths) {
|
|
@@ -152371,13 +152391,13 @@ function fileTools() {
|
|
|
152371
152391
|
if (typeof p2 !== "string") refused2.push({ path: rel, error: p2.error });
|
|
152372
152392
|
else if (!existsSync63(p2)) refused2.push({ path: rel, error: "no such file" });
|
|
152373
152393
|
else if (!lstatSync20(p2).isFile()) refused2.push({ path: rel, error: "not a regular file" });
|
|
152374
|
-
else if (!
|
|
152375
|
-
|
|
152394
|
+
else if (!planned2.includes(p2)) {
|
|
152395
|
+
planned2.push(p2);
|
|
152376
152396
|
deleted.push(rel);
|
|
152377
152397
|
}
|
|
152378
152398
|
}
|
|
152379
152399
|
if (refused2.length) return { ...ok({ ok: false, error: "refused", deleted: [], refused: refused2 }), isError: true };
|
|
152380
|
-
for (const p2 of
|
|
152400
|
+
for (const p2 of planned2) rmSync15(p2);
|
|
152381
152401
|
return ok({ ok: true, dir: app, deleted });
|
|
152382
152402
|
}
|
|
152383
152403
|
}
|
|
@@ -155738,25 +155758,25 @@ var init_preview_assets_generated = __esm({
|
|
|
155738
155758
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
155739
155759
|
init_preview_assets_format();
|
|
155740
155760
|
PREVIEW_ASSET_MANIFEST = [
|
|
155741
|
-
{ key: "assets/index-
|
|
155742
|
-
{ key: "assets/pdf-
|
|
155743
|
-
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
155744
|
-
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset:
|
|
155745
|
-
{ key: "assets/pdfDocument-
|
|
155746
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
155747
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
155748
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
155749
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
155750
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
155751
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
155752
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
155753
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
155754
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
155755
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
155756
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
155757
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
155758
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
155759
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
155761
|
+
{ key: "assets/index-BGnhry40.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1257479, sha256: "9dae9495031ad4b3f58da8b01d402b9bf1a8849fbbcc5c1a92c2fef67714e298" },
|
|
155762
|
+
{ key: "assets/pdf-BiYGtkj7.js", contentType: "application/javascript; charset=utf-8", offset: 1257487, length: 488199, sha256: "186b07ee58a3a152bd51eb3a45b0d31c391a41345c6a18212fdc1947d43f83db" },
|
|
155763
|
+
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1745686, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
|
|
155764
|
+
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1745759, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
|
|
155765
|
+
{ key: "assets/pdfDocument-CmrdgHk3.js", contentType: "application/javascript; charset=utf-8", offset: 3062793, length: 2858, sha256: "16b5f066b672011380ee7739ffca3db572877072bdbac1ec1931b619be10b90b" },
|
|
155766
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3065651, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
155767
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3070261, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
155768
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3558845, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
155769
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3649769, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
155770
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3740753, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
155771
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 3831733, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
155772
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 3922605, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
155773
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4013585, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
155774
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4122221, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
155775
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4231305, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
155776
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4340353, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
155777
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4448053, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
155778
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 4536161, length: 4947, sha256: "2b2b2ec5619e33c93b438fa5a4091d3ef5bafd728558b2cd3a194579e56b525f" },
|
|
155779
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4541108, length: 17344, sha256: "d057298d75e7373e5e2c4d11b7d1bcbea88e03af555ba63d97641c78509c58e4" }
|
|
155760
155780
|
];
|
|
155761
155781
|
}
|
|
155762
155782
|
});
|
|
@@ -157507,17 +157527,17 @@ var init_iap_plan = __esm({
|
|
|
157507
157527
|
function sameOp(a2, b2) {
|
|
157508
157528
|
return a2.kind === b2.kind && ("locale" in a2 ? a2.locale : void 0) === ("locale" in b2 ? b2.locale : void 0);
|
|
157509
157529
|
}
|
|
157510
|
-
function assertSameAccount(
|
|
157511
|
-
if (
|
|
157530
|
+
function assertSameAccount(planned2, current) {
|
|
157531
|
+
if (planned2.profile === current.profile && planned2.team === current.team && planned2.fingerprint === current.fingerprint) return;
|
|
157512
157532
|
throw new IapProvisionError(
|
|
157513
157533
|
"account",
|
|
157514
|
-
`the plan was made with profile "${
|
|
157534
|
+
`the plan was made with profile "${planned2.profile}" (team ${planned2.team}, key ${planned2.fingerprint}) but this run resolved profile "${current.profile}" (team ${current.team}, key ${current.fingerprint}). Make a new plan with the account you mean.`
|
|
157515
157535
|
);
|
|
157516
157536
|
}
|
|
157517
|
-
function driftOf(
|
|
157518
|
-
if (
|
|
157537
|
+
function driftOf(planned2, live3) {
|
|
157538
|
+
if (planned2.decision === "conflict") return void 0;
|
|
157519
157539
|
if (live3.decision === "conflict") return `${live3.productId} now conflicts: ${live3.conflicts.join("; ")}`;
|
|
157520
|
-
const unplanned = live3.ops.filter((op) => !
|
|
157540
|
+
const unplanned = live3.ops.filter((op) => !planned2.ops.some((p2) => sameOp(p2, op)));
|
|
157521
157541
|
return unplanned.length ? `${live3.productId} now needs ${unplanned.map(describeOp).join(", ")}, which the plan did not list` : void 0;
|
|
157522
157542
|
}
|
|
157523
157543
|
function assertNoDrift(plan, live3) {
|
|
@@ -157669,8 +157689,8 @@ async function runOps(run2, ops, context, manifest) {
|
|
|
157669
157689
|
return steps;
|
|
157670
157690
|
}
|
|
157671
157691
|
function outcomeOf(ops, steps, unmet) {
|
|
157672
|
-
const
|
|
157673
|
-
if (
|
|
157692
|
+
const failed3 = steps.some((s2) => s2.state === "failed");
|
|
157693
|
+
if (failed3) return steps.some((s2) => s2.state === "done" || s2.state === "reconciled") ? "partial" : "failed";
|
|
157674
157694
|
if (unmet.length) return "partial";
|
|
157675
157695
|
if (ops.some((op) => op.kind === "createProduct")) return "created";
|
|
157676
157696
|
return ops.length ? "updated" : "reused";
|
|
@@ -157687,9 +157707,9 @@ async function readBack(run2, context, manifest) {
|
|
|
157687
157707
|
async function unmetFor(item, observed, context) {
|
|
157688
157708
|
return observed ? metadataDiffs(item, observed, await context.pricing.targetAmount(item.price, observed.resourceId)) : [];
|
|
157689
157709
|
}
|
|
157690
|
-
async function knownUnmetFor(item,
|
|
157691
|
-
if (!
|
|
157692
|
-
return metadataDiffs(item,
|
|
157710
|
+
async function knownUnmetFor(item, planned2, context) {
|
|
157711
|
+
if (!planned2.observed) return [];
|
|
157712
|
+
return metadataDiffs(item, planned2.observed, planned2.targetPrice ?? await context.pricing.targetAmount(item.price));
|
|
157693
157713
|
}
|
|
157694
157714
|
async function applyItem(item, live3, context, manifest) {
|
|
157695
157715
|
const base = { target: manifest.target, item, readAt: context.now() };
|
|
@@ -157713,19 +157733,19 @@ function deferredResult(item, live3, context, manifest) {
|
|
|
157713
157733
|
const steps = live3.ops.map((op) => stepFor(op, "notRun"));
|
|
157714
157734
|
return itemResult({ target: manifest.target, item, observed: live3.observed, outcome: "deferred", steps, requirements: [DEFERRED_REQUIREMENT], readAt: context.now() });
|
|
157715
157735
|
}
|
|
157716
|
-
function needsRefresh(
|
|
157717
|
-
return
|
|
157736
|
+
function needsRefresh(planned2) {
|
|
157737
|
+
return planned2.decision !== "conflict" && planned2.ops.length > 0;
|
|
157718
157738
|
}
|
|
157719
|
-
function plannedResult(item,
|
|
157720
|
-
if (
|
|
157721
|
-
return itemResult({ target: manifest.target, item, observed:
|
|
157739
|
+
function plannedResult(item, planned2, plan, context, manifest) {
|
|
157740
|
+
if (planned2.decision === "conflict") return applyItem(item, planned2, context, manifest);
|
|
157741
|
+
return itemResult({ target: manifest.target, item, observed: planned2.observed, outcome: "reused", readAt: new Date(plan.createdAt) });
|
|
157722
157742
|
}
|
|
157723
157743
|
async function applyIap(planDoc, applyContext) {
|
|
157724
157744
|
const plan = verifyPlan2(planDoc);
|
|
157725
157745
|
assertSameAccount(plan.identity, applyContext.identity);
|
|
157726
157746
|
const context = { ...applyContext, pricing: applyContext.pricing ?? new PriceGrid(applyContext.api) };
|
|
157727
157747
|
const manifest = plan.manifest;
|
|
157728
|
-
const refresh = plan.items.flatMap((
|
|
157748
|
+
const refresh = plan.items.flatMap((planned2, i2) => needsRefresh(planned2) ? [i2] : []);
|
|
157729
157749
|
const live3 = await planItemsAt(context, manifest, refresh);
|
|
157730
157750
|
assertNoDrift(plan, live3);
|
|
157731
157751
|
const items = [];
|
|
@@ -157954,6 +157974,17 @@ var init_iap_credentials = __esm({
|
|
|
157954
157974
|
}
|
|
157955
157975
|
});
|
|
157956
157976
|
|
|
157977
|
+
// ../../core/sdk/iap/src/wix-payments-contract.ts
|
|
157978
|
+
var HIMALAYA_SERVE_IAP_ROUTE, APPLE_SALE_RULES;
|
|
157979
|
+
var init_wix_payments_contract = __esm({
|
|
157980
|
+
"../../core/sdk/iap/src/wix-payments-contract.ts"() {
|
|
157981
|
+
HIMALAYA_SERVE_IAP_ROUTE = { prefix: "/himalaya-serve/v1/iap" };
|
|
157982
|
+
APPLE_SALE_RULES = {
|
|
157983
|
+
onlineProgram: { appProductId: (id) => id, productType: "NON_CONSUMABLE" }
|
|
157984
|
+
};
|
|
157985
|
+
}
|
|
157986
|
+
});
|
|
157987
|
+
|
|
157957
157988
|
// ../store-release/iap-draft.ts
|
|
157958
157989
|
import { createHash as createHash38 } from "node:crypto";
|
|
157959
157990
|
function fit(text9, max) {
|
|
@@ -158213,6 +158244,327 @@ var init_redact = __esm({
|
|
|
158213
158244
|
}
|
|
158214
158245
|
});
|
|
158215
158246
|
|
|
158247
|
+
// ../store-release/version.ts
|
|
158248
|
+
var version_exports = {};
|
|
158249
|
+
__export(version_exports, {
|
|
158250
|
+
bumpVersion: () => bumpVersion,
|
|
158251
|
+
readAndroidVersion: () => readAndroidVersion,
|
|
158252
|
+
readAndroidVersionName: () => readAndroidVersionName,
|
|
158253
|
+
readIosMarketingVersion: () => readIosMarketingVersion,
|
|
158254
|
+
readIosVersion: () => readIosVersion,
|
|
158255
|
+
readIosVersionStrings: () => readIosVersionStrings,
|
|
158256
|
+
readIosVersionStringsOrNull: () => readIosVersionStringsOrNull,
|
|
158257
|
+
readTargetVersionKeys: () => readTargetVersionKeys,
|
|
158258
|
+
readTargetVersionStrings: () => readTargetVersionStrings,
|
|
158259
|
+
setAndroidVersion: () => setAndroidVersion,
|
|
158260
|
+
setIosVersion: () => setIosVersion,
|
|
158261
|
+
stampIosVersionStrings: () => stampIosVersionStrings,
|
|
158262
|
+
stampTargetVersion: () => stampTargetVersion,
|
|
158263
|
+
stampVersionKeys: () => stampVersionKeys
|
|
158264
|
+
});
|
|
158265
|
+
import { readFileSync as readFileSync85, writeFileSync as writeFileSync29 } from "node:fs";
|
|
158266
|
+
function readIosVersion(projectYml) {
|
|
158267
|
+
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158268
|
+
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
158269
|
+
if (marketing === null || build3 === null) {
|
|
158270
|
+
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
158271
|
+
}
|
|
158272
|
+
return { marketing, build: Number(build3) };
|
|
158273
|
+
}
|
|
158274
|
+
function setIosVersion(projectYml, v2) {
|
|
158275
|
+
let out2 = replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing);
|
|
158276
|
+
out2 = replaceScalar(out2, "CFBundleVersion", String(v2.build));
|
|
158277
|
+
out2 = out2.replace(
|
|
158278
|
+
/(^[ \t]*# >>> himalaya:live-activity:target[^\n]*\n)([\s\S]*?)(^[ \t]*# <<< himalaya:live-activity:target[^\n]*$)/m,
|
|
158279
|
+
(_match, start, body, end) => {
|
|
158280
|
+
if (!body.trim()) return start + body + end;
|
|
158281
|
+
return start + replaceScalar(replaceScalar(body, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", String(v2.build)) + end;
|
|
158282
|
+
}
|
|
158283
|
+
);
|
|
158284
|
+
return out2;
|
|
158285
|
+
}
|
|
158286
|
+
function readIosVersionStrings(projectYml) {
|
|
158287
|
+
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158288
|
+
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
158289
|
+
if (marketing === null || build3 === null) {
|
|
158290
|
+
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
158291
|
+
}
|
|
158292
|
+
return { marketing, build: build3 };
|
|
158293
|
+
}
|
|
158294
|
+
function readIosVersionStringsOrNull(projectYml) {
|
|
158295
|
+
try {
|
|
158296
|
+
return readIosVersionStrings(projectYml);
|
|
158297
|
+
} catch {
|
|
158298
|
+
return null;
|
|
158299
|
+
}
|
|
158300
|
+
}
|
|
158301
|
+
function stampIosVersionStrings(projectYml, v2) {
|
|
158302
|
+
return replaceScalar(replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", v2.build);
|
|
158303
|
+
}
|
|
158304
|
+
function stampVersionKeys(projectYml, v2) {
|
|
158305
|
+
let out2 = projectYml;
|
|
158306
|
+
if (v2.marketing !== void 0) out2 = replaceScalar(out2, "CFBundleShortVersionString", v2.marketing);
|
|
158307
|
+
if (v2.build !== void 0) out2 = replaceScalar(out2, "CFBundleVersion", v2.build);
|
|
158308
|
+
return out2;
|
|
158309
|
+
}
|
|
158310
|
+
function targetBlock(lines, target) {
|
|
158311
|
+
const head = new RegExp(`^ {2}${target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*$`);
|
|
158312
|
+
const start = lines.findIndex((l2) => head.test(l2));
|
|
158313
|
+
if (start < 0) return null;
|
|
158314
|
+
let end = start + 1;
|
|
158315
|
+
while (end < lines.length && !/^ {0,2}\S/.test(lines[end])) end++;
|
|
158316
|
+
return { start, end };
|
|
158317
|
+
}
|
|
158318
|
+
function readTargetVersionStrings(projectYml, target) {
|
|
158319
|
+
const lines = projectYml.split("\n");
|
|
158320
|
+
const block = targetBlock(lines, target);
|
|
158321
|
+
if (!block) return null;
|
|
158322
|
+
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
158323
|
+
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
158324
|
+
const build3 = matchScalar(body, "CFBundleVersion");
|
|
158325
|
+
return marketing !== null && build3 !== null ? { marketing, build: build3 } : null;
|
|
158326
|
+
}
|
|
158327
|
+
function readTargetVersionKeys(projectYml, target) {
|
|
158328
|
+
const lines = projectYml.split("\n");
|
|
158329
|
+
const block = targetBlock(lines, target);
|
|
158330
|
+
if (!block) return null;
|
|
158331
|
+
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
158332
|
+
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
158333
|
+
const build3 = matchScalar(body, "CFBundleVersion");
|
|
158334
|
+
if (marketing === null && build3 === null) return null;
|
|
158335
|
+
return { ...marketing !== null ? { marketing } : {}, ...build3 !== null ? { build: build3 } : {} };
|
|
158336
|
+
}
|
|
158337
|
+
function stampTargetVersion(yml, target, v2) {
|
|
158338
|
+
const lines = yml.split("\n");
|
|
158339
|
+
const block = targetBlock(lines, target);
|
|
158340
|
+
if (!block) return yml;
|
|
158341
|
+
for (let i2 = block.start + 1; i2 < block.end; i2++) {
|
|
158342
|
+
const inline = /^ {4}info:\s*\{\s*path:\s*([^\s,}]+)\s*\}\s*(#.*)?$/.exec(lines[i2]);
|
|
158343
|
+
if (inline) {
|
|
158344
|
+
lines.splice(i2, 1, " info:", ` path: ${inline[1]}`);
|
|
158345
|
+
block.end++;
|
|
158346
|
+
break;
|
|
158347
|
+
}
|
|
158348
|
+
}
|
|
158349
|
+
const { start, end } = block;
|
|
158350
|
+
const want = {};
|
|
158351
|
+
if (v2.marketing !== void 0) want.CFBundleShortVersionString = v2.marketing;
|
|
158352
|
+
if (v2.build !== void 0) want.CFBundleVersion = v2.build;
|
|
158353
|
+
const seen = /* @__PURE__ */ new Set();
|
|
158354
|
+
let infoAt = -1;
|
|
158355
|
+
let propsAt = -1;
|
|
158356
|
+
for (let i2 = start + 1; i2 < end; i2++) {
|
|
158357
|
+
if (/^ {4}info:\s*$/.test(lines[i2])) infoAt = i2;
|
|
158358
|
+
if (infoAt >= 0 && /^ {6}properties:\s*$/.test(lines[i2]) && lines.slice(infoAt + 1, i2).every((l2) => !/^ {4}\S/.test(l2))) propsAt = i2;
|
|
158359
|
+
const m2 = /^(\s+)(CFBundleShortVersionString|CFBundleVersion):\s*.*$/.exec(lines[i2]);
|
|
158360
|
+
if (m2 && m2[2] in want) {
|
|
158361
|
+
lines[i2] = `${m2[1]}${m2[2]}: "${want[m2[2]]}"`;
|
|
158362
|
+
seen.add(m2[2]);
|
|
158363
|
+
}
|
|
158364
|
+
}
|
|
158365
|
+
const missing = Object.keys(want).filter((k2) => !seen.has(k2)).map((k2) => ` ${k2}: "${want[k2]}"`);
|
|
158366
|
+
if (missing.length && propsAt >= 0) {
|
|
158367
|
+
lines.splice(propsAt + 1, 0, ...missing);
|
|
158368
|
+
} else if (missing.length && infoAt >= 0) {
|
|
158369
|
+
let after = infoAt + 1;
|
|
158370
|
+
while (after < end && /^ {6}\S/.test(lines[after])) after++;
|
|
158371
|
+
lines.splice(after, 0, " properties:", ...missing);
|
|
158372
|
+
}
|
|
158373
|
+
return lines.join("\n");
|
|
158374
|
+
}
|
|
158375
|
+
function readIosMarketingVersion(projectYml) {
|
|
158376
|
+
return matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158377
|
+
}
|
|
158378
|
+
function scalarRe(key2) {
|
|
158379
|
+
return new RegExp(`^(\\s*${key2}:\\s*)("?)([^"\\n#]*?)("?)(\\s*(?:#.*)?)$`, "m");
|
|
158380
|
+
}
|
|
158381
|
+
function matchScalar(content, key2) {
|
|
158382
|
+
const m2 = scalarRe(key2).exec(content);
|
|
158383
|
+
return m2 ? m2[3].trim() : null;
|
|
158384
|
+
}
|
|
158385
|
+
function replaceScalar(content, key2, value) {
|
|
158386
|
+
const re2 = scalarRe(key2);
|
|
158387
|
+
if (!re2.test(content)) throw new Error(`could not locate \`${key2}:\` in project.yml`);
|
|
158388
|
+
return content.replace(re2, (_full, pre, openQ, _oldVal, _closeQ, tail) => {
|
|
158389
|
+
const q2 = openQ ? '"' : "";
|
|
158390
|
+
return `${pre}${q2}${value}${q2}${tail}`;
|
|
158391
|
+
});
|
|
158392
|
+
}
|
|
158393
|
+
function readAndroidVersion(gradle) {
|
|
158394
|
+
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
158395
|
+
const code = /(\bversionCode\s*=\s*)(\d+)/.exec(gradle);
|
|
158396
|
+
if (!name || !code) throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
158397
|
+
return { marketing: name[2], build: Number(code[2]) };
|
|
158398
|
+
}
|
|
158399
|
+
function readAndroidVersionName(gradle) {
|
|
158400
|
+
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
158401
|
+
return name ? name[2] : null;
|
|
158402
|
+
}
|
|
158403
|
+
function setAndroidVersion(gradle, v2) {
|
|
158404
|
+
if (!/\bversionName\s*=\s*"/.test(gradle) || !/\bversionCode\s*=\s*\d+/.test(gradle)) {
|
|
158405
|
+
throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
158406
|
+
}
|
|
158407
|
+
return gradle.replace(/(\bversionName\s*=\s*")[^"]*(")/, `$1${v2.marketing}$2`).replace(/(\bversionCode\s*=\s*)\d+/, `$1${v2.build}`);
|
|
158408
|
+
}
|
|
158409
|
+
function bumpVersion(app, opts) {
|
|
158410
|
+
const iosPath = iosProjectYml(app);
|
|
158411
|
+
const gradlePath = androidGradle(app);
|
|
158412
|
+
const iosYml = readFileSync85(iosPath, "utf8");
|
|
158413
|
+
const gradle = readFileSync85(gradlePath, "utf8");
|
|
158414
|
+
const current = readIosVersion(iosYml);
|
|
158415
|
+
const next = {
|
|
158416
|
+
marketing: opts.marketing ?? current.marketing,
|
|
158417
|
+
build: opts.build === "increment" || opts.build === void 0 ? current.build + (opts.build === "increment" ? 1 : 0) : opts.build
|
|
158418
|
+
};
|
|
158419
|
+
writeFileSync29(iosPath, setIosVersion(iosYml, next));
|
|
158420
|
+
writeFileSync29(gradlePath, setAndroidVersion(gradle, next));
|
|
158421
|
+
return next;
|
|
158422
|
+
}
|
|
158423
|
+
var init_version = __esm({
|
|
158424
|
+
"../store-release/version.ts"() {
|
|
158425
|
+
init_paths2();
|
|
158426
|
+
}
|
|
158427
|
+
});
|
|
158428
|
+
|
|
158429
|
+
// ../store-release/store-spec.ts
|
|
158430
|
+
function defaultProdBundleId(devBundleId) {
|
|
158431
|
+
return devBundleId.replace(/\.dev$/, "");
|
|
158432
|
+
}
|
|
158433
|
+
var init_store_spec = __esm({
|
|
158434
|
+
"../store-release/store-spec.ts"() {
|
|
158435
|
+
init_paths2();
|
|
158436
|
+
init_version();
|
|
158437
|
+
init_embedded_bundles();
|
|
158438
|
+
init_embedded_bundles();
|
|
158439
|
+
}
|
|
158440
|
+
});
|
|
158441
|
+
|
|
158442
|
+
// src/iap-config-edit.ts
|
|
158443
|
+
import { existsSync as existsSync73, readFileSync as readFileSync86 } from "node:fs";
|
|
158444
|
+
import { basename as basename18, join as join72 } from "node:path";
|
|
158445
|
+
import ts8 from "typescript";
|
|
158446
|
+
function bindPurchasesAppInConfig(source, options) {
|
|
158447
|
+
const fileName = options.fileName ?? "config.ts";
|
|
158448
|
+
const kind = fileName.endsWith(".ts") ? ts8.ScriptKind.TS : ts8.ScriptKind.JS;
|
|
158449
|
+
const file2 = ts8.createSourceFile(fileName, source, ts8.ScriptTarget.Latest, true, kind);
|
|
158450
|
+
const wanted = `wixIap: { purchasesAppId: ${JSON.stringify(options.purchasesAppId)} }`;
|
|
158451
|
+
const unchanged = (result) => ({ source, changed: false, applied: [], conflicts: [], instructions: [], ...result });
|
|
158452
|
+
const app = defineAppLiteral(file2);
|
|
158453
|
+
if (!app || app.properties.length === 0) {
|
|
158454
|
+
return unchanged({ instructions: [`${fileName} does not export a defineApp({ \u2026 }) object literal, so it was not edited. Add ${wanted} and "iap" in capabilities to the app's config.`] });
|
|
158455
|
+
}
|
|
158456
|
+
const site = siteFinding(app, options.siteId, fileName);
|
|
158457
|
+
const bundle = bundleFinding(app, options, fileName);
|
|
158458
|
+
const binding2 = bindingFinding(app, file2, options.purchasesAppId, wanted, fileName);
|
|
158459
|
+
const conflicts = [site, bundle, binding2].flatMap((f2) => f2.conflict ? [f2.conflict] : []);
|
|
158460
|
+
if (conflicts.length) return unchanged({ conflicts });
|
|
158461
|
+
const capability = capabilityFinding(app, fileName);
|
|
158462
|
+
const splices = [binding2.splice, capability.splice].filter((s2) => !!s2);
|
|
158463
|
+
return {
|
|
158464
|
+
source: applySplices(source, splices),
|
|
158465
|
+
changed: splices.length > 0,
|
|
158466
|
+
applied: [binding2.applied, capability.applied].filter((a2) => !!a2),
|
|
158467
|
+
conflicts: [],
|
|
158468
|
+
instructions: [site.instruction, binding2.instruction, capability.instruction, bundle.instruction].filter((i2) => !!i2)
|
|
158469
|
+
};
|
|
158470
|
+
}
|
|
158471
|
+
function siteFinding(app, siteId, fileName) {
|
|
158472
|
+
const check = `make sure the app's member login uses siteId ${JSON.stringify(siteId)}: a build bakes the purchases app only for the site its login resolves to.`;
|
|
158473
|
+
const login = loginOf(app);
|
|
158474
|
+
if (login.kind !== "member") return { instruction: `${fileName} does not write auth as a WixConsumerAuthProvider({ \u2026 }) call it can read, so ${check}` };
|
|
158475
|
+
const found = lookup2(login.literal, "siteId");
|
|
158476
|
+
const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
158477
|
+
if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `auth's siteId is not written as a literal, so ${check}` };
|
|
158478
|
+
if (value.text.toLowerCase() === siteId.toLowerCase()) return {};
|
|
158479
|
+
return { conflict: `auth's siteId is "${value.text}", but the purchases app is registered on site "${siteId}". A build bakes the binding only when they match, so ${fileName} was not edited.` };
|
|
158480
|
+
}
|
|
158481
|
+
function bundleFinding(app, { bundleId, storeBundleId }, fileName) {
|
|
158482
|
+
if (storeBundleId) {
|
|
158483
|
+
if (storeBundleId === bundleId) return {};
|
|
158484
|
+
return { conflict: `store/store.config.yaml builds bundle "${storeBundleId}", but the purchases app is registered for "${bundleId}". ${fileName} was not edited.` };
|
|
158485
|
+
}
|
|
158486
|
+
const found = lookup2(app, "bundleId");
|
|
158487
|
+
const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
158488
|
+
if (!value || !ts8.isStringLiteralLike(value)) {
|
|
158489
|
+
return { instruction: `${fileName} does not write bundleId as a literal: make sure this app builds bundle ${JSON.stringify(bundleId)}, the one the purchases app is registered for.` };
|
|
158490
|
+
}
|
|
158491
|
+
if (value.text === bundleId || defaultProdBundleId(value.text) === bundleId) return {};
|
|
158492
|
+
return { conflict: `${fileName} builds bundle "${value.text}", but the purchases app is registered for "${bundleId}". This is another app's config, so it was not edited.` };
|
|
158493
|
+
}
|
|
158494
|
+
function bindingFinding(app, file2, purchasesAppId, wanted, fileName) {
|
|
158495
|
+
const wixIap = lookup2(app, "wixIap");
|
|
158496
|
+
if (wixIap.kind === "absent") return { splice: appendProperties(app, file2, [`${wanted},`]), applied: "wixIap.purchasesAppId" };
|
|
158497
|
+
const literal = wixIap.kind === "written" ? unwrap(wixIap.node.initializer) : void 0;
|
|
158498
|
+
if (!literal || !ts8.isObjectLiteralExpression(literal)) return { instruction: `${fileName} computes wixIap, so it was not edited: it must evaluate to ${wanted}.` };
|
|
158499
|
+
const current = lookup2(literal, "purchasesAppId");
|
|
158500
|
+
if (current.kind === "absent") return { splice: appendProperties(literal, file2, [`purchasesAppId: ${JSON.stringify(purchasesAppId)},`]), applied: "wixIap.purchasesAppId" };
|
|
158501
|
+
const value = current.kind === "written" ? unwrap(current.node.initializer) : void 0;
|
|
158502
|
+
if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `${fileName} computes wixIap.purchasesAppId, so it was not edited: it must evaluate to ${JSON.stringify(purchasesAppId)}.` };
|
|
158503
|
+
if (value.text === purchasesAppId) return {};
|
|
158504
|
+
return { conflict: `${fileName} already binds purchases app "${value.text}", but this site's purchases app for the bundle is "${purchasesAppId}". Nothing was changed; fix whichever is stale.` };
|
|
158505
|
+
}
|
|
158506
|
+
function capabilityFinding(app, fileName) {
|
|
158507
|
+
const capabilities = lookup2(app, "capabilities");
|
|
158508
|
+
const list = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
|
|
158509
|
+
if (capabilities.kind !== "absent" && (!list || !ts8.isArrayLiteralExpression(list))) {
|
|
158510
|
+
return { instruction: `Add "iap" to capabilities: the purchases app is baked only into a build that declares it, and ${fileName} does not list capabilities inline.` };
|
|
158511
|
+
}
|
|
158512
|
+
if (!list) return { instruction: `Add capabilities: ["iap"] (with the app's other capabilities) to ${fileName}: the purchases app is baked only into a build that declares it.` };
|
|
158513
|
+
const elements = list.elements;
|
|
158514
|
+
if (elements.some((e2) => ts8.isStringLiteralLike(e2) && e2.text === "iap")) return {};
|
|
158515
|
+
const last = elements[elements.length - 1];
|
|
158516
|
+
return {
|
|
158517
|
+
splice: last ? { at: last.end, end: last.end, text: ', "iap"' } : { at: list.getStart(), end: list.end, text: '["iap"]' },
|
|
158518
|
+
applied: "iap capability"
|
|
158519
|
+
};
|
|
158520
|
+
}
|
|
158521
|
+
function withStoreBundle(dir, options) {
|
|
158522
|
+
if (options.storeBundleId) return options;
|
|
158523
|
+
const path2 = join72(dir, "store", "store.config.yaml");
|
|
158524
|
+
if (!existsSync73(path2)) return options;
|
|
158525
|
+
const storeBundleId = parseStoreConfig(readFileSync86(path2, "utf8")).ios?.bundleId;
|
|
158526
|
+
return storeBundleId ? { ...options, storeBundleId } : options;
|
|
158527
|
+
}
|
|
158528
|
+
function previewIapConfigEdit(dir, options) {
|
|
158529
|
+
const path2 = configEntry(dir);
|
|
158530
|
+
if (!path2) return void 0;
|
|
158531
|
+
if (isSymlink2(path2)) return { path: path2, changed: false, applied: [], conflicts: [], instructions: [`${basename18(path2)} is a symlink, so it would not be edited: add the purchases app in the file it points to.`] };
|
|
158532
|
+
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync86(path2, "utf8"), { ...withStoreBundle(dir, options), fileName: basename18(path2) });
|
|
158533
|
+
return { path: path2, changed, applied, conflicts, instructions };
|
|
158534
|
+
}
|
|
158535
|
+
async function applyIapConfigEdit(dir, options, validate4) {
|
|
158536
|
+
const path2 = configEntry(dir);
|
|
158537
|
+
if (!path2) return void 0;
|
|
158538
|
+
const fileName = basename18(path2);
|
|
158539
|
+
const refuse7 = (why) => ({ path: path2, changed: false, applied: [], conflicts: [], instructions: [why] });
|
|
158540
|
+
if (isSymlink2(path2)) return refuse7(`${fileName} is a symlink, so it was not edited: add the purchases app in the file it points to.`);
|
|
158541
|
+
const original = readFileSync86(path2, "utf8");
|
|
158542
|
+
const edit = bindPurchasesAppInConfig(original, { ...withStoreBundle(dir, options), fileName });
|
|
158543
|
+
const { applied, conflicts, instructions } = edit;
|
|
158544
|
+
if (!edit.changed) return { path: path2, changed: false, applied, conflicts, instructions };
|
|
158545
|
+
const backup = backUpConfig(dir, "store-iap-backup", fileName, original);
|
|
158546
|
+
if (!backup) return refuse7(`.himi is not a plain directory in this package (a symlink?), so ${fileName} was not edited.`);
|
|
158547
|
+
writeFileAtomic(path2, edit.source);
|
|
158548
|
+
const introduced = await introducedErrors(dir, validate4, {
|
|
158549
|
+
restore: () => writeFileAtomic(path2, original),
|
|
158550
|
+
reapply: () => writeFileAtomic(path2, edit.source)
|
|
158551
|
+
}, () => false).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
158552
|
+
if (introduced) {
|
|
158553
|
+
writeFileAtomic(path2, original);
|
|
158554
|
+
return { path: path2, changed: false, applied: [], conflicts, instructions: [`Add to ${fileName} by hand: ${applied.join(", ")}.`, ...instructions], backup, rolledBack: introduced };
|
|
158555
|
+
}
|
|
158556
|
+
return { path: path2, changed: true, applied, conflicts, instructions, backup };
|
|
158557
|
+
}
|
|
158558
|
+
var init_iap_config_edit = __esm({
|
|
158559
|
+
"src/iap-config-edit.ts"() {
|
|
158560
|
+
init_app_config_loader();
|
|
158561
|
+
init_config_source_edit();
|
|
158562
|
+
init_progress();
|
|
158563
|
+
init_preflight();
|
|
158564
|
+
init_store_spec();
|
|
158565
|
+
}
|
|
158566
|
+
});
|
|
158567
|
+
|
|
158216
158568
|
// src/store-iap-catalog.ts
|
|
158217
158569
|
function amountText(value) {
|
|
158218
158570
|
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
@@ -158368,6 +158720,287 @@ var init_store_iap_catalog = __esm({
|
|
|
158368
158720
|
}
|
|
158369
158721
|
});
|
|
158370
158722
|
|
|
158723
|
+
// src/store-iap-purchases.ts
|
|
158724
|
+
function createPurchasesOwnerApi(call) {
|
|
158725
|
+
return {
|
|
158726
|
+
listApps: async () => (await allPages(call, `${PURCHASES}/apps/query`, "apps")).map(decodeApp),
|
|
158727
|
+
registerApp: async ({ name, bundleId }) => {
|
|
158728
|
+
const reply = await call("POST", `${PURCHASES}/apps`, { app: { name, appleConfig: { bundleId } } });
|
|
158729
|
+
return decodeApp(reply.app);
|
|
158730
|
+
},
|
|
158731
|
+
setAppleCredentials: async (appId2, key2) => {
|
|
158732
|
+
await call("POST", `${PURCHASES}/apps/${encodeURIComponent(appId2)}/apple-credentials`, {
|
|
158733
|
+
inAppPurchaseKeyId: key2.keyId,
|
|
158734
|
+
issuerId: key2.issuerId,
|
|
158735
|
+
privateKey: key2.privateKey
|
|
158736
|
+
});
|
|
158737
|
+
},
|
|
158738
|
+
listProducts: async (appId2) => (await allPages(call, `${PURCHASES}/apps/${encodeURIComponent(appId2)}/products/query`, "products")).map(decodeProduct),
|
|
158739
|
+
addProduct: async (appId2, product) => {
|
|
158740
|
+
const reply = await call("POST", `${PURCHASES}/apps/${encodeURIComponent(appId2)}/products`, { product: { ...product, active: true } });
|
|
158741
|
+
return decodeProduct(reply.product);
|
|
158742
|
+
}
|
|
158743
|
+
};
|
|
158744
|
+
}
|
|
158745
|
+
function wixIapProviderConnector(call, route) {
|
|
158746
|
+
return {
|
|
158747
|
+
connect: async (appId2) => {
|
|
158748
|
+
const reply = await call("POST", `${route.prefix}/provider-account/connect`, { appId: appId2 });
|
|
158749
|
+
return { connected: reply.readiness?.providerAccountConnected === true };
|
|
158750
|
+
}
|
|
158751
|
+
};
|
|
158752
|
+
}
|
|
158753
|
+
function refusalCode(error) {
|
|
158754
|
+
const code = error?.body?.details?.applicationError?.code;
|
|
158755
|
+
return typeof code === "string" ? code : void 0;
|
|
158756
|
+
}
|
|
158757
|
+
async function allPages(call, path2, field) {
|
|
158758
|
+
const items = [];
|
|
158759
|
+
let cursor;
|
|
158760
|
+
for (let pages2 = 0; pages2 < MAX_PAGES3; pages2++) {
|
|
158761
|
+
const reply = await call("POST", path2, { query: { cursorPaging: { limit: PAGE3, ...cursor ? { cursor } : {} } } });
|
|
158762
|
+
const page = reply[field];
|
|
158763
|
+
if (!Array.isArray(page)) throw new Error(`the purchases service answered ${path2} without a ${field} list`);
|
|
158764
|
+
items.push(...page);
|
|
158765
|
+
const paging = reply.pagingMetadata;
|
|
158766
|
+
cursor = paging?.hasNext !== false && typeof paging?.cursors?.next === "string" && paging.cursors.next ? paging.cursors.next : void 0;
|
|
158767
|
+
if (!cursor) return items;
|
|
158768
|
+
}
|
|
158769
|
+
throw new Error(`${path2} had more than ${MAX_PAGES3} pages; refusing to plan from a partial ${field} list`);
|
|
158770
|
+
}
|
|
158771
|
+
function decodeApp(raw) {
|
|
158772
|
+
const app = raw;
|
|
158773
|
+
if (typeof app?.id !== "string" || typeof app.appleConfig?.bundleId !== "string") throw new Error("the purchases service returned an app without an id and bundle id");
|
|
158774
|
+
return { id: app.id, name: typeof app.name === "string" ? app.name : "", bundleId: app.appleConfig.bundleId, privateKeyStored: app.appleConfig.privateKeyStored === true };
|
|
158775
|
+
}
|
|
158776
|
+
function decodeProduct(raw) {
|
|
158777
|
+
const p2 = raw;
|
|
158778
|
+
if (typeof p2?.id !== "string" || typeof p2.appProductId !== "string" || typeof p2.storeProductId !== "string") {
|
|
158779
|
+
throw new Error("the purchases service returned a product without its ids");
|
|
158780
|
+
}
|
|
158781
|
+
return { id: p2.id, appProductId: p2.appProductId, storeProductId: p2.storeProductId, type: String(p2.type ?? ""), active: p2.active === true };
|
|
158782
|
+
}
|
|
158783
|
+
var PURCHASES, PAGE3, MAX_PAGES3;
|
|
158784
|
+
var init_store_iap_purchases = __esm({
|
|
158785
|
+
"src/store-iap-purchases.ts"() {
|
|
158786
|
+
PURCHASES = "/_api/mobile-apps-iap-purchases/v1";
|
|
158787
|
+
PAGE3 = 100;
|
|
158788
|
+
MAX_PAGES3 = 100;
|
|
158789
|
+
}
|
|
158790
|
+
});
|
|
158791
|
+
|
|
158792
|
+
// src/store-iap-connect.ts
|
|
158793
|
+
async function connectIap(manifest, deps, options) {
|
|
158794
|
+
const { target } = manifest;
|
|
158795
|
+
const report3 = (app2, appId2, rest) => {
|
|
158796
|
+
const steps = [app2, rest.credentials, rest.provider, ...rest.mappings];
|
|
158797
|
+
return {
|
|
158798
|
+
site: target.wixSiteId,
|
|
158799
|
+
bundleId: target.bundleId,
|
|
158800
|
+
applied: options.apply,
|
|
158801
|
+
complete: steps.every((step) => step.state === "reused" || step.state === "done"),
|
|
158802
|
+
purchasesAppId: appId2,
|
|
158803
|
+
app: app2,
|
|
158804
|
+
...rest
|
|
158805
|
+
};
|
|
158806
|
+
};
|
|
158807
|
+
const found = await findOrRegister(deps.api, manifest, options.apply);
|
|
158808
|
+
if (!found.app) {
|
|
158809
|
+
const skipped = found.step.state === "planned" ? planned : noApp;
|
|
158810
|
+
return report3(found.step, null, {
|
|
158811
|
+
credentials: found.step.state === "planned" ? credentialsPlan(deps.appleKey) : skipped("the app is not registered"),
|
|
158812
|
+
provider: found.step.state === "planned" ? providerPlan(deps.provider) : skipped("the app is not registered"),
|
|
158813
|
+
mappings: manifest.items.map((item) => mappingWithoutApp(item, found.step.state === "planned"))
|
|
158814
|
+
});
|
|
158815
|
+
}
|
|
158816
|
+
const { app } = found;
|
|
158817
|
+
const credentials = await storeKey(deps, app, options.apply);
|
|
158818
|
+
const provider = await connectProvider(deps.provider, app.id, options.apply);
|
|
158819
|
+
const mappings = await mapItems(deps.api, app.id, manifest.items, options.apply);
|
|
158820
|
+
return report3(found.step, app.id, { credentials, provider, mappings });
|
|
158821
|
+
}
|
|
158822
|
+
async function findOrRegister(api2, manifest, apply) {
|
|
158823
|
+
const { bundleId, himiApp, wixSiteId } = manifest.target;
|
|
158824
|
+
const existing = (await api2.listApps()).find((app) => app.bundleId === bundleId);
|
|
158825
|
+
if (existing) return { app: existing, step: { state: "reused", detail: `purchases app ${existing.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158826
|
+
if (!apply) return { step: { state: "planned", detail: `register ${bundleId} on site ${wixSiteId}` } };
|
|
158827
|
+
try {
|
|
158828
|
+
const app = await api2.registerApp({ name: himiApp, bundleId });
|
|
158829
|
+
return { app, step: { state: "done", detail: `registered purchases app ${app.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158830
|
+
} catch (error) {
|
|
158831
|
+
if (refusalCode(error) !== "ALREADY_EXISTS") return { step: failed("register the app", error) };
|
|
158832
|
+
let apps;
|
|
158833
|
+
try {
|
|
158834
|
+
apps = await api2.listApps();
|
|
158835
|
+
} catch (rereadError) {
|
|
158836
|
+
return { step: failed("re-read the site's purchases apps after the bundle was reported registered", rereadError) };
|
|
158837
|
+
}
|
|
158838
|
+
const raced = apps.find((app) => app.bundleId === bundleId);
|
|
158839
|
+
if (raced) return { app: raced, step: { state: "reused", detail: `purchases app ${raced.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158840
|
+
return {
|
|
158841
|
+
step: {
|
|
158842
|
+
state: "conflict",
|
|
158843
|
+
code: "bundle_registered_elsewhere",
|
|
158844
|
+
detail: `${bundleId} is already registered to another app, on another site (this site has none for it). A bundle id belongs to one purchases app platform-wide; only the owner of that registration can remove it. Nothing was changed.`
|
|
158845
|
+
}
|
|
158846
|
+
};
|
|
158847
|
+
}
|
|
158848
|
+
}
|
|
158849
|
+
async function storeKey(deps, app, apply) {
|
|
158850
|
+
if (app.privateKeyStored) return { state: "reused", detail: "an In-App Purchase key is already stored" };
|
|
158851
|
+
if (!deps.appleKey) return credentialsPlan(null);
|
|
158852
|
+
if (!apply) return credentialsPlan(deps.appleKey);
|
|
158853
|
+
try {
|
|
158854
|
+
await deps.api.setAppleCredentials(app.id, deps.appleKey);
|
|
158855
|
+
return { state: "done", detail: "stored the In-App Purchase key" };
|
|
158856
|
+
} catch (error) {
|
|
158857
|
+
return failed("store the In-App Purchase key", error);
|
|
158858
|
+
}
|
|
158859
|
+
}
|
|
158860
|
+
function credentialsPlan(key2) {
|
|
158861
|
+
return key2 ? { state: "planned", detail: "store the In-App Purchase key" } : {
|
|
158862
|
+
state: "blocked",
|
|
158863
|
+
code: "apple_key_missing",
|
|
158864
|
+
detail: "no In-App Purchase key: create one in App Store Connect \u2192 Users and Access \u2192 Integrations \u2192 In-App Purchase, then rerun with --iap-key <AuthKey.p8> --iap-key-id <key id> (an App Store Connect API key is rejected)."
|
|
158865
|
+
};
|
|
158866
|
+
}
|
|
158867
|
+
async function connectProvider(provider, appId2, apply) {
|
|
158868
|
+
if (!provider || !apply) return providerPlan(provider);
|
|
158869
|
+
try {
|
|
158870
|
+
const { connected } = await provider.connect(appId2);
|
|
158871
|
+
return connected ? { state: "done", detail: "the appleIAP payment provider is connected on the site" } : { state: "blocked", code: "provider_not_connected", detail: "wix-iap answered, but the appleIAP provider account is not connected" };
|
|
158872
|
+
} catch (error) {
|
|
158873
|
+
const e2 = error;
|
|
158874
|
+
if (e2?.status === 404 && !e2.body?.details?.applicationError?.code) return providerPlan(null);
|
|
158875
|
+
return failed("connect the appleIAP provider", error);
|
|
158876
|
+
}
|
|
158877
|
+
}
|
|
158878
|
+
function providerPlan(provider) {
|
|
158879
|
+
return provider ? { state: "planned", detail: "connect the appleIAP payment provider through wix-iap" } : {
|
|
158880
|
+
state: "blocked",
|
|
158881
|
+
code: "provider_route_unavailable",
|
|
158882
|
+
detail: "the appleIAP provider is connected through Serve's IAP routes (wix-iap ConnectProviderAccount), and this Serve target has none."
|
|
158883
|
+
};
|
|
158884
|
+
}
|
|
158885
|
+
async function mapItems(api2, appId2, items, apply) {
|
|
158886
|
+
let catalog3;
|
|
158887
|
+
try {
|
|
158888
|
+
catalog3 = await api2.listProducts(appId2);
|
|
158889
|
+
} catch (error) {
|
|
158890
|
+
return items.map((item) => {
|
|
158891
|
+
const target = mappingTarget(item);
|
|
158892
|
+
return "skip" in target ? target.skip : { ...target, ...failed("read the app's catalog", error) };
|
|
158893
|
+
});
|
|
158894
|
+
}
|
|
158895
|
+
const steps = [];
|
|
158896
|
+
for (const item of items) {
|
|
158897
|
+
const target = mappingTarget(item);
|
|
158898
|
+
if ("skip" in target) {
|
|
158899
|
+
steps.push(target.skip);
|
|
158900
|
+
continue;
|
|
158901
|
+
}
|
|
158902
|
+
const decided = decide(catalog3, target);
|
|
158903
|
+
if (decided || !apply) {
|
|
158904
|
+
steps.push(decided ?? { ...target, state: "planned", detail: `map ${target.appProductId} \u2192 ${target.storeProductId}` });
|
|
158905
|
+
continue;
|
|
158906
|
+
}
|
|
158907
|
+
try {
|
|
158908
|
+
catalog3.push(await api2.addProduct(appId2, { appProductId: target.appProductId, storeProductId: target.storeProductId, type: target.type }));
|
|
158909
|
+
steps.push({ ...target, state: "done", detail: `mapped ${target.appProductId} \u2192 ${target.storeProductId}` });
|
|
158910
|
+
} catch (error) {
|
|
158911
|
+
const now = await api2.listProducts(appId2).catch(() => catalog3);
|
|
158912
|
+
steps.push(decide(now, target) ?? { ...target, ...failed("map the item", error) });
|
|
158913
|
+
}
|
|
158914
|
+
}
|
|
158915
|
+
return steps;
|
|
158916
|
+
}
|
|
158917
|
+
function mappingTarget(item) {
|
|
158918
|
+
const skip = (entity2, detail) => ({ skip: { entity: entity2, appProductId: null, storeProductId: item.productId, state: "skipped", code: "mapping_unsupported", detail } });
|
|
158919
|
+
if (!item.wix || item.unlocks?.length) {
|
|
158920
|
+
return skip(item.productId, "a consumable tier unlocks several Wix items, but a purchase pays one order item, so it cannot be mapped");
|
|
158921
|
+
}
|
|
158922
|
+
const entity = `${item.wix.entityType}:${item.wix.entityId}`;
|
|
158923
|
+
const rule = APPLE_SALE_RULES[item.wix.entityType];
|
|
158924
|
+
if (!rule) return skip(entity, `the App Store purchase flow does not support ${item.wix.entityType} items yet`);
|
|
158925
|
+
if (PRODUCT_TYPE[item.type] !== rule.productType) {
|
|
158926
|
+
return skip(entity, `the App Store purchase flow sells ${item.wix.entityType} items only as ${rule.productType}, not ${PRODUCT_TYPE[item.type]}`);
|
|
158927
|
+
}
|
|
158928
|
+
return { entity, appProductId: rule.appProductId(item.wix.entityId), storeProductId: item.productId, type: rule.productType };
|
|
158929
|
+
}
|
|
158930
|
+
function decide(catalog3, target) {
|
|
158931
|
+
const byWixItem = catalog3.find((p2) => p2.appProductId === target.appProductId);
|
|
158932
|
+
if (byWixItem) {
|
|
158933
|
+
if (byWixItem.storeProductId !== target.storeProductId) {
|
|
158934
|
+
return { ...target, state: "conflict", code: "mapping_conflict", detail: `${target.appProductId} is already mapped to ${byWixItem.storeProductId}; it was left as it is` };
|
|
158935
|
+
}
|
|
158936
|
+
if (byWixItem.type !== target.type) {
|
|
158937
|
+
return { ...target, state: "conflict", code: "mapping_type_mismatch", detail: `${target.appProductId} \u2192 ${target.storeProductId} exists as ${byWixItem.type}, which the purchase flow cannot sell; it was left as it is` };
|
|
158938
|
+
}
|
|
158939
|
+
if (!byWixItem.active) {
|
|
158940
|
+
return { ...target, state: "conflict", code: "mapping_inactive", detail: `${target.appProductId} \u2192 ${target.storeProductId} exists but is inactive (taken off sale); it was left as it is` };
|
|
158941
|
+
}
|
|
158942
|
+
return { ...target, state: "reused", detail: `${target.appProductId} \u2192 ${target.storeProductId}` };
|
|
158943
|
+
}
|
|
158944
|
+
const bySku = catalog3.find((p2) => p2.storeProductId === target.storeProductId);
|
|
158945
|
+
if (bySku) {
|
|
158946
|
+
return { ...target, state: "conflict", code: "sku_in_use", detail: `${target.storeProductId} is already mapped to ${bySku.appProductId}; it was left as it is` };
|
|
158947
|
+
}
|
|
158948
|
+
return void 0;
|
|
158949
|
+
}
|
|
158950
|
+
function mappingWithoutApp(item, planning) {
|
|
158951
|
+
const target = mappingTarget(item);
|
|
158952
|
+
if ("skip" in target) return target.skip;
|
|
158953
|
+
return planning ? { ...target, state: "planned", detail: `map ${target.appProductId} \u2192 ${target.storeProductId}` } : { ...target, ...noApp("the app is not registered") };
|
|
158954
|
+
}
|
|
158955
|
+
function planned(detail) {
|
|
158956
|
+
return { state: "planned", detail };
|
|
158957
|
+
}
|
|
158958
|
+
function noApp(why) {
|
|
158959
|
+
return { state: "skipped", code: "no_purchases_app", detail: `${why}, so this step did not run` };
|
|
158960
|
+
}
|
|
158961
|
+
function failed(what, error) {
|
|
158962
|
+
return { state: "failed", code: "request_failed", detail: `could not ${what}: ${error instanceof Error ? error.message : String(error)}` };
|
|
158963
|
+
}
|
|
158964
|
+
var PRODUCT_TYPE;
|
|
158965
|
+
var init_store_iap_connect = __esm({
|
|
158966
|
+
"src/store-iap-connect.ts"() {
|
|
158967
|
+
init_wix_payments_contract();
|
|
158968
|
+
init_store_iap_purchases();
|
|
158969
|
+
PRODUCT_TYPE = { nonConsumable: "NON_CONSUMABLE", consumable: "CONSUMABLE" };
|
|
158970
|
+
}
|
|
158971
|
+
});
|
|
158972
|
+
|
|
158973
|
+
// src/serve-preview.ts
|
|
158974
|
+
function parsePreviewTag(value) {
|
|
158975
|
+
if (value === void 0 || value === "") return void 0;
|
|
158976
|
+
if (!TAG.test(value)) throw new PreviewTagError(`invalid Serve preview tag ${JSON.stringify(value)}: expected dp-<tag> as dpx deploy-preview prints it`);
|
|
158977
|
+
return value;
|
|
158978
|
+
}
|
|
158979
|
+
function isServeRequest(url) {
|
|
158980
|
+
const u2 = new URL(String(url));
|
|
158981
|
+
return u2.protocol === "https:" && WIX_HOSTS.has(u2.hostname) && SERVE_MOUNTS.some((mount) => u2.pathname.startsWith(mount));
|
|
158982
|
+
}
|
|
158983
|
+
function servePreviewFetch(fetchImpl, previewTag) {
|
|
158984
|
+
if (!previewTag) return fetchImpl;
|
|
158985
|
+
return ((input, init) => {
|
|
158986
|
+
const url = input instanceof Request ? input.url : String(input);
|
|
158987
|
+
if (!isServeRequest(url)) return fetchImpl(input, init);
|
|
158988
|
+
const headers2 = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
158989
|
+
headers2.set("x-wix-route-serve", previewTag);
|
|
158990
|
+
return fetchImpl(input, { ...init, headers: headers2 });
|
|
158991
|
+
});
|
|
158992
|
+
}
|
|
158993
|
+
var TAG, WIX_HOSTS, SERVE_MOUNTS, PreviewTagError;
|
|
158994
|
+
var init_serve_preview = __esm({
|
|
158995
|
+
"src/serve-preview.ts"() {
|
|
158996
|
+
TAG = /^dp-[a-z0-9]+$/;
|
|
158997
|
+
WIX_HOSTS = /* @__PURE__ */ new Set(["www.wixapis.com", "bo.wix.com", "www.wix.com"]);
|
|
158998
|
+
SERVE_MOUNTS = ["/himalaya-serve/", "/_api/himalaya-serve/"];
|
|
158999
|
+
PreviewTagError = class extends Error {
|
|
159000
|
+
};
|
|
159001
|
+
}
|
|
159002
|
+
});
|
|
159003
|
+
|
|
158371
159004
|
// src/store-iap.ts
|
|
158372
159005
|
var store_iap_exports = {};
|
|
158373
159006
|
__export(store_iap_exports, {
|
|
@@ -158378,9 +159011,9 @@ __export(store_iap_exports, {
|
|
|
158378
159011
|
runStoreIap: () => runStoreIap
|
|
158379
159012
|
});
|
|
158380
159013
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
158381
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as
|
|
159014
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as readFileSync87, realpathSync as realpathSync13, rmSync as rmSync18, writeFileSync as writeFileSync30 } from "node:fs";
|
|
158382
159015
|
import { homedir as homedir8, hostname } from "node:os";
|
|
158383
|
-
import { join as
|
|
159016
|
+
import { join as join73 } from "node:path";
|
|
158384
159017
|
function scrubDeep(value, scrub) {
|
|
158385
159018
|
if (typeof value === "string") return scrub(value);
|
|
158386
159019
|
if (Array.isArray(value)) return value.map((v2) => scrubDeep(v2, scrub));
|
|
@@ -158686,6 +159319,136 @@ async function draftCommand(flags, deps, out2) {
|
|
|
158686
159319
|
}
|
|
158687
159320
|
return draft.manifest ? 0 : 1;
|
|
158688
159321
|
}
|
|
159322
|
+
function readInAppPurchaseKey(flags, deps, creds) {
|
|
159323
|
+
const path2 = textFlag(flags, "iap-key");
|
|
159324
|
+
const keyId = textFlag(flags, "iap-key-id");
|
|
159325
|
+
if (!path2 && !keyId) return null;
|
|
159326
|
+
if (!path2 || !keyId) throw new UsageError("store iap connect needs --iap-key <AuthKey.p8> and --iap-key-id <id> together");
|
|
159327
|
+
if (!/^[A-Z0-9]{10}$/.test(keyId)) throw new UsageError(`--iap-key-id must be the 10-character key id App Store Connect shows, got "${keyId}"`);
|
|
159328
|
+
let privateKey;
|
|
159329
|
+
try {
|
|
159330
|
+
assertCredentialOutsideRepo("--iap-key", (deps.realpath ?? realpathSync13)(path2));
|
|
159331
|
+
privateKey = readInput(deps, path2, "In-App Purchase key");
|
|
159332
|
+
} catch (error) {
|
|
159333
|
+
throw new KeyError(error.message);
|
|
159334
|
+
}
|
|
159335
|
+
if (!/-----BEGIN PRIVATE KEY-----/.test(privateKey)) throw new KeyError(`${path2} is not a PEM private key (an App Store Connect .p8 file)`);
|
|
159336
|
+
return { keyId, issuerId: creds.key.issuerId, privateKey };
|
|
159337
|
+
}
|
|
159338
|
+
function firstProblem(report3) {
|
|
159339
|
+
const steps = [report3.app, report3.credentials, report3.provider, ...report3.mappings];
|
|
159340
|
+
return steps.find((step) => step.code)?.code ?? (report3.complete ? void 0 : "setup_incomplete");
|
|
159341
|
+
}
|
|
159342
|
+
function printConnect(out2, report3, heading) {
|
|
159343
|
+
out2.line(`himi store iap connect \u2014 ${heading}`);
|
|
159344
|
+
out2.line(` ${pad("site")}${report3.site} \xB7 bundle ${report3.bundleId}`);
|
|
159345
|
+
const row = (label2, step) => out2.line(` ${pad(label2)}${step.state.padEnd(9)}${step.detail}`);
|
|
159346
|
+
row("app", report3.app);
|
|
159347
|
+
row("key", report3.credentials);
|
|
159348
|
+
row("provider", report3.provider);
|
|
159349
|
+
for (const mapping of report3.mappings) row("mapping", mapping);
|
|
159350
|
+
if (report3.purchasesAppId) out2.line(` ${pad("binding")}wixIap: { purchasesAppId: "${report3.purchasesAppId}" }`);
|
|
159351
|
+
}
|
|
159352
|
+
function printConfig(out2, config, note) {
|
|
159353
|
+
if (note) out2.line(` ${pad("config")}${note}`);
|
|
159354
|
+
if (!config) return;
|
|
159355
|
+
out2.line(` ${pad("config")}${config.changed ? `recorded ${config.applied.join(", ")} in ${config.path}` : `${config.path} unchanged`}`);
|
|
159356
|
+
for (const line of [...config.conflicts, ...config.instructions]) out2.line(` ${pad("")}${line}`);
|
|
159357
|
+
}
|
|
159358
|
+
async function recordBinding(flags, deps, report3, apply) {
|
|
159359
|
+
const dir = textFlag(flags, "content");
|
|
159360
|
+
const wanted = report3.purchasesAppId ? `wixIap: { purchasesAppId: "${report3.purchasesAppId}" }` : void 0;
|
|
159361
|
+
if (!dir) return { note: wanted ? `add ${wanted} and "iap" in capabilities to the app's config (or rerun with --content <dir>)` : void 0 };
|
|
159362
|
+
if (!report3.purchasesAppId) return { note: `${dir} was not edited: there is no purchases app on the site yet`, unapplied: true };
|
|
159363
|
+
const options = { purchasesAppId: report3.purchasesAppId, siteId: report3.site, bundleId: report3.bundleId };
|
|
159364
|
+
const validate4 = deps.validateConfig;
|
|
159365
|
+
let config;
|
|
159366
|
+
if (!apply) config = previewIapConfigEdit(dir, options);
|
|
159367
|
+
else if (!validate4) return { note: `${dir} was not edited (himi validate is unavailable here): add ${wanted} by hand`, unapplied: true };
|
|
159368
|
+
else config = await applyIapConfigEdit(dir, options, validate4);
|
|
159369
|
+
if (!config) return { note: `${dir} has no config.ts, so it was not edited: add ${wanted} to the app's config`, unapplied: true };
|
|
159370
|
+
return { config, unapplied: config.instructions.length > 0 };
|
|
159371
|
+
}
|
|
159372
|
+
async function connectCommand(flags, deps, out2) {
|
|
159373
|
+
try {
|
|
159374
|
+
return await connectWith(flags, deps, out2);
|
|
159375
|
+
} catch (error) {
|
|
159376
|
+
if (error instanceof UsageError) return out2.fail(error.message, { ok: false, code: "invalid_usage", usage: STORE_IAP_USAGE });
|
|
159377
|
+
if (error instanceof IapManifestError) {
|
|
159378
|
+
return out2.fail(`${error.label} is not a valid IAP manifest`, { ok: false, code: "manifest_invalid", problems: error.problems });
|
|
159379
|
+
}
|
|
159380
|
+
if (error instanceof CredentialsError) return out2.fail(error.message, { ok: false, code: "credentials_unavailable" });
|
|
159381
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "connect_failed" });
|
|
159382
|
+
}
|
|
159383
|
+
}
|
|
159384
|
+
async function connectWith(flags, deps, out2) {
|
|
159385
|
+
const manifestPath = requireFlag(flags, "manifest", "connect");
|
|
159386
|
+
const profile = requireFlag(flags, "profile", "connect");
|
|
159387
|
+
const dryRun = flags["dry-run"] === true;
|
|
159388
|
+
let previewTag;
|
|
159389
|
+
try {
|
|
159390
|
+
previewTag = parsePreviewTag(textFlag(flags, "preview-tag") ?? process.env.HIMI_SERVE_PREVIEW_TAG);
|
|
159391
|
+
} catch (error) {
|
|
159392
|
+
throw new UsageError(error.message);
|
|
159393
|
+
}
|
|
159394
|
+
const manifest = readManifest2(deps, manifestPath);
|
|
159395
|
+
let creds;
|
|
159396
|
+
try {
|
|
159397
|
+
creds = deps.resolveCredentials({ profileFlag: profile, target: manifest.target });
|
|
159398
|
+
} catch (error) {
|
|
159399
|
+
throw new CredentialsError(error instanceof Error ? error.message : String(error));
|
|
159400
|
+
}
|
|
159401
|
+
out2.protect(creds);
|
|
159402
|
+
let appleKey;
|
|
159403
|
+
try {
|
|
159404
|
+
appleKey = readInAppPurchaseKey(flags, deps, creds);
|
|
159405
|
+
} catch (error) {
|
|
159406
|
+
if (error instanceof KeyError) return out2.fail(error.message, { ok: false, code: "iap_key_unreadable" });
|
|
159407
|
+
throw error;
|
|
159408
|
+
}
|
|
159409
|
+
if (appleKey) out2.protectKey(appleKey);
|
|
159410
|
+
const transport = deps.wixTransport(manifest.target.wixSiteId);
|
|
159411
|
+
const route = deps.wixIapRoute();
|
|
159412
|
+
const serve = route ? deps.serveTransport?.(manifest.target.wixSiteId, previewTag) ?? transport : transport;
|
|
159413
|
+
const connectDeps = { api: createPurchasesOwnerApi(transport), appleKey, provider: route ? wixIapProviderConnector(serve, route) : null };
|
|
159414
|
+
let plan;
|
|
159415
|
+
try {
|
|
159416
|
+
plan = await connectIap(manifest, connectDeps, { apply: false });
|
|
159417
|
+
} catch (error) {
|
|
159418
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "request_failed" });
|
|
159419
|
+
}
|
|
159420
|
+
let report3 = plan;
|
|
159421
|
+
if (!dryRun && writesPlanned(plan)) {
|
|
159422
|
+
const confirmed = flags.yes === true;
|
|
159423
|
+
if (!confirmed && !(out2.interactive && !out2.json && deps.canPrompt())) {
|
|
159424
|
+
return out2.fail(
|
|
159425
|
+
"refusing to change the Wix site's In-App Purchases setup without confirmation: there is no interactive terminal to ask (or --json was given). Review the dry run (--dry-run), then pass --yes.",
|
|
159426
|
+
{ ok: false, code: "confirmation_required", manifest: manifestPath }
|
|
159427
|
+
);
|
|
159428
|
+
}
|
|
159429
|
+
if (!out2.json) printConnect(out2, plan, "plan");
|
|
159430
|
+
if (!confirmed && !await deps.confirm(`Apply this In-App Purchases setup to Wix site ${manifest.target.wixSiteId}?`)) {
|
|
159431
|
+
out2.line(" aborted \u2014 nothing was changed on the Wix site.");
|
|
159432
|
+
return 1;
|
|
159433
|
+
}
|
|
159434
|
+
try {
|
|
159435
|
+
report3 = await connectIap(manifest, connectDeps, { apply: true });
|
|
159436
|
+
} catch (error) {
|
|
159437
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "request_failed" });
|
|
159438
|
+
}
|
|
159439
|
+
}
|
|
159440
|
+
const { config, note, unapplied } = await recordBinding(flags, deps, report3, !dryRun);
|
|
159441
|
+
const outPath = textFlag(flags, "out");
|
|
159442
|
+
if (outPath) writeJson(deps, out2, outPath, { report: report3, config });
|
|
159443
|
+
const configProblem = config?.conflicts.length ? "config_conflict" : unapplied ? "config_not_applied" : void 0;
|
|
159444
|
+
const code = firstProblem(report3) ?? configProblem;
|
|
159445
|
+
if (out2.json) out2.print({ ok: !code, ...code ? { code } : {}, dryRun, report: report3, config, ...note ? { note } : {} });
|
|
159446
|
+
else {
|
|
159447
|
+
printConnect(out2, report3, dryRun ? "dry run (nothing was written)" : "result");
|
|
159448
|
+
printConfig(out2, config, note);
|
|
159449
|
+
}
|
|
159450
|
+
return code ? 1 : 0;
|
|
159451
|
+
}
|
|
158689
159452
|
async function runStoreIap(pos, flags, io2, deps) {
|
|
158690
159453
|
const out2 = new CommandOutput(io2, flags.json === true);
|
|
158691
159454
|
const sub = pos[2];
|
|
@@ -158706,17 +159469,17 @@ function fileJournal(path2) {
|
|
|
158706
159469
|
}
|
|
158707
159470
|
function readLockSummary(path2) {
|
|
158708
159471
|
try {
|
|
158709
|
-
const { pid, host, at: at2 } = JSON.parse(
|
|
159472
|
+
const { pid, host, at: at2 } = JSON.parse(readFileSync87(path2, "utf8"));
|
|
158710
159473
|
return `pid ${pid} on ${host} since ${at2}`;
|
|
158711
159474
|
} catch {
|
|
158712
159475
|
return "unreadable lock";
|
|
158713
159476
|
}
|
|
158714
159477
|
}
|
|
158715
159478
|
function acquireApplyLock(dir, appleAppId) {
|
|
158716
|
-
const path2 =
|
|
159479
|
+
const path2 = join73(dir, "apply.lock");
|
|
158717
159480
|
const stamp = JSON.stringify({ pid: process.pid, host: hostname(), at: (/* @__PURE__ */ new Date()).toISOString(), token: randomUUID8() });
|
|
158718
159481
|
try {
|
|
158719
|
-
|
|
159482
|
+
writeFileSync30(path2, stamp, { flag: "wx", mode: 384 });
|
|
158720
159483
|
} catch (e2) {
|
|
158721
159484
|
if (e2.code !== "EEXIST") throw e2;
|
|
158722
159485
|
throw new Error(
|
|
@@ -158726,7 +159489,7 @@ function acquireApplyLock(dir, appleAppId) {
|
|
|
158726
159489
|
return () => {
|
|
158727
159490
|
let current = "";
|
|
158728
159491
|
try {
|
|
158729
|
-
current =
|
|
159492
|
+
current = readFileSync87(path2, "utf8");
|
|
158730
159493
|
} catch {
|
|
158731
159494
|
return;
|
|
158732
159495
|
}
|
|
@@ -158734,7 +159497,7 @@ function acquireApplyLock(dir, appleAppId) {
|
|
|
158734
159497
|
};
|
|
158735
159498
|
}
|
|
158736
159499
|
function stateDir(appleAppId) {
|
|
158737
|
-
const dir =
|
|
159500
|
+
const dir = join73(homedir8(), ".himalaya", "store-iap", appleAppId);
|
|
158738
159501
|
mkdirSync34(dir, { recursive: true, mode: 448 });
|
|
158739
159502
|
return dir;
|
|
158740
159503
|
}
|
|
@@ -158750,21 +159513,25 @@ async function confirmOnTerminal(question) {
|
|
|
158750
159513
|
}
|
|
158751
159514
|
function defaultStoreIapDeps() {
|
|
158752
159515
|
return {
|
|
158753
|
-
readFile: (path2) =>
|
|
159516
|
+
readFile: (path2) => readFileSync87(path2, "utf8"),
|
|
158754
159517
|
writeFileAtomic,
|
|
158755
159518
|
resolveCredentials: ({ profileFlag, target }) => resolveIapCredentials({ profileFlag, target }),
|
|
158756
159519
|
createApi: (key2) => createIapApi(createAscClient({ key: key2 })),
|
|
158757
|
-
openJournal: (appleAppId) => fileJournal(
|
|
159520
|
+
openJournal: (appleAppId) => fileJournal(join73(stateDir(appleAppId), "journal.jsonl")),
|
|
158758
159521
|
acquireLock: (appleAppId) => acquireApplyLock(stateDir(appleAppId), appleAppId),
|
|
158759
159522
|
canPrompt: () => process.stdin.isTTY === true,
|
|
158760
159523
|
wixTransport: (siteId) => ownerTransport(siteId),
|
|
159524
|
+
// Serve's owner-only ConnectProviderAccount route; Serve answers 404 while its IAP routes are off.
|
|
159525
|
+
wixIapRoute: () => HIMALAYA_SERVE_IAP_ROUTE,
|
|
159526
|
+
// Serve's provider route requires a Wix user, so never the API key the purchases calls may use.
|
|
159527
|
+
serveTransport: (siteId, previewTag) => ownerTransport(siteId, servePreviewFetch(fetch, previewTag), void 0, userSiteToken),
|
|
158761
159528
|
profileTeam: (profile) => resolveStoreCredentials({ app: profile, cfg: {}, profileFlag: profile, env: {} }).team,
|
|
158762
159529
|
confirm: confirmOnTerminal,
|
|
158763
159530
|
now: () => /* @__PURE__ */ new Date(),
|
|
158764
159531
|
sleep: (ms2) => new Promise((resolve61) => setTimeout(resolve61, ms2))
|
|
158765
159532
|
};
|
|
158766
159533
|
}
|
|
158767
|
-
var STORE_IAP_USAGE, SUMMARY_THRESHOLD, SUMMARY_DETAIL_LIMIT, UsageError, CommandOutput, pad, DECISION_ORDER, OUTCOME_ORDER, COMPLETE, DRAFT_MODES, TERRITORY_CODE, LOCALE_CODE, GRID_UNAVAILABLE_NOTE, COMMANDS;
|
|
159534
|
+
var STORE_IAP_USAGE, SUMMARY_THRESHOLD, SUMMARY_DETAIL_LIMIT, UsageError, CommandOutput, pad, DECISION_ORDER, OUTCOME_ORDER, COMPLETE, DRAFT_MODES, TERRITORY_CODE, LOCALE_CODE, GRID_UNAVAILABLE_NOTE, KeyError, CredentialsError, writesPlanned, COMMANDS;
|
|
158768
159535
|
var init_store_iap = __esm({
|
|
158769
159536
|
"src/store-iap.ts"() {
|
|
158770
159537
|
init_iap_api();
|
|
@@ -158772,15 +159539,21 @@ var init_store_iap = __esm({
|
|
|
158772
159539
|
init_iap_client();
|
|
158773
159540
|
init_credential_profile();
|
|
158774
159541
|
init_iap_credentials();
|
|
159542
|
+
init_preflight();
|
|
159543
|
+
init_wix_payments_contract();
|
|
158775
159544
|
init_iap_draft();
|
|
158776
159545
|
init_iap_manifest();
|
|
158777
159546
|
init_iap_pricing();
|
|
158778
159547
|
init_iap_plan();
|
|
158779
159548
|
init_redact();
|
|
158780
159549
|
init_progress();
|
|
159550
|
+
init_iap_config_edit();
|
|
158781
159551
|
init_store_iap_catalog();
|
|
159552
|
+
init_store_iap_connect();
|
|
159553
|
+
init_store_iap_purchases();
|
|
159554
|
+
init_serve_preview();
|
|
158782
159555
|
init_wix_owner();
|
|
158783
|
-
STORE_IAP_USAGE = "himi store iap draft|plan|apply|status \u2014 draft --site <msid> --profile <name> --apple-app <id> --bundle <id> --base-territory <ISO3> --out <manifest.json> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <manifest.json>] [--report <file>] \xB7 plan --manifest <file> --profile <name> --out <plan.json> \xB7 apply --plan <plan.json> --profile <name> --out <result.json> [--yes] [--limit <n>] \xB7 status --manifest <file> --profile <name> [--out <file>]";
|
|
159556
|
+
STORE_IAP_USAGE = "himi store iap draft|plan|apply|status|connect \u2014 draft --site <msid> --profile <name> --apple-app <id> --bundle <id> --base-territory <ISO3> --out <manifest.json> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <manifest.json>] [--report <file>] \xB7 plan --manifest <file> --profile <name> --out <plan.json> \xB7 apply --plan <plan.json> --profile <name> --out <result.json> [--yes] [--limit <n>] \xB7 status --manifest <file> --profile <name> [--out <file>] \xB7 connect --manifest <file> --profile <name> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <report.json>]";
|
|
158784
159557
|
SUMMARY_THRESHOLD = 50;
|
|
158785
159558
|
SUMMARY_DETAIL_LIMIT = 20;
|
|
158786
159559
|
UsageError = class extends Error {
|
|
@@ -158797,6 +159570,9 @@ var init_store_iap = __esm({
|
|
|
158797
159570
|
protect(creds) {
|
|
158798
159571
|
this.secrets.push(creds.key.privateKeyPem, creds.key.issuerId, creds.key.keyId);
|
|
158799
159572
|
}
|
|
159573
|
+
protectKey(key2) {
|
|
159574
|
+
this.secrets.push(key2.privateKey, key2.keyId);
|
|
159575
|
+
}
|
|
158800
159576
|
line(text9 = "") {
|
|
158801
159577
|
this.io.log(this.scrub(text9));
|
|
158802
159578
|
}
|
|
@@ -158828,11 +159604,17 @@ var init_store_iap = __esm({
|
|
|
158828
159604
|
TERRITORY_CODE = /^[A-Z]{3}$/;
|
|
158829
159605
|
LOCALE_CODE = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
158830
159606
|
GRID_UNAVAILABLE_NOTE = "the app has no in-app purchase yet to read Apple's price grid through, so tiers are keyed by Wix price \u2014 prices that resolve to the same Apple point get separate tiers; redraft after the first product exists to merge them";
|
|
159607
|
+
KeyError = class extends Error {
|
|
159608
|
+
};
|
|
159609
|
+
CredentialsError = class extends Error {
|
|
159610
|
+
};
|
|
159611
|
+
writesPlanned = (report3) => [report3.app, report3.credentials, report3.provider, ...report3.mappings].some((step) => step.state === "planned");
|
|
158831
159612
|
COMMANDS = {
|
|
158832
159613
|
draft: draftCommand,
|
|
158833
159614
|
plan: planCommand,
|
|
158834
159615
|
apply: applyCommand,
|
|
158835
|
-
status: statusCommand
|
|
159616
|
+
status: statusCommand,
|
|
159617
|
+
connect: connectCommand
|
|
158836
159618
|
};
|
|
158837
159619
|
}
|
|
158838
159620
|
});
|
|
@@ -159213,9 +159995,9 @@ __export(preflight_app_exports, {
|
|
|
159213
159995
|
preflightApp: () => preflightApp,
|
|
159214
159996
|
profileAccount: () => profileAccount
|
|
159215
159997
|
});
|
|
159216
|
-
import { readFileSync as
|
|
159998
|
+
import { readFileSync as readFileSync88, existsSync as existsSync74, readdirSync as readdirSync33, statSync as statSync19 } from "node:fs";
|
|
159217
159999
|
import { createHash as createHash39 } from "node:crypto";
|
|
159218
|
-
import { join as
|
|
160000
|
+
import { join as join74 } from "node:path";
|
|
159219
160001
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
159220
160002
|
const f2 = [];
|
|
159221
160003
|
const has = (re2, s2) => re2.test(s2);
|
|
@@ -159279,13 +160061,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
159279
160061
|
}
|
|
159280
160062
|
}
|
|
159281
160063
|
async function preflightApp(app, opts = {}) {
|
|
159282
|
-
const projectYml =
|
|
159283
|
-
const storeConfig =
|
|
160064
|
+
const projectYml = existsSync74(iosProjectYml(app)) ? readFileSync88(iosProjectYml(app), "utf8") : "";
|
|
160065
|
+
const storeConfig = existsSync74(storeConfigPath(app)) ? readFileSync88(storeConfigPath(app), "utf8") : "";
|
|
159284
160066
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
159285
160067
|
const findings = analyze(
|
|
159286
160068
|
projectYml,
|
|
159287
160069
|
storeConfig,
|
|
159288
|
-
await appIconState(
|
|
160070
|
+
await appIconState(join74(appDir(app), "ios")),
|
|
159289
160071
|
profileAccount(app, storeConfig, opts)
|
|
159290
160072
|
);
|
|
159291
160073
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -159314,17 +160096,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
159314
160096
|
return f2;
|
|
159315
160097
|
}
|
|
159316
160098
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
159317
|
-
const root =
|
|
160099
|
+
const root = join74(storeDir(app), "metadata");
|
|
159318
160100
|
const out2 = /* @__PURE__ */ new Set();
|
|
159319
|
-
if (
|
|
160101
|
+
if (existsSync74(root)) {
|
|
159320
160102
|
for (const n2 of readdirSync33(root)) if (n2.endsWith(".txt")) out2.add(n2);
|
|
159321
160103
|
}
|
|
159322
|
-
if (
|
|
160104
|
+
if (existsSync74(join74(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
|
|
159323
160105
|
return out2;
|
|
159324
160106
|
}
|
|
159325
160107
|
function reviewInfoFiles(app) {
|
|
159326
|
-
const dir =
|
|
159327
|
-
if (!
|
|
160108
|
+
const dir = join74(storeDir(app), "review_information");
|
|
160109
|
+
if (!existsSync74(dir)) return /* @__PURE__ */ new Set();
|
|
159328
160110
|
return new Set(readdirSync33(dir).filter((n2) => n2.endsWith(".txt")));
|
|
159329
160111
|
}
|
|
159330
160112
|
function isValidAppStoreSize(w2, h2) {
|
|
@@ -159434,12 +160216,12 @@ function analyzePlayListing(assets) {
|
|
|
159434
160216
|
return f2;
|
|
159435
160217
|
}
|
|
159436
160218
|
function playListingAssets(app, locale = "en-US") {
|
|
159437
|
-
const dir =
|
|
160219
|
+
const dir = join74(storeDir(app), "play", locale, "images");
|
|
159438
160220
|
const read = (names) => {
|
|
159439
160221
|
for (const name of names) {
|
|
159440
|
-
const p2 =
|
|
160222
|
+
const p2 = join74(dir, name);
|
|
159441
160223
|
try {
|
|
159442
|
-
if (statSync19(p2).isFile()) return { name, bytes:
|
|
160224
|
+
if (statSync19(p2).isFile()) return { name, bytes: readFileSync88(p2) };
|
|
159443
160225
|
} catch {
|
|
159444
160226
|
}
|
|
159445
160227
|
}
|
|
@@ -159470,26 +160252,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
159470
160252
|
return f2;
|
|
159471
160253
|
}
|
|
159472
160254
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
159473
|
-
const dir =
|
|
159474
|
-
if (!
|
|
160255
|
+
const dir = join74(storeDir(app), "metadata", locale);
|
|
160256
|
+
if (!existsSync74(dir)) return /* @__PURE__ */ new Set();
|
|
159475
160257
|
return new Set(readdirSync33(dir).filter((n2) => n2.endsWith(".txt")));
|
|
159476
160258
|
}
|
|
159477
160259
|
function listScreenshots(app, locale = "en-US") {
|
|
159478
160260
|
const out2 = [];
|
|
159479
|
-
const flat =
|
|
159480
|
-
if (
|
|
160261
|
+
const flat = join74(storeDir(app), "screenshots", locale);
|
|
160262
|
+
if (existsSync74(flat)) {
|
|
159481
160263
|
for (const png of readdirSync33(flat).filter((n2) => n2.endsWith(".png"))) {
|
|
159482
|
-
const sz = pngSize(
|
|
160264
|
+
const sz = pngSize(readFileSync88(join74(flat, png)));
|
|
159483
160265
|
if (sz) out2.push({ name: png, w: sz.w, h: sz.h });
|
|
159484
160266
|
}
|
|
159485
160267
|
}
|
|
159486
|
-
const legacy =
|
|
159487
|
-
if (
|
|
160268
|
+
const legacy = join74(storeDir(app), "metadata", locale, "screenshots");
|
|
160269
|
+
if (existsSync74(legacy)) {
|
|
159488
160270
|
for (const deviceDir of readdirSync33(legacy)) {
|
|
159489
|
-
const d2 =
|
|
160271
|
+
const d2 = join74(legacy, deviceDir);
|
|
159490
160272
|
if (!statSync19(d2).isDirectory()) continue;
|
|
159491
160273
|
for (const png of readdirSync33(d2).filter((n2) => n2.endsWith(".png"))) {
|
|
159492
|
-
const sz = pngSize(
|
|
160274
|
+
const sz = pngSize(readFileSync88(join74(d2, png)));
|
|
159493
160275
|
if (sz) out2.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
159494
160276
|
}
|
|
159495
160277
|
}
|
|
@@ -159497,13 +160279,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
159497
160279
|
return out2;
|
|
159498
160280
|
}
|
|
159499
160281
|
function placeholderHashes2() {
|
|
159500
|
-
const templateIos =
|
|
159501
|
-
if (!
|
|
160282
|
+
const templateIos = join74(appDir("_template"), "ios");
|
|
160283
|
+
if (!existsSync74(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
159502
160284
|
for (const target of readdirSync33(templateIos)) {
|
|
159503
|
-
const p2 =
|
|
160285
|
+
const p2 = join74(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
159504
160286
|
try {
|
|
159505
160287
|
if (!statSync19(p2).isFile()) continue;
|
|
159506
|
-
return [LEGACY_PLACEHOLDER_SHA2562, createHash39("sha256").update(
|
|
160288
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash39("sha256").update(readFileSync88(p2)).digest("hex")];
|
|
159507
160289
|
} catch {
|
|
159508
160290
|
}
|
|
159509
160291
|
}
|
|
@@ -159534,12 +160316,12 @@ async function pixelIssues(bytes2) {
|
|
|
159534
160316
|
}
|
|
159535
160317
|
}
|
|
159536
160318
|
async function appIconState(iosDir) {
|
|
159537
|
-
if (!
|
|
160319
|
+
if (!existsSync74(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
159538
160320
|
for (const target of readdirSync33(iosDir)) {
|
|
159539
|
-
const p2 =
|
|
160321
|
+
const p2 = join74(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
159540
160322
|
try {
|
|
159541
160323
|
if (!statSync19(p2).isFile()) continue;
|
|
159542
|
-
const bytes2 =
|
|
160324
|
+
const bytes2 = readFileSync88(p2);
|
|
159543
160325
|
const hash2 = createHash39("sha256").update(bytes2).digest("hex");
|
|
159544
160326
|
const pixels = await pixelIssues(bytes2);
|
|
159545
160327
|
return {
|
|
@@ -159600,195 +160382,13 @@ var init_preflight_app = __esm({
|
|
|
159600
160382
|
}
|
|
159601
160383
|
});
|
|
159602
160384
|
|
|
159603
|
-
// ../store-release/version.ts
|
|
159604
|
-
var version_exports = {};
|
|
159605
|
-
__export(version_exports, {
|
|
159606
|
-
bumpVersion: () => bumpVersion,
|
|
159607
|
-
readAndroidVersion: () => readAndroidVersion,
|
|
159608
|
-
readAndroidVersionName: () => readAndroidVersionName,
|
|
159609
|
-
readIosMarketingVersion: () => readIosMarketingVersion,
|
|
159610
|
-
readIosVersion: () => readIosVersion,
|
|
159611
|
-
readIosVersionStrings: () => readIosVersionStrings,
|
|
159612
|
-
readIosVersionStringsOrNull: () => readIosVersionStringsOrNull,
|
|
159613
|
-
readTargetVersionKeys: () => readTargetVersionKeys,
|
|
159614
|
-
readTargetVersionStrings: () => readTargetVersionStrings,
|
|
159615
|
-
setAndroidVersion: () => setAndroidVersion,
|
|
159616
|
-
setIosVersion: () => setIosVersion,
|
|
159617
|
-
stampIosVersionStrings: () => stampIosVersionStrings,
|
|
159618
|
-
stampTargetVersion: () => stampTargetVersion,
|
|
159619
|
-
stampVersionKeys: () => stampVersionKeys
|
|
159620
|
-
});
|
|
159621
|
-
import { readFileSync as readFileSync87, writeFileSync as writeFileSync30 } from "node:fs";
|
|
159622
|
-
function readIosVersion(projectYml) {
|
|
159623
|
-
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159624
|
-
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
159625
|
-
if (marketing === null || build3 === null) {
|
|
159626
|
-
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
159627
|
-
}
|
|
159628
|
-
return { marketing, build: Number(build3) };
|
|
159629
|
-
}
|
|
159630
|
-
function setIosVersion(projectYml, v2) {
|
|
159631
|
-
let out2 = replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing);
|
|
159632
|
-
out2 = replaceScalar(out2, "CFBundleVersion", String(v2.build));
|
|
159633
|
-
out2 = out2.replace(
|
|
159634
|
-
/(^[ \t]*# >>> himalaya:live-activity:target[^\n]*\n)([\s\S]*?)(^[ \t]*# <<< himalaya:live-activity:target[^\n]*$)/m,
|
|
159635
|
-
(_match, start, body, end) => {
|
|
159636
|
-
if (!body.trim()) return start + body + end;
|
|
159637
|
-
return start + replaceScalar(replaceScalar(body, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", String(v2.build)) + end;
|
|
159638
|
-
}
|
|
159639
|
-
);
|
|
159640
|
-
return out2;
|
|
159641
|
-
}
|
|
159642
|
-
function readIosVersionStrings(projectYml) {
|
|
159643
|
-
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159644
|
-
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
159645
|
-
if (marketing === null || build3 === null) {
|
|
159646
|
-
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
159647
|
-
}
|
|
159648
|
-
return { marketing, build: build3 };
|
|
159649
|
-
}
|
|
159650
|
-
function readIosVersionStringsOrNull(projectYml) {
|
|
159651
|
-
try {
|
|
159652
|
-
return readIosVersionStrings(projectYml);
|
|
159653
|
-
} catch {
|
|
159654
|
-
return null;
|
|
159655
|
-
}
|
|
159656
|
-
}
|
|
159657
|
-
function stampIosVersionStrings(projectYml, v2) {
|
|
159658
|
-
return replaceScalar(replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", v2.build);
|
|
159659
|
-
}
|
|
159660
|
-
function stampVersionKeys(projectYml, v2) {
|
|
159661
|
-
let out2 = projectYml;
|
|
159662
|
-
if (v2.marketing !== void 0) out2 = replaceScalar(out2, "CFBundleShortVersionString", v2.marketing);
|
|
159663
|
-
if (v2.build !== void 0) out2 = replaceScalar(out2, "CFBundleVersion", v2.build);
|
|
159664
|
-
return out2;
|
|
159665
|
-
}
|
|
159666
|
-
function targetBlock(lines, target) {
|
|
159667
|
-
const head = new RegExp(`^ {2}${target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*$`);
|
|
159668
|
-
const start = lines.findIndex((l2) => head.test(l2));
|
|
159669
|
-
if (start < 0) return null;
|
|
159670
|
-
let end = start + 1;
|
|
159671
|
-
while (end < lines.length && !/^ {0,2}\S/.test(lines[end])) end++;
|
|
159672
|
-
return { start, end };
|
|
159673
|
-
}
|
|
159674
|
-
function readTargetVersionStrings(projectYml, target) {
|
|
159675
|
-
const lines = projectYml.split("\n");
|
|
159676
|
-
const block = targetBlock(lines, target);
|
|
159677
|
-
if (!block) return null;
|
|
159678
|
-
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
159679
|
-
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
159680
|
-
const build3 = matchScalar(body, "CFBundleVersion");
|
|
159681
|
-
return marketing !== null && build3 !== null ? { marketing, build: build3 } : null;
|
|
159682
|
-
}
|
|
159683
|
-
function readTargetVersionKeys(projectYml, target) {
|
|
159684
|
-
const lines = projectYml.split("\n");
|
|
159685
|
-
const block = targetBlock(lines, target);
|
|
159686
|
-
if (!block) return null;
|
|
159687
|
-
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
159688
|
-
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
159689
|
-
const build3 = matchScalar(body, "CFBundleVersion");
|
|
159690
|
-
if (marketing === null && build3 === null) return null;
|
|
159691
|
-
return { ...marketing !== null ? { marketing } : {}, ...build3 !== null ? { build: build3 } : {} };
|
|
159692
|
-
}
|
|
159693
|
-
function stampTargetVersion(yml, target, v2) {
|
|
159694
|
-
const lines = yml.split("\n");
|
|
159695
|
-
const block = targetBlock(lines, target);
|
|
159696
|
-
if (!block) return yml;
|
|
159697
|
-
for (let i2 = block.start + 1; i2 < block.end; i2++) {
|
|
159698
|
-
const inline = /^ {4}info:\s*\{\s*path:\s*([^\s,}]+)\s*\}\s*(#.*)?$/.exec(lines[i2]);
|
|
159699
|
-
if (inline) {
|
|
159700
|
-
lines.splice(i2, 1, " info:", ` path: ${inline[1]}`);
|
|
159701
|
-
block.end++;
|
|
159702
|
-
break;
|
|
159703
|
-
}
|
|
159704
|
-
}
|
|
159705
|
-
const { start, end } = block;
|
|
159706
|
-
const want = {};
|
|
159707
|
-
if (v2.marketing !== void 0) want.CFBundleShortVersionString = v2.marketing;
|
|
159708
|
-
if (v2.build !== void 0) want.CFBundleVersion = v2.build;
|
|
159709
|
-
const seen = /* @__PURE__ */ new Set();
|
|
159710
|
-
let infoAt = -1;
|
|
159711
|
-
let propsAt = -1;
|
|
159712
|
-
for (let i2 = start + 1; i2 < end; i2++) {
|
|
159713
|
-
if (/^ {4}info:\s*$/.test(lines[i2])) infoAt = i2;
|
|
159714
|
-
if (infoAt >= 0 && /^ {6}properties:\s*$/.test(lines[i2]) && lines.slice(infoAt + 1, i2).every((l2) => !/^ {4}\S/.test(l2))) propsAt = i2;
|
|
159715
|
-
const m2 = /^(\s+)(CFBundleShortVersionString|CFBundleVersion):\s*.*$/.exec(lines[i2]);
|
|
159716
|
-
if (m2 && m2[2] in want) {
|
|
159717
|
-
lines[i2] = `${m2[1]}${m2[2]}: "${want[m2[2]]}"`;
|
|
159718
|
-
seen.add(m2[2]);
|
|
159719
|
-
}
|
|
159720
|
-
}
|
|
159721
|
-
const missing = Object.keys(want).filter((k2) => !seen.has(k2)).map((k2) => ` ${k2}: "${want[k2]}"`);
|
|
159722
|
-
if (missing.length && propsAt >= 0) {
|
|
159723
|
-
lines.splice(propsAt + 1, 0, ...missing);
|
|
159724
|
-
} else if (missing.length && infoAt >= 0) {
|
|
159725
|
-
let after = infoAt + 1;
|
|
159726
|
-
while (after < end && /^ {6}\S/.test(lines[after])) after++;
|
|
159727
|
-
lines.splice(after, 0, " properties:", ...missing);
|
|
159728
|
-
}
|
|
159729
|
-
return lines.join("\n");
|
|
159730
|
-
}
|
|
159731
|
-
function readIosMarketingVersion(projectYml) {
|
|
159732
|
-
return matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159733
|
-
}
|
|
159734
|
-
function scalarRe(key2) {
|
|
159735
|
-
return new RegExp(`^(\\s*${key2}:\\s*)("?)([^"\\n#]*?)("?)(\\s*(?:#.*)?)$`, "m");
|
|
159736
|
-
}
|
|
159737
|
-
function matchScalar(content, key2) {
|
|
159738
|
-
const m2 = scalarRe(key2).exec(content);
|
|
159739
|
-
return m2 ? m2[3].trim() : null;
|
|
159740
|
-
}
|
|
159741
|
-
function replaceScalar(content, key2, value) {
|
|
159742
|
-
const re2 = scalarRe(key2);
|
|
159743
|
-
if (!re2.test(content)) throw new Error(`could not locate \`${key2}:\` in project.yml`);
|
|
159744
|
-
return content.replace(re2, (_full, pre, openQ, _oldVal, _closeQ, tail) => {
|
|
159745
|
-
const q2 = openQ ? '"' : "";
|
|
159746
|
-
return `${pre}${q2}${value}${q2}${tail}`;
|
|
159747
|
-
});
|
|
159748
|
-
}
|
|
159749
|
-
function readAndroidVersion(gradle) {
|
|
159750
|
-
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
159751
|
-
const code = /(\bversionCode\s*=\s*)(\d+)/.exec(gradle);
|
|
159752
|
-
if (!name || !code) throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
159753
|
-
return { marketing: name[2], build: Number(code[2]) };
|
|
159754
|
-
}
|
|
159755
|
-
function readAndroidVersionName(gradle) {
|
|
159756
|
-
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
159757
|
-
return name ? name[2] : null;
|
|
159758
|
-
}
|
|
159759
|
-
function setAndroidVersion(gradle, v2) {
|
|
159760
|
-
if (!/\bversionName\s*=\s*"/.test(gradle) || !/\bversionCode\s*=\s*\d+/.test(gradle)) {
|
|
159761
|
-
throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
159762
|
-
}
|
|
159763
|
-
return gradle.replace(/(\bversionName\s*=\s*")[^"]*(")/, `$1${v2.marketing}$2`).replace(/(\bversionCode\s*=\s*)\d+/, `$1${v2.build}`);
|
|
159764
|
-
}
|
|
159765
|
-
function bumpVersion(app, opts) {
|
|
159766
|
-
const iosPath = iosProjectYml(app);
|
|
159767
|
-
const gradlePath = androidGradle(app);
|
|
159768
|
-
const iosYml = readFileSync87(iosPath, "utf8");
|
|
159769
|
-
const gradle = readFileSync87(gradlePath, "utf8");
|
|
159770
|
-
const current = readIosVersion(iosYml);
|
|
159771
|
-
const next = {
|
|
159772
|
-
marketing: opts.marketing ?? current.marketing,
|
|
159773
|
-
build: opts.build === "increment" || opts.build === void 0 ? current.build + (opts.build === "increment" ? 1 : 0) : opts.build
|
|
159774
|
-
};
|
|
159775
|
-
writeFileSync30(iosPath, setIosVersion(iosYml, next));
|
|
159776
|
-
writeFileSync30(gradlePath, setAndroidVersion(gradle, next));
|
|
159777
|
-
return next;
|
|
159778
|
-
}
|
|
159779
|
-
var init_version = __esm({
|
|
159780
|
-
"../store-release/version.ts"() {
|
|
159781
|
-
init_paths2();
|
|
159782
|
-
}
|
|
159783
|
-
});
|
|
159784
|
-
|
|
159785
160385
|
// ../store-release/asc-status.ts
|
|
159786
160386
|
var asc_status_exports = {};
|
|
159787
160387
|
__export(asc_status_exports, {
|
|
159788
160388
|
ascStatus: () => ascStatus,
|
|
159789
160389
|
buildVerdict: () => buildVerdict
|
|
159790
160390
|
});
|
|
159791
|
-
import { readFileSync as
|
|
160391
|
+
import { readFileSync as readFileSync89 } from "node:fs";
|
|
159792
160392
|
function buildVerdict(builds) {
|
|
159793
160393
|
if (!builds.length) {
|
|
159794
160394
|
return "NO builds registered \u2014 if you uploaded recently and it's been >15 min, the binary was REJECTED IN PROCESSING (reason is email-only; run validate-binary.ts / scan-purpose-strings.ts to reproduce it).";
|
|
@@ -159802,7 +160402,7 @@ function buildVerdict(builds) {
|
|
|
159802
160402
|
function client(creds) {
|
|
159803
160403
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
159804
160404
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
159805
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
160405
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync89(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
159806
160406
|
return async (path2) => {
|
|
159807
160407
|
const r2 = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
159808
160408
|
return { status: r2.status, json: await r2.json().catch(() => ({})) };
|
|
@@ -159962,7 +160562,7 @@ __export(secrets_exports, {
|
|
|
159962
160562
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
159963
160563
|
runSecretsCommand: () => runSecretsCommand
|
|
159964
160564
|
});
|
|
159965
|
-
import { readFileSync as
|
|
160565
|
+
import { readFileSync as readFileSync90 } from "node:fs";
|
|
159966
160566
|
function environment(value) {
|
|
159967
160567
|
if (value === "preview" || value === "production") return value;
|
|
159968
160568
|
throw new Error("--environment must be preview or production");
|
|
@@ -159993,7 +160593,7 @@ async function runSecretsCommand(operation, flags, io2, options = {}) {
|
|
|
159993
160593
|
io2.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
159994
160594
|
return 0;
|
|
159995
160595
|
}
|
|
159996
|
-
const value = options.readValue ? options.readValue() :
|
|
160596
|
+
const value = options.readValue ? options.readValue() : readFileSync90(0, "utf8").replace(/\r?\n$/, "");
|
|
159997
160597
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
159998
160598
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
159999
160599
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -160022,7 +160622,7 @@ async function runRemoteSecretsCommand(operation, flags, io2, options) {
|
|
|
160022
160622
|
}
|
|
160023
160623
|
let body;
|
|
160024
160624
|
if (operation !== "list") {
|
|
160025
|
-
const value = options.readValue ? options.readValue() :
|
|
160625
|
+
const value = options.readValue ? options.readValue() : readFileSync90(0, "utf8").replace(/\r?\n$/, "");
|
|
160026
160626
|
body = JSON.stringify({ value });
|
|
160027
160627
|
}
|
|
160028
160628
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -160406,7 +161006,7 @@ async function runAllMembers(args) {
|
|
|
160406
161006
|
if (flags["dry-run"] === true) {
|
|
160407
161007
|
if (recipients.length) {
|
|
160408
161008
|
const result = await send2(recipients[0], requestId2, true);
|
|
160409
|
-
const code =
|
|
161009
|
+
const code = refusalCode2(result);
|
|
160410
161010
|
if (code) return refuse6(io2, code, HINTS[code], 1);
|
|
160411
161011
|
}
|
|
160412
161012
|
io2.log(JSON.stringify({ ok: true, state: "dry_run", campaignId: requestId2, recipients: recipients.length, sent: false }));
|
|
@@ -160425,7 +161025,7 @@ async function runAllMembers(args) {
|
|
|
160425
161025
|
},
|
|
160426
161026
|
send: async (recipient, memberRequestId) => {
|
|
160427
161027
|
const response = await send2(recipient, memberRequestId);
|
|
160428
|
-
const code =
|
|
161028
|
+
const code = refusalCode2(response);
|
|
160429
161029
|
if (code === "rate_limited" && response.retryAfterSec) return { state: "rate_limited", retryAfterSec: response.retryAfterSec };
|
|
160430
161030
|
if (code) return { state: "failed", code };
|
|
160431
161031
|
return { state: "accepted", deduplicated: response.body?.deduplicated === true };
|
|
@@ -160449,7 +161049,7 @@ function flagRefusal(flags) {
|
|
|
160449
161049
|
return void 0;
|
|
160450
161050
|
}
|
|
160451
161051
|
function report2(http, sent, flags, io2) {
|
|
160452
|
-
const code =
|
|
161052
|
+
const code = refusalCode2(http);
|
|
160453
161053
|
if (code === "send_outcome_unknown") {
|
|
160454
161054
|
return refuse6(io2, code, `Ping may have accepted it. Re-run the same command with --request-id ${sent.requestId}: Ping runs one request at most once per site for 24 hours.`, 1, { requestId: sent.requestId });
|
|
160455
161055
|
}
|
|
@@ -160461,7 +161061,7 @@ function report2(http, sent, flags, io2) {
|
|
|
160461
161061
|
else io2.log(summary(http.body ?? {}, sent));
|
|
160462
161062
|
return 0;
|
|
160463
161063
|
}
|
|
160464
|
-
function
|
|
161064
|
+
function refusalCode2(http) {
|
|
160465
161065
|
if (http.error) return http.error === "push_send_unreachable" ? "send_outcome_unknown" : http.error;
|
|
160466
161066
|
if (http.ok && (http.body?.state === "accepted" || http.body?.state === "dry_run")) return void 0;
|
|
160467
161067
|
const code = String(http.body?.error ?? "");
|
|
@@ -160520,15 +161120,15 @@ __export(notify_exports, {
|
|
|
160520
161120
|
runNotify: () => runNotify,
|
|
160521
161121
|
saveAdminSession: () => saveAdminSession
|
|
160522
161122
|
});
|
|
160523
|
-
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as
|
|
161123
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as readFileSync91, writeFileSync as writeFileSync31 } from "node:fs";
|
|
160524
161124
|
import { homedir as homedir9 } from "node:os";
|
|
160525
|
-
import { dirname as dirname39, join as
|
|
161125
|
+
import { dirname as dirname39, join as join75 } from "node:path";
|
|
160526
161126
|
function defaultSessionsPath() {
|
|
160527
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
161127
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join75(homedir9(), ".himalaya", "admin-sessions.json");
|
|
160528
161128
|
}
|
|
160529
161129
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
160530
161130
|
try {
|
|
160531
|
-
return JSON.parse(
|
|
161131
|
+
return JSON.parse(readFileSync91(path2, "utf8"));
|
|
160532
161132
|
} catch {
|
|
160533
161133
|
return {};
|
|
160534
161134
|
}
|
|
@@ -160905,20 +161505,20 @@ __export(base44_auth_exports, {
|
|
|
160905
161505
|
usableBase44Auth: () => usableBase44Auth,
|
|
160906
161506
|
writeBase44Session: () => writeBase44Session
|
|
160907
161507
|
});
|
|
160908
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
161508
|
+
import { chmodSync as chmodSync4, existsSync as existsSync75, mkdirSync as mkdirSync36, readFileSync as readFileSync92, rmSync as rmSync19, writeFileSync as writeFileSync32 } from "node:fs";
|
|
160909
161509
|
import { homedir as homedir10 } from "node:os";
|
|
160910
|
-
import { dirname as dirname40, join as
|
|
161510
|
+
import { dirname as dirname40, join as join76 } from "node:path";
|
|
160911
161511
|
function base44ApiBase(env = process.env) {
|
|
160912
161512
|
return (env.BASE44_API_URL?.trim() || "https://app.base44.com").replace(/\/+$/, "");
|
|
160913
161513
|
}
|
|
160914
161514
|
function base44SessionPath(home = homedir10()) {
|
|
160915
|
-
return
|
|
161515
|
+
return join76(home, ".himi", "base44", "session.json");
|
|
160916
161516
|
}
|
|
160917
161517
|
function readBase44Session(home) {
|
|
160918
161518
|
const p2 = base44SessionPath(home);
|
|
160919
|
-
if (!
|
|
161519
|
+
if (!existsSync75(p2)) return void 0;
|
|
160920
161520
|
try {
|
|
160921
|
-
const s2 = JSON.parse(
|
|
161521
|
+
const s2 = JSON.parse(readFileSync92(p2, "utf8"));
|
|
160922
161522
|
return typeof s2.accessToken === "string" && s2.accessToken ? s2 : void 0;
|
|
160923
161523
|
} catch {
|
|
160924
161524
|
return void 0;
|
|
@@ -160934,7 +161534,7 @@ function writeBase44Session(session, home) {
|
|
|
160934
161534
|
}
|
|
160935
161535
|
function deleteBase44Session(home) {
|
|
160936
161536
|
const p2 = base44SessionPath(home);
|
|
160937
|
-
if (!
|
|
161537
|
+
if (!existsSync75(p2)) return false;
|
|
160938
161538
|
rmSync19(p2, { force: true });
|
|
160939
161539
|
return true;
|
|
160940
161540
|
}
|
|
@@ -161029,9 +161629,9 @@ async function base44DeviceLogin(opts) {
|
|
|
161029
161629
|
throw new Error("the Base44 sign-in code expired before it was approved \u2014 run `himi base44 login` again");
|
|
161030
161630
|
}
|
|
161031
161631
|
function importBase44CliSession(home = homedir10(), env = process.env) {
|
|
161032
|
-
const src =
|
|
161033
|
-
if (!
|
|
161034
|
-
const a2 = JSON.parse(
|
|
161632
|
+
const src = join76(home, ".base44", "auth", "auth.json");
|
|
161633
|
+
if (!existsSync75(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
|
|
161634
|
+
const a2 = JSON.parse(readFileSync92(src, "utf8"));
|
|
161035
161635
|
if (typeof a2.accessToken !== "string" || !a2.accessToken) throw new Error(`${src} holds no access token`);
|
|
161036
161636
|
const session = {
|
|
161037
161637
|
accessToken: a2.accessToken,
|
|
@@ -163166,7 +163766,7 @@ var init_brand_font = __esm({
|
|
|
163166
163766
|
|
|
163167
163767
|
// src/site-analyze/write-artifacts.ts
|
|
163168
163768
|
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync33 } from "node:fs";
|
|
163169
|
-
import { join as
|
|
163769
|
+
import { join as join77 } from "node:path";
|
|
163170
163770
|
function attachVeloSources(book, sources, put) {
|
|
163171
163771
|
const byPath = new Map((sources ?? []).map((s2) => [s2.path, s2.text]));
|
|
163172
163772
|
for (const f2 of book.velo.files) {
|
|
@@ -163321,12 +163921,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
163321
163921
|
}
|
|
163322
163922
|
async function writeBusinessBook(result, opts) {
|
|
163323
163923
|
const out2 = opts.outDir;
|
|
163324
|
-
mkdirSync37(
|
|
163325
|
-
mkdirSync37(
|
|
163924
|
+
mkdirSync37(join77(out2, "evidence/pages"), { recursive: true });
|
|
163925
|
+
mkdirSync37(join77(out2, "media/catalog"), { recursive: true });
|
|
163326
163926
|
const files = [];
|
|
163327
163927
|
const put = (rel, body) => {
|
|
163328
|
-
const p2 =
|
|
163329
|
-
mkdirSync37(
|
|
163928
|
+
const p2 = join77(out2, rel);
|
|
163929
|
+
mkdirSync37(join77(p2, ".."), { recursive: true });
|
|
163330
163930
|
writeFileSync33(p2, body);
|
|
163331
163931
|
files.push(rel);
|
|
163332
163932
|
};
|
|
@@ -164230,11 +164830,11 @@ var init_analyze = __esm({
|
|
|
164230
164830
|
});
|
|
164231
164831
|
|
|
164232
164832
|
// src/base44-analyze/write-artifacts.ts
|
|
164233
|
-
import { existsSync as
|
|
164234
|
-
import { dirname as dirname41, join as
|
|
164833
|
+
import { existsSync as existsSync76, mkdirSync as mkdirSync38, readFileSync as readFileSync93, rmSync as rmSync20, writeFileSync as writeFileSync34 } from "node:fs";
|
|
164834
|
+
import { dirname as dirname41, join as join78, resolve as resolve56, sep as sep19 } from "node:path";
|
|
164235
164835
|
function isBookFolder(dir) {
|
|
164236
164836
|
try {
|
|
164237
|
-
return JSON.parse(
|
|
164837
|
+
return JSON.parse(readFileSync93(join78(dir, "book.json"), "utf8")).kind === "base44-app-book";
|
|
164238
164838
|
} catch {
|
|
164239
164839
|
return false;
|
|
164240
164840
|
}
|
|
@@ -164321,24 +164921,24 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
164321
164921
|
const md = renderBookMd(book);
|
|
164322
164922
|
assertNoSecrets(json6);
|
|
164323
164923
|
assertNoSecrets(md);
|
|
164324
|
-
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) =>
|
|
164924
|
+
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync76(join78(out2, n2)));
|
|
164325
164925
|
if (owned.length) {
|
|
164326
164926
|
if (!isBookFolder(out2)) throw new Error(`refusing to write the app book into ${out2}: it already has ${owned.join(", ")} that ${owned.length === 1 ? "is" : "are"} not from an app book \u2014 pick an empty --out`);
|
|
164327
|
-
for (const d2 of ["source", "screenshots"]) rmSync20(
|
|
164927
|
+
for (const d2 of ["source", "screenshots"]) rmSync20(join78(out2, d2), { recursive: true, force: true });
|
|
164328
164928
|
}
|
|
164329
164929
|
mkdirSync38(out2, { recursive: true });
|
|
164330
|
-
writeFileSync34(
|
|
164331
|
-
writeFileSync34(
|
|
164930
|
+
writeFileSync34(join78(out2, "book.json"), json6);
|
|
164931
|
+
writeFileSync34(join78(out2, "BOOK.md"), md);
|
|
164332
164932
|
files.push("book.json", "BOOK.md");
|
|
164333
164933
|
for (const s2 of shots) {
|
|
164334
|
-
mkdirSync38(
|
|
164335
|
-
writeFileSync34(
|
|
164934
|
+
mkdirSync38(join78(out2, "screenshots"), { recursive: true });
|
|
164935
|
+
writeFileSync34(join78(out2, "screenshots", s2.filename), s2.bytes);
|
|
164336
164936
|
files.push(`screenshots/${s2.filename}`);
|
|
164337
164937
|
}
|
|
164338
|
-
const sourceRoot =
|
|
164938
|
+
const sourceRoot = join78(out2, "source");
|
|
164339
164939
|
for (const f2 of result.sourceFiles) {
|
|
164340
164940
|
if (!safeRel(f2.path)) continue;
|
|
164341
|
-
const dest =
|
|
164941
|
+
const dest = join78(sourceRoot, ...f2.path.split("/"));
|
|
164342
164942
|
if (!dest.startsWith(sourceRoot + sep19)) continue;
|
|
164343
164943
|
mkdirSync38(dirname41(dest), { recursive: true });
|
|
164344
164944
|
writeFileSync34(dest, f2.bytes);
|
|
@@ -167883,7 +168483,7 @@ __export(cli_exports, {
|
|
|
167883
168483
|
import { execFile } from "node:child_process";
|
|
167884
168484
|
import { mkdirSync as mkdirSync39, mkdtempSync as mkdtempSync4, rmSync as rmSync21, writeFileSync as writeFileSync35 } from "node:fs";
|
|
167885
168485
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
167886
|
-
import { join as
|
|
168486
|
+
import { join as join79, resolve as resolve57 } from "node:path";
|
|
167887
168487
|
import { promisify } from "node:util";
|
|
167888
168488
|
function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
167889
168489
|
return async (appId2) => {
|
|
@@ -167896,11 +168496,11 @@ function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
|
167896
168496
|
}
|
|
167897
168497
|
const bytes2 = await readCapped(res, MAX_TARBALL_BYTES);
|
|
167898
168498
|
if (!bytes2) throw new Error(`project download is over the ${MAX_TARBALL_BYTES}-byte cap`);
|
|
167899
|
-
const root = mkdtempSync4(
|
|
168499
|
+
const root = mkdtempSync4(join79(tmpdir5(), "himi-base44-"));
|
|
167900
168500
|
const cleanup = () => rmSync21(root, { recursive: true, force: true });
|
|
167901
168501
|
try {
|
|
167902
|
-
const archive =
|
|
167903
|
-
const dir =
|
|
168502
|
+
const archive = join79(root, "project.tar");
|
|
168503
|
+
const dir = join79(root, "project");
|
|
167904
168504
|
writeFileSync35(archive, bytes2);
|
|
167905
168505
|
mkdirSync39(dir);
|
|
167906
168506
|
await extract(archive, dir);
|
|
@@ -169195,8 +169795,8 @@ var init_customer_build = __esm({
|
|
|
169195
169795
|
});
|
|
169196
169796
|
|
|
169197
169797
|
// src/site-analyze/apply.ts
|
|
169198
|
-
import { existsSync as
|
|
169199
|
-
import { dirname as dirname42, isAbsolute as isAbsolute8, join as
|
|
169798
|
+
import { existsSync as existsSync77, readFileSync as readFileSync94, writeFileSync as writeFileSync36, copyFileSync as copyFileSync2, mkdirSync as mkdirSync40, realpathSync as realpathSync14, statSync as statSync20 } from "node:fs";
|
|
169799
|
+
import { dirname as dirname42, isAbsolute as isAbsolute8, join as join80, resolve as resolve58, sep as sep20 } from "node:path";
|
|
169200
169800
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
169201
169801
|
function unpairedRedirectNote(overlay) {
|
|
169202
169802
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
@@ -169211,7 +169811,7 @@ function committedShellProvisioning(path2) {
|
|
|
169211
169811
|
function findRepoRoot(cwd) {
|
|
169212
169812
|
let dir = cwd;
|
|
169213
169813
|
for (let i2 = 0; i2 < 8; i2++) {
|
|
169214
|
-
if (SHELL_NAMES2.some((name) =>
|
|
169814
|
+
if (SHELL_NAMES2.some((name) => existsSync77(join80(dir, shellAppDir(name), "package.json")))) return dir;
|
|
169215
169815
|
const next = dirname42(dir);
|
|
169216
169816
|
if (next === dir) break;
|
|
169217
169817
|
dir = next;
|
|
@@ -169314,11 +169914,11 @@ function sameKnownSite(previous, next) {
|
|
|
169314
169914
|
}
|
|
169315
169915
|
function buildMergedContract(options) {
|
|
169316
169916
|
const { appDir: appDir3, packageDir, overlay } = options;
|
|
169317
|
-
const committedPath =
|
|
169318
|
-
if (!
|
|
169917
|
+
const committedPath = join80(appDir3, "provisioning.json");
|
|
169918
|
+
if (!existsSync77(committedPath)) {
|
|
169319
169919
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
169320
169920
|
}
|
|
169321
|
-
const committed = JSON.parse(
|
|
169921
|
+
const committed = JSON.parse(readFileSync94(committedPath, "utf8"));
|
|
169322
169922
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
169323
169923
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
169324
169924
|
const branding = merged.branding ?? {};
|
|
@@ -169330,13 +169930,13 @@ function buildMergedContract(options) {
|
|
|
169330
169930
|
};
|
|
169331
169931
|
const stage = (fromRel, toRel) => {
|
|
169332
169932
|
const from = contained(packageDir, fromRel);
|
|
169333
|
-
const to2 = contained(
|
|
169334
|
-
if (!from || !to2 || !
|
|
169933
|
+
const to2 = contained(join80(appDir3, STAGED), toRel.slice(STAGED.length + 1));
|
|
169934
|
+
if (!from || !to2 || !existsSync77(from)) return void 0;
|
|
169335
169935
|
let real;
|
|
169336
169936
|
let realRoot;
|
|
169337
169937
|
try {
|
|
169338
|
-
real =
|
|
169339
|
-
realRoot =
|
|
169938
|
+
real = realpathSync14(from);
|
|
169939
|
+
realRoot = realpathSync14(packageDir);
|
|
169340
169940
|
} catch {
|
|
169341
169941
|
return void 0;
|
|
169342
169942
|
}
|
|
@@ -169353,11 +169953,11 @@ function buildMergedContract(options) {
|
|
|
169353
169953
|
};
|
|
169354
169954
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
169355
169955
|
if (icon) branding.appIconPath = icon;
|
|
169356
|
-
const facesPath =
|
|
169357
|
-
if (
|
|
169956
|
+
const facesPath = join80(packageDir, "media/fonts/faces.json");
|
|
169957
|
+
if (existsSync77(facesPath)) {
|
|
169358
169958
|
let faces = [];
|
|
169359
169959
|
try {
|
|
169360
|
-
const parsed = JSON.parse(
|
|
169960
|
+
const parsed = JSON.parse(readFileSync94(facesPath, "utf8"));
|
|
169361
169961
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
169362
169962
|
} catch {
|
|
169363
169963
|
faces = [];
|
|
@@ -169378,9 +169978,9 @@ function buildMergedContract(options) {
|
|
|
169378
169978
|
merged.branding = branding;
|
|
169379
169979
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
169380
169980
|
`;
|
|
169381
|
-
const path2 =
|
|
169981
|
+
const path2 = join80(packageDir, "provisioning.contract.json");
|
|
169382
169982
|
writeFileSync36(path2, body);
|
|
169383
|
-
const localPath2 =
|
|
169983
|
+
const localPath2 = join80(appDir3, LOCAL_CONTRACT_REL);
|
|
169384
169984
|
mkdirSync40(dirname42(localPath2), { recursive: true });
|
|
169385
169985
|
writeFileSync36(localPath2, body);
|
|
169386
169986
|
staged.push(localPath2);
|
|
@@ -169415,10 +170015,10 @@ function catalogTypography(overlay, template) {
|
|
|
169415
170015
|
function staticFaqFor(overlay, overlayPath) {
|
|
169416
170016
|
const own4 = overlay.faq;
|
|
169417
170017
|
if (own4 !== void 0) return deriveStaticFaq(own4);
|
|
169418
|
-
const bookPath =
|
|
169419
|
-
if (!
|
|
170018
|
+
const bookPath = join80(dirname42(resolve58(overlayPath)), "book.json");
|
|
170019
|
+
if (!existsSync77(bookPath)) return void 0;
|
|
169420
170020
|
try {
|
|
169421
|
-
const book = JSON.parse(
|
|
170021
|
+
const book = JSON.parse(readFileSync94(bookPath, "utf8"));
|
|
169422
170022
|
const copy = book?.copy;
|
|
169423
170023
|
if (!copy || typeof copy !== "object" || copy.unavailable) return void 0;
|
|
169424
170024
|
const pairs = deriveStaticFaq(copy.faq);
|
|
@@ -169432,10 +170032,10 @@ function staticGalleriesFor(overlay, overlayPath) {
|
|
|
169432
170032
|
if (overlay.galleries !== void 0) return deriveStaticGalleries(
|
|
169433
170033
|
overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
|
|
169434
170034
|
);
|
|
169435
|
-
const bookPath =
|
|
169436
|
-
if (!
|
|
170035
|
+
const bookPath = join80(dirname42(resolve58(overlayPath)), "book.json");
|
|
170036
|
+
if (!existsSync77(bookPath)) return void 0;
|
|
169437
170037
|
try {
|
|
169438
|
-
const book = JSON.parse(
|
|
170038
|
+
const book = JSON.parse(readFileSync94(bookPath, "utf8"));
|
|
169439
170039
|
if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
|
|
169440
170040
|
const galleries = deriveStaticGalleries(book.look.pages);
|
|
169441
170041
|
return galleries.length || book.look.complete === true ? galleries : void 0;
|
|
@@ -169447,8 +170047,8 @@ async function applyOverlays(input) {
|
|
|
169447
170047
|
const cwd = resolve58(input.cwd);
|
|
169448
170048
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
169449
170049
|
assertKnownShell(shell);
|
|
169450
|
-
const overlay = JSON.parse(
|
|
169451
|
-
const tokens2 = JSON.parse(
|
|
170050
|
+
const overlay = JSON.parse(readFileSync94(input.overlayPath, "utf8"));
|
|
170051
|
+
const tokens2 = JSON.parse(readFileSync94(input.tokensPath, "utf8"));
|
|
169452
170052
|
const faq = staticFaqFor(overlay, input.overlayPath);
|
|
169453
170053
|
if (faq !== void 0) overlay.faq = faq;
|
|
169454
170054
|
const galleries = staticGalleriesFor(overlay, input.overlayPath);
|
|
@@ -169465,9 +170065,9 @@ async function applyOverlays(input) {
|
|
|
169465
170065
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
169466
170066
|
);
|
|
169467
170067
|
}
|
|
169468
|
-
const appDir3 =
|
|
169469
|
-
const committedPath =
|
|
169470
|
-
const committedSite =
|
|
170068
|
+
const appDir3 = join80(repoRoot2, shellAppDir(shell));
|
|
170069
|
+
const committedPath = join80(appDir3, "provisioning.json");
|
|
170070
|
+
const committedSite = existsSync77(committedPath) ? JSON.parse(readFileSync94(committedPath, "utf8")).site : void 0;
|
|
169471
170071
|
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
169472
170072
|
throw new Error(
|
|
169473
170073
|
`shell "${shell}" is a site shell: its contract names the customer's website (a \`site\` block), and this overlay has none. Re-run \`himi site analyze --url <site> --shell ${shell}\` to derive the site's page map (edit \`site.pages\` in provisioning.overlay.json if needed), then --apply.`
|
|
@@ -169494,9 +170094,9 @@ async function applyOverlays(input) {
|
|
|
169494
170094
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
169495
170095
|
};
|
|
169496
170096
|
}
|
|
169497
|
-
const pkgProv =
|
|
170097
|
+
const pkgProv = join80(cwd, "provisioning.json");
|
|
169498
170098
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
169499
|
-
const contentPath =
|
|
170099
|
+
const contentPath = join80(cwd, "himalaya.content.json");
|
|
169500
170100
|
const syncViewNames = (before, after) => {
|
|
169501
170101
|
const content = readContentManifest(cwd);
|
|
169502
170102
|
if (!content) return;
|
|
@@ -169508,8 +170108,8 @@ async function applyOverlays(input) {
|
|
|
169508
170108
|
};
|
|
169509
170109
|
let packageFaq = faq;
|
|
169510
170110
|
let packageGalleries = galleries;
|
|
169511
|
-
if (
|
|
169512
|
-
const cur = JSON.parse(
|
|
170111
|
+
if (existsSync77(pkgProv)) {
|
|
170112
|
+
const cur = JSON.parse(readFileSync94(pkgProv, "utf8"));
|
|
169513
170113
|
if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
|
|
169514
170114
|
const merged = deepMerge4(cur, overlay);
|
|
169515
170115
|
packageFaq = merged.faq;
|
|
@@ -169525,9 +170125,9 @@ async function applyOverlays(input) {
|
|
|
169525
170125
|
if (Array.isArray(packageGalleries) && packageGalleries.length && !overlay.installedVerticals.includes("galleries")) {
|
|
169526
170126
|
overlay.installedVerticals.push("galleries");
|
|
169527
170127
|
}
|
|
169528
|
-
const pkgTokens =
|
|
169529
|
-
if (
|
|
169530
|
-
const cur = JSON.parse(
|
|
170128
|
+
const pkgTokens = join80(cwd, "tokens.json");
|
|
170129
|
+
if (existsSync77(pkgTokens) && (tokens2.colors || tokens2.typography)) {
|
|
170130
|
+
const cur = JSON.parse(readFileSync94(pkgTokens, "utf8"));
|
|
169531
170131
|
let tokensIn = tokens2;
|
|
169532
170132
|
if (tokens2.typography) {
|
|
169533
170133
|
const fonts = catalogTypography(tokens2.typography, cur.typography);
|
|
@@ -169552,9 +170152,9 @@ async function applyOverlays(input) {
|
|
|
169552
170152
|
wrote.push(pkgTokens);
|
|
169553
170153
|
}
|
|
169554
170154
|
const homeAction = homeRefreshActionId(shell);
|
|
169555
|
-
const homeSrc =
|
|
169556
|
-
if (homeAction &&
|
|
169557
|
-
const prev =
|
|
170155
|
+
const homeSrc = join80(cwd, "dev/index.ts");
|
|
170156
|
+
if (homeAction && existsSync77(homeSrc)) {
|
|
170157
|
+
const prev = readFileSync94(homeSrc, "utf8");
|
|
169558
170158
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
169559
170159
|
let next = patched.src;
|
|
169560
170160
|
if (!patched.foreign && faq?.length && prev.includes('"tier5.himiBrandedFaq.load"') && !prev.includes('"staticFaq"')) {
|
|
@@ -169589,13 +170189,13 @@ async function applyOverlays(input) {
|
|
|
169589
170189
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
169590
170190
|
}
|
|
169591
170191
|
}
|
|
169592
|
-
if (!input.iconPath || !
|
|
170192
|
+
if (!input.iconPath || !existsSync77(input.iconPath)) {
|
|
169593
170193
|
const book = input.iconPath ? dirname42(dirname42(resolve58(input.iconPath))) : void 0;
|
|
169594
170194
|
notes.push(
|
|
169595
170195
|
book ? `no icon installed \u2014 ${siteLogoAbsence(book).hint}` : "no icon installed and no business book to say why \u2014 `himi icon generate` draws one from the accent, or `himi icon set <file.png>` installs the customer's own mark"
|
|
169596
170196
|
);
|
|
169597
170197
|
}
|
|
169598
|
-
if (input.iconPath &&
|
|
170198
|
+
if (input.iconPath && existsSync77(input.iconPath)) {
|
|
169599
170199
|
try {
|
|
169600
170200
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
169601
170201
|
wrote.push(...installed.wrote);
|
|
@@ -170552,7 +171152,7 @@ __export(cli_exports2, {
|
|
|
170552
171152
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
170553
171153
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
170554
171154
|
});
|
|
170555
|
-
import { existsSync as
|
|
171155
|
+
import { existsSync as existsSync78, readFileSync as readFileSync95 } from "node:fs";
|
|
170556
171156
|
import { resolve as resolve59 } from "node:path";
|
|
170557
171157
|
function applyNeedsClient(shell) {
|
|
170558
171158
|
if (shell === void 0 || !SHELL_NAMES2.includes(shell)) return true;
|
|
@@ -170609,9 +171209,9 @@ async function runSiteAnalyze(opts) {
|
|
|
170609
171209
|
if (book?.skipped) result.warnings = [...result.warnings ?? [], book.skipped];
|
|
170610
171210
|
const derived = deriveSiteShell({ siteUrl: result.book.input.siteUrl, look: result.book.look, kind, routes });
|
|
170611
171211
|
const prevOverlayPath = resolve59(outDir, "provisioning.overlay.json");
|
|
170612
|
-
const prevSite =
|
|
171212
|
+
const prevSite = existsSync78(prevOverlayPath) ? (() => {
|
|
170613
171213
|
try {
|
|
170614
|
-
return JSON.parse(
|
|
171214
|
+
return JSON.parse(readFileSync95(prevOverlayPath, "utf8")).site;
|
|
170615
171215
|
} catch {
|
|
170616
171216
|
return void 0;
|
|
170617
171217
|
}
|
|
@@ -170630,7 +171230,7 @@ async function runSiteAnalyze(opts) {
|
|
|
170630
171230
|
}
|
|
170631
171231
|
const previousOverlay = resolve59(outDir, "provisioning.overlay.json");
|
|
170632
171232
|
carryOverGoals(
|
|
170633
|
-
|
|
171233
|
+
existsSync78(previousOverlay) ? readFileSync95(previousOverlay, "utf8") : void 0,
|
|
170634
171234
|
result.provisioningOverlay
|
|
170635
171235
|
);
|
|
170636
171236
|
const ownerCall = ownerAuth ? ownerTransportFrom(fetchImpl, ownerAuth) : void 0;
|
|
@@ -170688,7 +171288,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
170688
171288
|
let source;
|
|
170689
171289
|
if (opts.sourcePath) {
|
|
170690
171290
|
const p2 = resolve59(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
170691
|
-
source =
|
|
171291
|
+
source = readFileSync95(p2, "utf8");
|
|
170692
171292
|
}
|
|
170693
171293
|
let body;
|
|
170694
171294
|
if (opts.bodyRaw != null) {
|
|
@@ -170716,9 +171316,9 @@ async function runSiteFunctionCli(opts) {
|
|
|
170716
171316
|
});
|
|
170717
171317
|
}
|
|
170718
171318
|
function base44BookRoutes(bookPath, siteUrl) {
|
|
170719
|
-
if (!
|
|
171319
|
+
if (!existsSync78(bookPath)) return void 0;
|
|
170720
171320
|
try {
|
|
170721
|
-
const book = JSON.parse(
|
|
171321
|
+
const book = JSON.parse(readFileSync95(bookPath, "utf8"));
|
|
170722
171322
|
if (book.kind !== "base44-app-book" || !Array.isArray(book.routes)) return void 0;
|
|
170723
171323
|
const host = (u2) => {
|
|
170724
171324
|
try {
|
|
@@ -170973,7 +171573,7 @@ __export(site_create_exports, {
|
|
|
170973
171573
|
runSiteList: () => runSiteList,
|
|
170974
171574
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
170975
171575
|
});
|
|
170976
|
-
import { existsSync as
|
|
171576
|
+
import { existsSync as existsSync79, readFileSync as readFileSync96, writeFileSync as writeFileSync37 } from "node:fs";
|
|
170977
171577
|
import { resolve as resolvePath2 } from "node:path";
|
|
170978
171578
|
function oauthClientName(projectName) {
|
|
170979
171579
|
return `${projectName} client`;
|
|
@@ -171122,7 +171722,7 @@ async function runSiteCreate(opts) {
|
|
|
171122
171722
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
171123
171723
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
171124
171724
|
}
|
|
171125
|
-
function writeProvisioningBinding(target, binding2, fs2 = { existsSync:
|
|
171725
|
+
function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync79, readFileSync: readFileSync96, writeFileSync: writeFileSync37 }) {
|
|
171126
171726
|
const msid = binding2.siteId;
|
|
171127
171727
|
const path2 = resolvePath2(target);
|
|
171128
171728
|
const committed = committedShellProvisioning(path2);
|
|
@@ -171458,7 +172058,7 @@ var init_site_oauth_client = __esm({
|
|
|
171458
172058
|
|
|
171459
172059
|
// src/site-analyze/velo-source.ts
|
|
171460
172060
|
import path from "node:path";
|
|
171461
|
-
import
|
|
172061
|
+
import ts9 from "typescript";
|
|
171462
172062
|
function applySourceEdits(source, edits) {
|
|
171463
172063
|
const chunks = [];
|
|
171464
172064
|
let cursor = 0;
|
|
@@ -171476,13 +172076,13 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171476
172076
|
/\b(?:IST\.[\w.-]+|eyJ[\w-]+\.[\w-]+\.[\w-]+|(?:sk|rk)_(?:live|test)_[\w-]+|gh[pousr]_[\w]+|github_pat_[\w]+|AKIA[A-Z0-9]{16})\b/g,
|
|
171477
172077
|
REDACTED2
|
|
171478
172078
|
).replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, REDACTED2).replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/'"`]+:[^\s/'"`]+@/gi, "$1[REDACTED]@").replace(/([?&](?:api[-_]?key|token|secret|password|signature)=)[^&#\s'"`]+/gi, "$1[REDACTED]");
|
|
171479
|
-
const parsed =
|
|
172079
|
+
const parsed = ts9.createSourceFile("backend.ts", source, ts9.ScriptTarget.Latest, true);
|
|
171480
172080
|
const comments = /* @__PURE__ */ new Map();
|
|
171481
172081
|
const visitComments = (node) => {
|
|
171482
172082
|
for (const range of [
|
|
171483
|
-
...
|
|
171484
|
-
...
|
|
171485
|
-
...
|
|
172083
|
+
...ts9.getLeadingCommentRanges(source, node.pos) ?? [],
|
|
172084
|
+
...ts9.getTrailingCommentRanges(source, node.pos) ?? [],
|
|
172085
|
+
...ts9.getTrailingCommentRanges(source, node.end) ?? []
|
|
171486
172086
|
]) comments.set(range.pos, range.end);
|
|
171487
172087
|
for (const child of node.getChildren(parsed)) visitComments(child);
|
|
171488
172088
|
};
|
|
@@ -171501,22 +172101,22 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171501
172101
|
if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
|
|
171502
172102
|
return token;
|
|
171503
172103
|
};
|
|
171504
|
-
const clean2 =
|
|
172104
|
+
const clean2 = ts9.createSourceFile("backend.ts", source, ts9.ScriptTarget.Latest, true);
|
|
171505
172105
|
const masks = [];
|
|
171506
172106
|
const collectMasks = (node) => {
|
|
171507
172107
|
const start = node.getStart(clean2);
|
|
171508
|
-
if (
|
|
172108
|
+
if (ts9.isRegularExpressionLiteral(node)) {
|
|
171509
172109
|
masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
|
|
171510
|
-
} else if (
|
|
172110
|
+
} else if (ts9.isStringLiteral(node) || ts9.isTemplateLiteralToken(node)) {
|
|
171511
172111
|
masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
|
|
171512
172112
|
}
|
|
171513
|
-
|
|
172113
|
+
ts9.forEachChild(node, collectMasks);
|
|
171514
172114
|
};
|
|
171515
172115
|
collectMasks(clean2);
|
|
171516
172116
|
const assignmentContext = applySourceEdits(source, masks);
|
|
171517
172117
|
const edits = [];
|
|
171518
172118
|
const visitLiterals = (node) => {
|
|
171519
|
-
if (
|
|
172119
|
+
if (ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node) || ts9.isTemplateExpression(node)) {
|
|
171520
172120
|
const start = node.getStart(clean2);
|
|
171521
172121
|
const text9 = source.slice(start, node.end);
|
|
171522
172122
|
const redacted = redactLiteral(text9, start);
|
|
@@ -171525,7 +172125,7 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171525
172125
|
return;
|
|
171526
172126
|
}
|
|
171527
172127
|
}
|
|
171528
|
-
|
|
172128
|
+
ts9.forEachChild(node, visitLiterals);
|
|
171529
172129
|
};
|
|
171530
172130
|
visitLiterals(clean2);
|
|
171531
172131
|
return applySourceEdits(source, edits);
|
|
@@ -171564,19 +172164,19 @@ function selectVeloSource(files, request, knownSecrets = []) {
|
|
|
171564
172164
|
selected.set(file2.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
|
|
171565
172165
|
remaining -= excerpt.length;
|
|
171566
172166
|
const dependencies = [];
|
|
171567
|
-
const parsed =
|
|
172167
|
+
const parsed = ts9.createSourceFile(file2.path, file2.content, ts9.ScriptTarget.Latest, true);
|
|
171568
172168
|
const specifiers = [];
|
|
171569
172169
|
const collectImports = (node) => {
|
|
171570
172170
|
let specifier;
|
|
171571
|
-
if (
|
|
172171
|
+
if (ts9.isImportDeclaration(node) || ts9.isExportDeclaration(node)) {
|
|
171572
172172
|
specifier = node.moduleSpecifier;
|
|
171573
|
-
} else if (
|
|
172173
|
+
} else if (ts9.isImportEqualsDeclaration(node) && ts9.isExternalModuleReference(node.moduleReference)) {
|
|
171574
172174
|
specifier = node.moduleReference.expression;
|
|
171575
|
-
} else if (
|
|
172175
|
+
} else if (ts9.isCallExpression(node) && (node.expression.kind === ts9.SyntaxKind.ImportKeyword || ts9.isIdentifier(node.expression) && node.expression.text === "require")) {
|
|
171576
172176
|
specifier = node.arguments[0];
|
|
171577
172177
|
}
|
|
171578
|
-
if (specifier &&
|
|
171579
|
-
|
|
172178
|
+
if (specifier && ts9.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
|
|
172179
|
+
ts9.forEachChild(node, collectImports);
|
|
171580
172180
|
};
|
|
171581
172181
|
collectImports(parsed);
|
|
171582
172182
|
for (const specifier of specifiers) {
|
|
@@ -171650,7 +172250,7 @@ async function collectSiteContext(opts) {
|
|
|
171650
172250
|
visitorToken = await mintVisitorToken(fetcher, opts.clientId);
|
|
171651
172251
|
visitorAuth = { status: "ok" };
|
|
171652
172252
|
} catch (e2) {
|
|
171653
|
-
visitorAuth =
|
|
172253
|
+
visitorAuth = failed2(e2);
|
|
171654
172254
|
}
|
|
171655
172255
|
}
|
|
171656
172256
|
const visitor = visitorToken ? makeTransport(fetcher, { token: visitorToken, msid: opts.siteId }) : void 0;
|
|
@@ -171667,7 +172267,7 @@ async function collectSiteContext(opts) {
|
|
|
171667
172267
|
currency: identity2.locale.currency
|
|
171668
172268
|
} };
|
|
171669
172269
|
} catch (e2) {
|
|
171670
|
-
return
|
|
172270
|
+
return failed2(e2);
|
|
171671
172271
|
}
|
|
171672
172272
|
};
|
|
171673
172273
|
const cmsRead = async () => {
|
|
@@ -171680,7 +172280,7 @@ async function collectSiteContext(opts) {
|
|
|
171680
172280
|
return data;
|
|
171681
172281
|
} catch (e2) {
|
|
171682
172282
|
const code = e2 instanceof WixApiError2 ? e2.body?.details?.applicationError?.code : void 0;
|
|
171683
|
-
failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } :
|
|
172283
|
+
failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } : failed2(e2);
|
|
171684
172284
|
throw e2;
|
|
171685
172285
|
}
|
|
171686
172286
|
} : void 0;
|
|
@@ -171702,7 +172302,7 @@ async function collectSiteContext(opts) {
|
|
|
171702
172302
|
try {
|
|
171703
172303
|
return await owner(method, path2, body);
|
|
171704
172304
|
} catch (e2) {
|
|
171705
|
-
readFailure =
|
|
172305
|
+
readFailure = failed2(e2);
|
|
171706
172306
|
throw e2;
|
|
171707
172307
|
}
|
|
171708
172308
|
};
|
|
@@ -171729,7 +172329,7 @@ async function collectSiteContext(opts) {
|
|
|
171729
172329
|
truncated: files.length > selected.size || [...selected.values()].some((f2) => f2.sourceTruncated)
|
|
171730
172330
|
};
|
|
171731
172331
|
} catch (e2) {
|
|
171732
|
-
return { ...
|
|
172332
|
+
return { ...failed2(e2), files: [], sourceIncluded: false };
|
|
171733
172333
|
}
|
|
171734
172334
|
};
|
|
171735
172335
|
const [identity, cms, velo, probes] = await Promise.all([
|
|
@@ -171740,7 +172340,7 @@ async function collectSiteContext(opts) {
|
|
|
171740
172340
|
]);
|
|
171741
172341
|
const probeRead = (p2, available, auth) => {
|
|
171742
172342
|
if (!available) return auth;
|
|
171743
|
-
if (p2.httpStatus) return { ...
|
|
172343
|
+
if (p2.httpStatus) return { ...failed2(new WixApiError2(p2.httpStatus, "", "", null)), count: p2.count };
|
|
171744
172344
|
return { status: p2.status === "ok" || p2.status === "empty" ? p2.status : "error", count: p2.count };
|
|
171745
172345
|
};
|
|
171746
172346
|
return {
|
|
@@ -171756,7 +172356,7 @@ async function collectSiteContext(opts) {
|
|
|
171756
172356
|
}))
|
|
171757
172357
|
};
|
|
171758
172358
|
}
|
|
171759
|
-
var responseKeys, definitions, reads,
|
|
172359
|
+
var responseKeys, definitions, reads, failed2;
|
|
171760
172360
|
var init_context = __esm({
|
|
171761
172361
|
"src/site-analyze/context.ts"() {
|
|
171762
172362
|
init_probes();
|
|
@@ -171790,7 +172390,7 @@ var init_context = __esm({
|
|
|
171790
172390
|
...OWNER_VELO_PROBES.map((p2) => `${p2.method} ${p2.path}`),
|
|
171791
172391
|
...definitions.flatMap((p2) => [p2, ...p2.fallbacks ?? []].map((a2) => `${a2.method} ${a2.path}`))
|
|
171792
172392
|
]);
|
|
171793
|
-
|
|
172393
|
+
failed2 = (e2) => {
|
|
171794
172394
|
const httpStatus = e2 instanceof WixApiError2 ? e2.status : void 0;
|
|
171795
172395
|
return { status: httpStatus === 401 ? "unauthorized" : httpStatus === 403 ? "forbidden" : httpStatus === 404 || httpStatus === 428 ? "unavailable" : "error", ...httpStatus ? { httpStatus } : {} };
|
|
171796
172396
|
};
|
|
@@ -171798,12 +172398,12 @@ var init_context = __esm({
|
|
|
171798
172398
|
});
|
|
171799
172399
|
|
|
171800
172400
|
// src/cli.ts
|
|
171801
|
-
import { mkdtempSync as mkdtempSync5, readFileSync as
|
|
172401
|
+
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync97, mkdirSync as mkdirSync41, writeFileSync as writeFileSync38, existsSync as existsSync80, rmSync as rmSync22, readdirSync as readdirSync34, statSync as statSync21, lstatSync as lstatSync21, accessSync, constants as constants4, renameSync as renameSync12, cpSync as cpSync3 } from "node:fs";
|
|
171802
172402
|
import { execFile as execFile2, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
171803
172403
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
171804
172404
|
import { createHash as createHash41, randomUUID as randomUUID11 } from "node:crypto";
|
|
171805
172405
|
import { tmpdir as tmpdir6, homedir as homedir11, hostname as hostname2 } from "node:os";
|
|
171806
|
-
import { join as
|
|
172406
|
+
import { join as join81, resolve as resolve60, relative as relative15, basename as basename19, dirname as dirname43 } from "node:path";
|
|
171807
172407
|
import { fileURLToPath as fileURLToPath27 } from "node:url";
|
|
171808
172408
|
|
|
171809
172409
|
// ../serve-cli/src/client.ts
|
|
@@ -173957,8 +174557,8 @@ var str9 = (v2) => typeof v2 === "string" ? v2 : void 0;
|
|
|
173957
174557
|
var num3 = (v2) => typeof v2 === "string" && v2 !== "" && Number.isFinite(Number(v2)) ? Number(v2) : void 0;
|
|
173958
174558
|
function embeddedTemplateCatalog() {
|
|
173959
174559
|
return availableTemplates().map((name) => {
|
|
173960
|
-
const path2 =
|
|
173961
|
-
const meta = JSON.parse(
|
|
174560
|
+
const path2 = join81(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
174561
|
+
const meta = JSON.parse(readFileSync97(path2, "utf8"));
|
|
173962
174562
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
173963
174563
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
173964
174564
|
}
|
|
@@ -174495,11 +175095,20 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
174495
175095
|
exact price and explicit territories. Re-reads Apple
|
|
174496
175096
|
first, never edits a live product, never duplicates on
|
|
174497
175097
|
a rerun; prompts unless --yes. Writes the Wix\u2192Apple
|
|
174498
|
-
mapping
|
|
175098
|
+
mapping locally; \`connect\` registers it with Wix.
|
|
174499
175099
|
--limit <n> creates at most n new products per run (big
|
|
174500
175100
|
catalogs go in batches; a rerun continues).
|
|
174501
175101
|
himi store iap status --manifest <file> --profile <name> [--out <file>] [--json]
|
|
174502
175102
|
READ-ONLY: what App Store Connect has for each product.
|
|
175103
|
+
himi store iap connect --manifest <file> --profile <name> [--iap-key <AuthKey.p8> --iap-key-id <id>]
|
|
175104
|
+
[--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <report.json>] [--json]
|
|
175105
|
+
connect the manifest's Wix site to sell those products:
|
|
175106
|
+
register the bundle's purchases app on that site, store its
|
|
175107
|
+
In-App Purchase key, connect the appleIAP provider, and map
|
|
175108
|
+
each Wix item to its Apple product. Reads first and reuses
|
|
175109
|
+
what exists; a bundle, mapping or SKU held elsewhere is a
|
|
175110
|
+
conflict, never overwritten. --content records the
|
|
175111
|
+
purchases app as wixIap in the app's config.ts.
|
|
174503
175112
|
No build, signing or repo checkout. Guide: himi docs iap-products
|
|
174504
175113
|
himi logout [--target <t>] clear the stored control token for a target
|
|
174505
175114
|
himi notify setup --content <dir> [--target wix] [--yes] [--no-push-setup]
|
|
@@ -174803,7 +175412,7 @@ var COMMANDS2 = [
|
|
|
174803
175412
|
{ name: "visibility", summary: "read (no value) or set whether the public registry (/v1/apps + the Himi Player picker) LISTS the app. `public` lists it for everyone; `unlisted` hides it from listings while direct reads by app id \u2014 deep links, previews \u2014 keep working. App from --app or the content dir. Setting it needs no republish.", required: "[public|unlisted] [--app <a>] [--content <dir>] (--control-token)" },
|
|
174804
175413
|
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | brandy | base44 | player | demo-app) and defaults to the content package's himalaya.content.json `shell` (templates carry the one they were written for), else branded-lite. The per-app shells ADD the release's declared capabilities to the binary, while Himi Player and demo-app refuse a release declaring one they lack; `--plan` previews it without building; `brandy` is the site shell \u2014 the customer's own website as native-framed tabs. `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo --site <id>` reuses an existing customer ad-hoc profile and certificate for iOS; requires an owned site and a completed personal signing binding. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|brandy|base44|player|demo-app] [--signing wix-managed|byo] [--site <id>] [--android-signing qa-keystore|wix-keystore|debug] [--borrow-ios-id <bundleId>] [--no-wait] [--force] [--plan] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
174805
175414
|
{ name: "testflight", summary: 'build, sign and upload an app to TestFlight (internal testers \u2014 no Beta App Review), then WAIT until App Store Connect finishes processing it. Sugar for `store upload --track testflight`. Prompts first: a build number is consumed permanently on a real Apple account and cannot be reused \u2014 `--yes` for CI, `--dry-run` to see the plan without touching anything. The wait is the real check, not a nicety: fastlane prints "Successfully uploaded" for a binary App Store Connect then rejects in processing, and a rejected binary leaves NO build record at all (the reason is emailed). Public App Store review is deliberately NOT automatable here \u2014 `--track appstore` is refused; use /submit-ios-app when you mean to go public', required: "<app> [--track testflight|internal] [--profile <name>] [--yes] [--dry-run] [--skip-build] [--no-wait] [--json]" },
|
|
174806
|
-
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo. `iap draft|plan|apply|status` registers an app owner's digital products as in-app purchases (non-consumables, or consumable price tiers): draft reads the Wix catalog and writes the manifest, plan and status only read, apply is the one mutation boundary, and none of them builds, signs or needs a checkout (`himi docs iap-products`)", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>] | iap draft --site <msid> --profile <n> --apple-app <id> --bundle <id> --base-territory <t> --out <f> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <f>] [--report <f>] [--json] | iap plan --manifest <f> --profile <n> --out <f> [--json] | iap apply --plan <f> --profile <n> --out <f> [--yes] [--limit <n>] [--json] | iap status --manifest <f> --profile <n> [--out <f>] [--json]" },
|
|
175415
|
+
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo. `iap draft|plan|apply|status|connect` registers an app owner's digital products as in-app purchases (non-consumables, or consumable price tiers): draft reads the Wix catalog and writes the manifest, plan and status only read, apply is the one App Store mutation boundary, connect readies the Wix site to sell them (purchases app, In-App Purchase key, appleIAP provider, product mappings; --preview-tag routes only its Serve calls to a deploy preview), and none of them builds, signs or needs a checkout (`himi docs iap-products`)", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>] | iap draft --site <msid> --profile <n> --apple-app <id> --bundle <id> --base-territory <t> --out <f> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <f>] [--report <f>] [--json] | iap plan --manifest <f> --profile <n> --out <f> [--json] | iap apply --plan <f> --profile <n> --out <f> [--yes] [--limit <n>] [--json] | iap status --manifest <f> --profile <n> [--out <f>] [--json] | iap connect --manifest <f> --profile <n> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <f>] [--json]" },
|
|
174807
175416
|
{ name: "guide", summary: "print the Himalaya overview + headless dev loop + available topics (offline)", required: "[--json]" },
|
|
174808
175417
|
{ name: "docs", summary: "print bundled/verified cached guides offline; status reports kit identity; refresh downloads compatible reference content independently of CLI without changing app source", required: "[<topic>|catalog [kind]|status|refresh] [--pin <version|digest>] [--unpin] [--no-network] [--json]" },
|
|
174809
175418
|
{ name: "components", summary: "print the SDUI component vocabulary + props; a name = that component (offline)", required: "[<Name>] [--json]" },
|
|
@@ -174820,7 +175429,7 @@ var COMMANDS2 = [
|
|
|
174820
175429
|
];
|
|
174821
175430
|
function cliVersion() {
|
|
174822
175431
|
try {
|
|
174823
|
-
return JSON.parse(
|
|
175432
|
+
return JSON.parse(readFileSync97(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
174824
175433
|
} catch {
|
|
174825
175434
|
return "unknown";
|
|
174826
175435
|
}
|
|
@@ -174945,7 +175554,7 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
174945
175554
|
}
|
|
174946
175555
|
function packageVersion(path2) {
|
|
174947
175556
|
try {
|
|
174948
|
-
const version4 = JSON.parse(
|
|
175557
|
+
const version4 = JSON.parse(readFileSync97(path2, "utf8")).version;
|
|
174949
175558
|
return typeof version4 === "string" && version4 ? version4 : void 0;
|
|
174950
175559
|
} catch {
|
|
174951
175560
|
return void 0;
|
|
@@ -174954,7 +175563,7 @@ function packageVersion(path2) {
|
|
|
174954
175563
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
174955
175564
|
let dir = resolve60(fromDir);
|
|
174956
175565
|
for (; ; ) {
|
|
174957
|
-
const version4 = packageVersion(
|
|
175566
|
+
const version4 = packageVersion(join81(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
174958
175567
|
if (version4) return { version: version4, source: "local" };
|
|
174959
175568
|
const parent = dirname43(dir);
|
|
174960
175569
|
if (parent === dir) break;
|
|
@@ -174964,7 +175573,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
174964
175573
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
174965
175574
|
try {
|
|
174966
175575
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
174967
|
-
const version4 = root ? packageVersion(
|
|
175576
|
+
const version4 = root ? packageVersion(join81(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
174968
175577
|
return version4 ? { version: version4, source: "global" } : {};
|
|
174969
175578
|
} catch {
|
|
174970
175579
|
return {};
|
|
@@ -175011,11 +175620,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
175011
175620
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
175012
175621
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
175013
175622
|
function updateCachePath(env = process.env) {
|
|
175014
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
175623
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join81(homedir11(), ".himalaya", "update-check.json");
|
|
175015
175624
|
}
|
|
175016
175625
|
function readUpdateCache(path2) {
|
|
175017
175626
|
try {
|
|
175018
|
-
const parsed = JSON.parse(
|
|
175627
|
+
const parsed = JSON.parse(readFileSync97(path2, "utf8"));
|
|
175019
175628
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
175020
175629
|
} catch {
|
|
175021
175630
|
return {};
|
|
@@ -175084,12 +175693,12 @@ function createUpdateRunner(spawn8 = spawnSync5) {
|
|
|
175084
175693
|
},
|
|
175085
175694
|
installedVersion: () => {
|
|
175086
175695
|
const root = globalNodeModulesRoot();
|
|
175087
|
-
return root ? packageVersion(
|
|
175696
|
+
return root ? packageVersion(join81(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
175088
175697
|
},
|
|
175089
175698
|
reexec: (argv) => {
|
|
175090
175699
|
const root = globalNodeModulesRoot();
|
|
175091
|
-
const entry = root ?
|
|
175092
|
-
if (!entry || !
|
|
175700
|
+
const entry = root ? join81(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
175701
|
+
if (!entry || !existsSync80(entry)) return void 0;
|
|
175093
175702
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
175094
175703
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
175095
175704
|
stdio: "inherit",
|
|
@@ -175136,7 +175745,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
175136
175745
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
175137
175746
|
let content;
|
|
175138
175747
|
try {
|
|
175139
|
-
content =
|
|
175748
|
+
content = readFileSync97(path2, "utf8");
|
|
175140
175749
|
} catch {
|
|
175141
175750
|
continue;
|
|
175142
175751
|
}
|
|
@@ -175159,7 +175768,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
175159
175768
|
const mine = lockStamp(now);
|
|
175160
175769
|
const readLock = (path2) => {
|
|
175161
175770
|
try {
|
|
175162
|
-
return
|
|
175771
|
+
return readFileSync97(path2, "utf8");
|
|
175163
175772
|
} catch {
|
|
175164
175773
|
return void 0;
|
|
175165
175774
|
}
|
|
@@ -175751,7 +176360,7 @@ function executableOnPath(name, env = process.env) {
|
|
|
175751
176360
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
175752
176361
|
for (const dir of entries) {
|
|
175753
176362
|
for (const suffix of suffixes) {
|
|
175754
|
-
const candidate =
|
|
176363
|
+
const candidate = join81(dir, `${name}${suffix}`);
|
|
175755
176364
|
try {
|
|
175756
176365
|
if (!statSync21(candidate).isFile()) continue;
|
|
175757
176366
|
if (process.platform !== "win32") accessSync(candidate, constants4.X_OK);
|
|
@@ -175860,7 +176469,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
175860
176469
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths2(), paths_exports));
|
|
175861
176470
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
175862
176471
|
const iosYmlPath = iosProjectYml2(app);
|
|
175863
|
-
const iosYml =
|
|
176472
|
+
const iosYml = existsSync80(iosYmlPath) ? readFileSync97(iosYmlPath, "utf8") : "";
|
|
175864
176473
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
175865
176474
|
if (!optedIn) {
|
|
175866
176475
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -175874,7 +176483,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
175874
176483
|
}
|
|
175875
176484
|
function readConfigSource(dir) {
|
|
175876
176485
|
try {
|
|
175877
|
-
return
|
|
176486
|
+
return readFileSync97(join81(dir, "config.ts"), "utf8");
|
|
175878
176487
|
} catch {
|
|
175879
176488
|
return null;
|
|
175880
176489
|
}
|
|
@@ -175928,7 +176537,7 @@ var NoBase44SlotError = class extends Error {
|
|
|
175928
176537
|
};
|
|
175929
176538
|
async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {}) {
|
|
175930
176539
|
const dir = resolve60(parentDir, name);
|
|
175931
|
-
if (
|
|
176540
|
+
if (existsSync80(join81(dir, "himalaya.content.json"))) {
|
|
175932
176541
|
throw new Error(`content package already exists at ${dir}`);
|
|
175933
176542
|
}
|
|
175934
176543
|
const r2 = await c2.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -175974,7 +176583,7 @@ function symlinkDestinationIssue(dest) {
|
|
|
175974
176583
|
function restoreDestinationIssue(dest, force) {
|
|
175975
176584
|
const link = symlinkDestinationIssue(dest);
|
|
175976
176585
|
if (link) return link;
|
|
175977
|
-
if (!
|
|
176586
|
+
if (!existsSync80(dest)) return null;
|
|
175978
176587
|
if (!statSync21(dest).isDirectory()) {
|
|
175979
176588
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
175980
176589
|
}
|
|
@@ -175989,7 +176598,7 @@ function restoreDestinationIssue(dest, force) {
|
|
|
175989
176598
|
function isHimalayaMonorepoCheckout(start) {
|
|
175990
176599
|
let dir = resolve60(start);
|
|
175991
176600
|
for (; ; ) {
|
|
175992
|
-
if (
|
|
176601
|
+
if (existsSync80(join81(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync80(join81(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
175993
176602
|
const parent = dirname43(dir);
|
|
175994
176603
|
if (parent === dir) return false;
|
|
175995
176604
|
dir = parent;
|
|
@@ -176027,7 +176636,7 @@ function shellShaDivergenceWarnings(jobs) {
|
|
|
176027
176636
|
}
|
|
176028
176637
|
async function templatePublishName(sourceDir) {
|
|
176029
176638
|
const id = await appId(sourceDir);
|
|
176030
|
-
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ?
|
|
176639
|
+
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ? basename19(sourceDir) : id;
|
|
176031
176640
|
}
|
|
176032
176641
|
function templateNameError(name, from) {
|
|
176033
176642
|
if (name.startsWith(TEMPLATE_APP_PREFIX)) {
|
|
@@ -176050,7 +176659,7 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176050
176659
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
176051
176660
|
);
|
|
176052
176661
|
const repoRoot2 = resolve60(fileURLToPath27(new URL("../../..", import.meta.url)));
|
|
176053
|
-
const root =
|
|
176662
|
+
const root = join81(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
176054
176663
|
const stillRunning = (pid) => {
|
|
176055
176664
|
try {
|
|
176056
176665
|
process.kill(pid, 0);
|
|
@@ -176064,12 +176673,12 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176064
176673
|
if (!entry.isDirectory()) continue;
|
|
176065
176674
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
176066
176675
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
176067
|
-
rmSync22(
|
|
176676
|
+
rmSync22(join81(root, entry.name), { recursive: true, force: true });
|
|
176068
176677
|
}
|
|
176069
176678
|
}
|
|
176070
176679
|
} catch {
|
|
176071
176680
|
}
|
|
176072
|
-
const dest =
|
|
176681
|
+
const dest = join81(root, `${slug}-${process.pid}`);
|
|
176073
176682
|
rmSync22(dest, { recursive: true, force: true });
|
|
176074
176683
|
mkdirSync41(dest, { recursive: true });
|
|
176075
176684
|
try {
|
|
@@ -176082,17 +176691,17 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176082
176691
|
}
|
|
176083
176692
|
async function appId(dir) {
|
|
176084
176693
|
try {
|
|
176085
|
-
const { readFileSync:
|
|
176086
|
-
const m2 = JSON.parse(
|
|
176694
|
+
const { readFileSync: readFileSync98 } = await import("node:fs");
|
|
176695
|
+
const m2 = JSON.parse(readFileSync98(join81(dir, "himalaya.content.json"), "utf8"));
|
|
176087
176696
|
if (m2.name) return m2.name;
|
|
176088
176697
|
} catch {
|
|
176089
176698
|
}
|
|
176090
|
-
return
|
|
176699
|
+
return basename19(dir);
|
|
176091
176700
|
}
|
|
176092
176701
|
async function contentVisibility(dir) {
|
|
176093
176702
|
try {
|
|
176094
|
-
const { readFileSync:
|
|
176095
|
-
const m2 = JSON.parse(
|
|
176703
|
+
const { readFileSync: readFileSync98 } = await import("node:fs");
|
|
176704
|
+
const m2 = JSON.parse(readFileSync98(join81(dir, "himalaya.content.json"), "utf8"));
|
|
176096
176705
|
if (m2.visibility === "public" || m2.visibility === "unlisted") return m2.visibility;
|
|
176097
176706
|
} catch {
|
|
176098
176707
|
}
|
|
@@ -176381,7 +176990,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
176381
176990
|
...res.removed.length ? { removed: res.removed, note: "older copies at the app root, moved to .himi/legacy-agent-files/ (a backup, in case one became app code) \u2014 the current ones live in .agents/skills/himalaya/" } : {},
|
|
176382
176991
|
// In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
|
|
176383
176992
|
// hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
|
|
176384
|
-
...
|
|
176993
|
+
...existsSync80(join81(dir, ".himi", "attestations", "latest.json")) ? { next: "if `himi push` then refuses the attestation as stale, re-run `himi test` \u2014 in a git checkout this refresh changed the tree it covered" } : {},
|
|
176385
176994
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
176386
176995
|
portalUrl: idx.portalUrl
|
|
176387
176996
|
});
|
|
@@ -176404,7 +177013,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
176404
177013
|
try {
|
|
176405
177014
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
176406
177015
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
176407
|
-
out2 = mkdtempSync5(
|
|
177016
|
+
out2 = mkdtempSync5(join81(tmpdir6(), "himi-ux-record-"));
|
|
176408
177017
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
176409
177018
|
const outcome = await buildReleaseFromContent2(dir, out2, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
176410
177019
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -176583,7 +177192,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
176583
177192
|
let js2;
|
|
176584
177193
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
176585
177194
|
try {
|
|
176586
|
-
js2 =
|
|
177195
|
+
js2 = readFileSync97(join81(outDir, candidate), "utf8");
|
|
176587
177196
|
break;
|
|
176588
177197
|
} catch {
|
|
176589
177198
|
}
|
|
@@ -176614,7 +177223,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
176614
177223
|
}
|
|
176615
177224
|
return { families, source: "dist/bundles" };
|
|
176616
177225
|
}
|
|
176617
|
-
var boardOpen = (dir) =>
|
|
177226
|
+
var boardOpen = (dir) => existsSync80(join81(dir, ".himi", "studio", "index.html"));
|
|
176618
177227
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
176619
177228
|
async function leaveForBoard(dir, record2, value) {
|
|
176620
177229
|
if (!boardOpen(dir)) return;
|
|
@@ -176638,7 +177247,7 @@ async function liveMapFor(dir) {
|
|
|
176638
177247
|
}
|
|
176639
177248
|
var commandScratch = new AsyncLocalStorage2();
|
|
176640
177249
|
function commandScratchDir(prefix) {
|
|
176641
|
-
const dir = mkdtempSync5(
|
|
177250
|
+
const dir = mkdtempSync5(join81(tmpdir6(), prefix));
|
|
176642
177251
|
commandScratch.getStore()?.push(dir);
|
|
176643
177252
|
return dir;
|
|
176644
177253
|
}
|
|
@@ -176992,7 +177601,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
176992
177601
|
const owed = openApprovals2(readApprovals2(dir).events).length;
|
|
176993
177602
|
next.push(`carried the planning journal into the app (${carried.join(", ")}${owed ? `; ${owed} approval${owed === 1 ? "" : "s"} still owed` : ""}) \u2014 \`himi progress --brief\` there shows it`);
|
|
176994
177603
|
}
|
|
176995
|
-
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) =>
|
|
177604
|
+
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync80(join81(parentDir, f2)));
|
|
176996
177605
|
if (planInParent.length) {
|
|
176997
177606
|
next.push(`${planInParent.join(" and ")} in ${parentDir} ${planInParent.length > 1 ? "are" : "is"} not the app's \u2014 if that is the approved plan, move it over the template's boilerplate in ${dir}`);
|
|
176998
177607
|
}
|
|
@@ -177153,13 +177762,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177153
177762
|
if (adding) {
|
|
177154
177763
|
const from = str9(flags.from);
|
|
177155
177764
|
if (!from) throw new TrimRefusal2('--add <id> needs --from <file> holding the whole new SCREENS entry (` "<id>": { "screenId": "<id>", \u2026 },`)');
|
|
177156
|
-
print(adopt.addScreen(dir, adding,
|
|
177765
|
+
print(adopt.addScreen(dir, adding, readFileSync97(from, "utf8"), { parent: str9(flags.parent), tab: str9(flags.tab), displayName: str9(flags["display-name"]) }));
|
|
177157
177766
|
return 0;
|
|
177158
177767
|
}
|
|
177159
177768
|
if (target) {
|
|
177160
177769
|
const from = str9(flags.from);
|
|
177161
177770
|
if (!from) throw new TrimRefusal2("--write <id> needs --from <file> holding the whole entry, as --show prints it");
|
|
177162
|
-
print(adopt.replaceScreen(dir, target,
|
|
177771
|
+
print(adopt.replaceScreen(dir, target, readFileSync97(from, "utf8")));
|
|
177163
177772
|
return 0;
|
|
177164
177773
|
}
|
|
177165
177774
|
if (show) {
|
|
@@ -177241,7 +177850,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177241
177850
|
const { keepFromSpec: keepFromSpec2 } = await Promise.resolve().then(() => (init_template_adopt(), template_adopt_exports));
|
|
177242
177851
|
const dir = contentDir(flags);
|
|
177243
177852
|
try {
|
|
177244
|
-
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ??
|
|
177853
|
+
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ?? join81(dir, "SPEC.md"));
|
|
177245
177854
|
const own4 = typeof keep === "string" ? keep.split(",").map((k2) => k2.trim()).filter(Boolean) : [];
|
|
177246
177855
|
keep = [.../* @__PURE__ */ new Set([...spec.keep, ...own4])].join(",");
|
|
177247
177856
|
fromSpec = { fromSpec: {
|
|
@@ -177282,7 +177891,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177282
177891
|
const result = { ...outcome.result, ...fromSpec };
|
|
177283
177892
|
const adoptDir = contentDir(flags);
|
|
177284
177893
|
const kept = flags["dry-run"] !== true && (outcome.code === 0 || outcome.result.forcedKeep === true);
|
|
177285
|
-
if (kept &&
|
|
177894
|
+
if (kept && existsSync80(join81(adoptDir, adoptBits.ADOPT_FILE))) {
|
|
177286
177895
|
try {
|
|
177287
177896
|
const inv = adoptBits.inspectApp(adoptDir);
|
|
177288
177897
|
adoptBits.writeInventory(adoptDir, inv, { companions: "if-missing" });
|
|
@@ -177311,7 +177920,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177311
177920
|
const sourceDir = resolve60(str9(flags["source-dir"]) ?? appDir3);
|
|
177312
177921
|
let meta;
|
|
177313
177922
|
try {
|
|
177314
|
-
meta = JSON.parse(
|
|
177923
|
+
meta = JSON.parse(readFileSync97(join81(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
177315
177924
|
} catch {
|
|
177316
177925
|
io2.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>)` }));
|
|
177317
177926
|
return 2;
|
|
@@ -177321,7 +177930,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177321
177930
|
return 2;
|
|
177322
177931
|
}
|
|
177323
177932
|
try {
|
|
177324
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
177933
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync97(join81(sourceDir, "tokens.json"), "utf8")));
|
|
177325
177934
|
meta = { ...appearance, ...meta };
|
|
177326
177935
|
} catch {
|
|
177327
177936
|
}
|
|
@@ -177343,7 +177952,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177343
177952
|
const force = flags.force === true;
|
|
177344
177953
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
177345
177954
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
177346
|
-
const out2 = mkdtempSync5(
|
|
177955
|
+
const out2 = mkdtempSync5(join81(tmpdir6(), "himi-template-"));
|
|
177347
177956
|
publishScratch.push(out2);
|
|
177348
177957
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
177349
177958
|
const outcome = await buildReleaseFromContent2(buildDir, out2, {
|
|
@@ -177400,7 +178009,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177400
178009
|
let iconHash;
|
|
177401
178010
|
if (iconPath) {
|
|
177402
178011
|
try {
|
|
177403
|
-
const bytes2 =
|
|
178012
|
+
const bytes2 = readFileSync97(iconPath);
|
|
177404
178013
|
payload.icon = bytes2.toString("base64");
|
|
177405
178014
|
iconHash = createHash41("sha256").update(bytes2).digest("hex");
|
|
177406
178015
|
} catch {
|
|
@@ -177587,17 +178196,17 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177587
178196
|
const dir = contentDir(flags);
|
|
177588
178197
|
const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
|
|
177589
178198
|
const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
177590
|
-
const
|
|
178199
|
+
const failed3 = res.compileErrors;
|
|
177591
178200
|
print({
|
|
177592
|
-
ok:
|
|
178201
|
+
ok: failed3.length === 0,
|
|
177593
178202
|
outDir: res.outDir,
|
|
177594
178203
|
built: res.built,
|
|
177595
|
-
...
|
|
178204
|
+
...failed3.length ? { compileErrors: failed3 } : {},
|
|
177596
178205
|
// #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
|
|
177597
178206
|
// still compile); `validate --strict` is where it hard-fails.
|
|
177598
178207
|
...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
|
|
177599
178208
|
});
|
|
177600
|
-
return
|
|
178209
|
+
return failed3.length ? 1 : 0;
|
|
177601
178210
|
}
|
|
177602
178211
|
case "eject": {
|
|
177603
178212
|
const mod = String(pos[1] ?? "");
|
|
@@ -177699,7 +178308,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177699
178308
|
const path2 = dpxSessionTokenPath();
|
|
177700
178309
|
let raw;
|
|
177701
178310
|
try {
|
|
177702
|
-
raw =
|
|
178311
|
+
raw = readFileSync97(path2, "utf8");
|
|
177703
178312
|
} catch {
|
|
177704
178313
|
throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
|
|
177705
178314
|
}
|
|
@@ -177833,8 +178442,8 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177833
178442
|
const dir = resolve60(out2);
|
|
177834
178443
|
const files = himiPluginFiles2(skills.skillMd);
|
|
177835
178444
|
for (const f2 of files) {
|
|
177836
|
-
mkdirSync41(dirname43(
|
|
177837
|
-
writeFileSync38(
|
|
178445
|
+
mkdirSync41(dirname43(join81(dir, f2.path)), { recursive: true });
|
|
178446
|
+
writeFileSync38(join81(dir, f2.path), f2.text);
|
|
177838
178447
|
}
|
|
177839
178448
|
print({ ok: true, dir, files: files.map((f2) => f2.path), next: [`claude plugin validate ${dir}`, `claude --plugin-dir ${dir}`] });
|
|
177840
178449
|
return 0;
|
|
@@ -177851,13 +178460,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177851
178460
|
case "studio": {
|
|
177852
178461
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
177853
178462
|
const dir = contentDir(flags);
|
|
177854
|
-
if (!
|
|
178463
|
+
if (!existsSync80(join81(dir, "himalaya.content.json"))) {
|
|
177855
178464
|
io2.error(JSON.stringify({ ok: false, error: "not_a_content_package", dir, hint: "run from the app directory (or pass --content <dir>) \u2014 the board reads that package's .himi/" }));
|
|
177856
178465
|
return 2;
|
|
177857
178466
|
}
|
|
177858
178467
|
if (pos[1] === "reel") {
|
|
177859
178468
|
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
177860
|
-
const out2 = resolve60(str9(flags.out) ??
|
|
178469
|
+
const out2 = resolve60(str9(flags.out) ?? join81(dir, ".himi", "making-of.html"));
|
|
177861
178470
|
const { html, plan } = buildReel2(dir);
|
|
177862
178471
|
mkdirSync41(dirname43(out2), { recursive: true });
|
|
177863
178472
|
writeFileSync38(out2, html);
|
|
@@ -177868,7 +178477,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177868
178477
|
const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
|
|
177869
178478
|
openUrl2(url2);
|
|
177870
178479
|
}
|
|
177871
|
-
const handover = { file: out2, hint: `hand ${
|
|
178480
|
+
const handover = { file: out2, hint: `hand ${basename19(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` };
|
|
177872
178481
|
const report3 = {
|
|
177873
178482
|
ok: true,
|
|
177874
178483
|
file: out2,
|
|
@@ -177929,7 +178538,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
177929
178538
|
} = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
177930
178539
|
const dir = contentDir(flags);
|
|
177931
178540
|
const journal2 = journalPath2(dir);
|
|
177932
|
-
const isContentPackage =
|
|
178541
|
+
const isContentPackage = existsSync80(join81(dir, "himalaya.content.json"));
|
|
177933
178542
|
const hint = isContentPackage ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
|
|
177934
178543
|
const message = pos.slice(1).join(" ").trim();
|
|
177935
178544
|
const approvalFlags = ["approve", "done", "drop"].filter((f2) => flags[f2] !== void 0);
|
|
@@ -178081,7 +178690,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178081
178690
|
case "test": {
|
|
178082
178691
|
const dir = contentDir(flags);
|
|
178083
178692
|
const structuredOutput = flags.json === true || io2.isTTY !== true;
|
|
178084
|
-
if (
|
|
178693
|
+
if (existsSync80(join81(dir, "functions"))) {
|
|
178085
178694
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
178086
178695
|
const loaded = await loadFunctionsApp2(dir);
|
|
178087
178696
|
const results = [];
|
|
@@ -178213,7 +178822,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178213
178822
|
io2.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
178214
178823
|
return 2;
|
|
178215
178824
|
}
|
|
178216
|
-
const sources = collectWorkerSources2(
|
|
178825
|
+
const sources = collectWorkerSources2(join81(dir, "tier5-src"), screen.bundleName);
|
|
178217
178826
|
if (!sources) {
|
|
178218
178827
|
io2.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
178219
178828
|
return 2;
|
|
@@ -178391,7 +179000,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178391
179000
|
const sp = await runShotsPass2({
|
|
178392
179001
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
178393
179002
|
tokens: outcome.tokens,
|
|
178394
|
-
outDir:
|
|
179003
|
+
outDir: join81(dir, ".himi", "shots"),
|
|
178395
179004
|
width: 390,
|
|
178396
179005
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
178397
179006
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -178431,7 +179040,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178431
179040
|
releaseId: result.releaseId,
|
|
178432
179041
|
releasePayload: release2,
|
|
178433
179042
|
descriptors: attestedDescriptors,
|
|
178434
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
179043
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join81(dir, ".himi", "shots", name)])),
|
|
178435
179044
|
coverage: {
|
|
178436
179045
|
screens: crawledScreens.size,
|
|
178437
179046
|
actionsDispatched: result.actions.exercised,
|
|
@@ -178556,7 +179165,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178556
179165
|
return 2;
|
|
178557
179166
|
}
|
|
178558
179167
|
try {
|
|
178559
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
179168
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync97(stateArg.replace(/^@/, ""), "utf8");
|
|
178560
179169
|
injectedState = JSON.parse(raw);
|
|
178561
179170
|
} catch (e2) {
|
|
178562
179171
|
io2.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e2.message}` }));
|
|
@@ -178571,7 +179180,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178571
179180
|
return 2;
|
|
178572
179181
|
}
|
|
178573
179182
|
try {
|
|
178574
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
179183
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync97(inputArg.replace(/^@/, ""), "utf8");
|
|
178575
179184
|
const parsed = JSON.parse(raw);
|
|
178576
179185
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
178577
179186
|
injectedInput = parsed;
|
|
@@ -178653,7 +179262,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178653
179262
|
const diagnostics = (outcome.lint ?? []).find((s2) => s2.screenId === screenId)?.issues ?? [];
|
|
178654
179263
|
let pngFile;
|
|
178655
179264
|
let attestationPngFile;
|
|
178656
|
-
const shotPath =
|
|
179265
|
+
const shotPath = join81(dir, ".himi", "shots", `${screenId}.png`);
|
|
178657
179266
|
const pngTarget = typeof flags.png === "string" ? str9(flags.png) : flags.png === true ? shotPath : void 0;
|
|
178658
179267
|
if (pngTarget && r2.pngBase64) {
|
|
178659
179268
|
pngFile = writePngFile(pngTarget, r2.pngBase64);
|
|
@@ -179012,7 +179621,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179012
179621
|
io2.error(JSON.stringify(linked));
|
|
179013
179622
|
return 1;
|
|
179014
179623
|
}
|
|
179015
|
-
if (
|
|
179624
|
+
if (existsSync80(dest)) {
|
|
179016
179625
|
if (!statSync21(dest).isDirectory()) {
|
|
179017
179626
|
io2.error(JSON.stringify({
|
|
179018
179627
|
error: `${dest} exists and is not a directory`,
|
|
@@ -179025,7 +179634,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179025
179634
|
io2.error(JSON.stringify({ error: `${dest} already exists and is not empty`, hint: "pass --force to write into it anyway (merging, and naming what it keeps), --replace to restore exactly what was archived, or --out/--name to land somewhere else" }));
|
|
179026
179635
|
return 1;
|
|
179027
179636
|
}
|
|
179028
|
-
if (replace && occupied && !
|
|
179637
|
+
if (replace && occupied && !existsSync80(join81(dest, "himalaya.content.json"))) {
|
|
179029
179638
|
io2.error(JSON.stringify({
|
|
179030
179639
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
179031
179640
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -179223,9 +179832,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179223
179832
|
})));
|
|
179224
179833
|
return 1;
|
|
179225
179834
|
}
|
|
179226
|
-
const
|
|
179227
|
-
if (!
|
|
179228
|
-
io2.error(JSON.stringify(pushFailure2("invalid_patch",
|
|
179835
|
+
const planned2 = planFromPayload2(payload, baseForPlan.manifest, parsed.selectors);
|
|
179836
|
+
if (!planned2.ok) {
|
|
179837
|
+
io2.error(JSON.stringify(pushFailure2("invalid_patch", planned2.error), null, 2));
|
|
179229
179838
|
return 1;
|
|
179230
179839
|
}
|
|
179231
179840
|
const patchUxEvidence = handoverUxEvidence(dir, {
|
|
@@ -179262,7 +179871,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179262
179871
|
return runReleasePatch({
|
|
179263
179872
|
door: "push --only",
|
|
179264
179873
|
app,
|
|
179265
|
-
plan:
|
|
179874
|
+
plan: planned2.plan,
|
|
179266
179875
|
draft: onlyDraft,
|
|
179267
179876
|
// PIN the base that was actually validated. Passing `fromRelease` only when the user
|
|
179268
179877
|
// named one would let `runReleasePatch` resolve "current" a SECOND time, so a publish
|
|
@@ -179733,7 +180342,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179733
180342
|
}
|
|
179734
180343
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
179735
180344
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
179736
|
-
const built = mkdtempSync5(
|
|
180345
|
+
const built = mkdtempSync5(join81(tmpdir6(), "himi-pack-"));
|
|
179737
180346
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
179738
180347
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
179739
180348
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -179940,7 +180549,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179940
180549
|
}));
|
|
179941
180550
|
return 1;
|
|
179942
180551
|
}
|
|
179943
|
-
const archive =
|
|
180552
|
+
const archive = readFileSync97(resolve60(file2));
|
|
179944
180553
|
const result = await client2().createPackageShare({
|
|
179945
180554
|
app: opened.header.app,
|
|
179946
180555
|
releaseId: opened.header.releaseId,
|
|
@@ -180037,11 +180646,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180037
180646
|
const app = await appId(dir2);
|
|
180038
180647
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
180039
180648
|
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
180040
|
-
temp = mkdtempSync5(
|
|
180649
|
+
temp = mkdtempSync5(join81(tmpdir6(), "himi-run-build-"));
|
|
180041
180650
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
180042
180651
|
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
180043
180652
|
servedMissing = initial.missingBundles;
|
|
180044
|
-
source =
|
|
180653
|
+
source = join81(temp, app);
|
|
180045
180654
|
}
|
|
180046
180655
|
const chromeArg = str9(flags.chrome) ?? "preview";
|
|
180047
180656
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -180080,7 +180689,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180080
180689
|
if (!recordKit) return;
|
|
180081
180690
|
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
180082
180691
|
const failure = record2(served2, { ok: true, at: startedAt });
|
|
180083
|
-
if (!recorded) io2.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${
|
|
180692
|
+
if (!recorded) io2.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${join81(dir, ".himi")} is not a real directory`}, so the build board will not frame this preview.` }));
|
|
180084
180693
|
await refreshBoard();
|
|
180085
180694
|
};
|
|
180086
180695
|
const retract = async () => {
|
|
@@ -180116,7 +180725,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180116
180725
|
const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
180117
180726
|
const hhpPreviewRoute = watch2 ? (await Promise.resolve().then(() => (init_hhp_preview(), hhp_preview_exports))).hhpPreviewResponse : null;
|
|
180118
180727
|
const bus = watchKit ? new watchKit.ReloadBus() : void 0;
|
|
180119
|
-
if (watch2) served = mkdtempSync5(
|
|
180728
|
+
if (watch2) served = mkdtempSync5(join81(tmpdir6(), "himi-run-served-"));
|
|
180120
180729
|
const running = await runPackage2(source, {
|
|
180121
180730
|
port,
|
|
180122
180731
|
chrome: chromeArg,
|
|
@@ -180145,10 +180754,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180145
180754
|
await announce(running);
|
|
180146
180755
|
if (watchKit && bus) {
|
|
180147
180756
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
180148
|
-
const live3 =
|
|
180149
|
-
const manifestOf = (tree) => JSON.parse(
|
|
180757
|
+
const live3 = join81(running.releaseRoot, running.app);
|
|
180758
|
+
const manifestOf = (tree) => JSON.parse(readFileSync97(join81(tree, "release-manifest.json"), "utf8"));
|
|
180150
180759
|
let current = manifestOf(live3);
|
|
180151
|
-
const
|
|
180760
|
+
const failed3 = async (message) => {
|
|
180152
180761
|
if (stopping) return;
|
|
180153
180762
|
bus.publish("build.failed", { message });
|
|
180154
180763
|
record2(running, { ok: false, at: (/* @__PURE__ */ new Date()).toISOString(), error: message });
|
|
@@ -180157,33 +180766,33 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180157
180766
|
};
|
|
180158
180767
|
rebuild = watchKit.serialize(async () => {
|
|
180159
180768
|
const t0 = Date.now();
|
|
180160
|
-
const next = mkdtempSync5(
|
|
180769
|
+
const next = mkdtempSync5(join81(tmpdir6(), "himi-run-build-"));
|
|
180161
180770
|
try {
|
|
180162
180771
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
180163
180772
|
if (bres.compileErrors.length) {
|
|
180164
180773
|
const first = bres.compileErrors[0];
|
|
180165
180774
|
const diag = first.errors[0];
|
|
180166
|
-
await
|
|
180775
|
+
await failed3(`${first.bundle}: ${diag ? `${diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ""} ` : ""}${diag.text}` : "did not compile"}`);
|
|
180167
180776
|
return;
|
|
180168
180777
|
}
|
|
180169
180778
|
const hasWorkers = bres.built.length > 0;
|
|
180170
180779
|
const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, freshModule: true });
|
|
180171
180780
|
const blocker = watchKit.rebuildBlocker(outcome, servedMissing);
|
|
180172
180781
|
if (blocker) {
|
|
180173
|
-
await
|
|
180782
|
+
await failed3(blocker);
|
|
180174
180783
|
return;
|
|
180175
180784
|
}
|
|
180176
180785
|
if (stopping) return;
|
|
180177
|
-
const fresh = manifestOf(
|
|
180786
|
+
const fresh = manifestOf(join81(next, running.app));
|
|
180178
180787
|
const diff = watchKit.diffReleases(current, fresh);
|
|
180179
180788
|
const { describeChanges: describeChanges2, headline: headline2 } = await Promise.resolve().then(() => (init_build_changes(), build_changes_exports));
|
|
180180
|
-
const changes = describeChanges2(live3,
|
|
180789
|
+
const changes = describeChanges2(live3, join81(next, running.app), diff);
|
|
180181
180790
|
const retired = `${live3}.retired-${Date.now()}`;
|
|
180182
180791
|
renameSync12(live3, retired);
|
|
180183
180792
|
try {
|
|
180184
|
-
renameSync12(
|
|
180793
|
+
renameSync12(join81(next, running.app), live3);
|
|
180185
180794
|
} catch {
|
|
180186
|
-
cpSync3(
|
|
180795
|
+
cpSync3(join81(next, running.app), live3, { recursive: true });
|
|
180187
180796
|
}
|
|
180188
180797
|
rmSync22(retired, { recursive: true, force: true });
|
|
180189
180798
|
current = fresh;
|
|
@@ -180193,7 +180802,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180193
180802
|
await refreshBoard();
|
|
180194
180803
|
io2.error(JSON.stringify({ watch: "rebuilt", ms: Date.now() - t0, screens: diff.screens, tokens: diff.tokens, config: diff.config, ...changes.items.length ? { changed: headline2(changes), changes } : {}, tabs: bus.listeners }));
|
|
180195
180804
|
} catch (e2) {
|
|
180196
|
-
await
|
|
180805
|
+
await failed3(e2.message.split("\n")[0]);
|
|
180197
180806
|
} finally {
|
|
180198
180807
|
rmSync22(next, { recursive: true, force: true });
|
|
180199
180808
|
}
|
|
@@ -180810,7 +181419,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180810
181419
|
io2.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
180811
181420
|
return 2;
|
|
180812
181421
|
}
|
|
180813
|
-
if (!
|
|
181422
|
+
if (!existsSync80(file2)) {
|
|
180814
181423
|
io2.error(JSON.stringify({ error: `no such file: ${file2}` }));
|
|
180815
181424
|
return 2;
|
|
180816
181425
|
}
|
|
@@ -180866,7 +181475,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180866
181475
|
lintNote: "`himi patch` sends a raw file. Nothing here built or linted your app \u2014 `himi push --only <selector>` is the same edit with the full lint gate in front of it."
|
|
180867
181476
|
};
|
|
180868
181477
|
if (kind === "tokens" || kind === "app-config") {
|
|
180869
|
-
const body =
|
|
181478
|
+
const body = readFileSync97(file2, "utf8");
|
|
180870
181479
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
180871
181480
|
return runReleasePatch({
|
|
180872
181481
|
...common,
|
|
@@ -180881,7 +181490,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180881
181490
|
io2.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
180882
181491
|
return 2;
|
|
180883
181492
|
}
|
|
180884
|
-
const descriptor =
|
|
181493
|
+
const descriptor = readFileSync97(file2, "utf8");
|
|
180885
181494
|
try {
|
|
180886
181495
|
JSON.parse(descriptor);
|
|
180887
181496
|
} catch (e2) {
|
|
@@ -180921,7 +181530,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180921
181530
|
extra: { kind, screen: id, file: { path: file2, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
180922
181531
|
});
|
|
180923
181532
|
}
|
|
180924
|
-
const bytes2 =
|
|
181533
|
+
const bytes2 = readFileSync97(file2);
|
|
180925
181534
|
const sha2 = createHash41("sha256").update(bytes2).digest("hex");
|
|
180926
181535
|
const forScreens = (str9(flags["for-screen"]) ?? "").split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
180927
181536
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
@@ -181065,7 +181674,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181065
181674
|
}
|
|
181066
181675
|
let def;
|
|
181067
181676
|
try {
|
|
181068
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
181677
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync97(arg.slice(1), "utf8") : arg);
|
|
181069
181678
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
181070
181679
|
io2.error(JSON.stringify({ error: "invalid_definition", problems: [`--definition must be a JSON object, got ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`] }));
|
|
181071
181680
|
return 2;
|
|
@@ -181212,7 +181821,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181212
181821
|
case "testflight": {
|
|
181213
181822
|
if (command === "store" && pos[1] === "iap") {
|
|
181214
181823
|
const { runStoreIap: runStoreIap2, defaultStoreIapDeps: defaultStoreIapDeps2 } = await Promise.resolve().then(() => (init_store_iap(), store_iap_exports));
|
|
181215
|
-
return runStoreIap2(pos, flags, io2, defaultStoreIapDeps2());
|
|
181824
|
+
return runStoreIap2(pos, flags, io2, { ...defaultStoreIapDeps2(), validateConfig: createTrimValidator(deps) });
|
|
181216
181825
|
}
|
|
181217
181826
|
if (str9(flags.provider) === "wix-mobile-release") {
|
|
181218
181827
|
const playerTarget = wixPlayerTestflightTarget(str9(flags.target));
|
|
@@ -181347,7 +181956,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181347
181956
|
const rememberLastDist = async (jobs2) => {
|
|
181348
181957
|
try {
|
|
181349
181958
|
const dir = contentDir(flags);
|
|
181350
|
-
if (!
|
|
181959
|
+
if (!existsSync80(join81(dir, "himalaya.content.json"))) return;
|
|
181351
181960
|
const { lastDistFromJob: lastDistFromJob2, writeLastDist: writeLastDist2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
|
|
181352
181961
|
const own4 = await appId(dir);
|
|
181353
181962
|
for (const job of jobs2) {
|
|
@@ -181585,7 +182194,7 @@ ${label2}`);
|
|
|
181585
182194
|
const platform = str9(flags.platform)?.split(",").map((p2) => p2.trim()).filter(Boolean);
|
|
181586
182195
|
{
|
|
181587
182196
|
const distDir = contentDir(flags);
|
|
181588
|
-
if (
|
|
182197
|
+
if (existsSync80(join81(distDir, "himalaya.content.json"))) {
|
|
181589
182198
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
181590
182199
|
const errors = issues.filter((i2) => i2.severity === "error");
|
|
181591
182200
|
for (const i2 of issues.filter((i3) => i3.severity === "warning")) {
|
|
@@ -181924,7 +182533,7 @@ ${label2}`);
|
|
|
181924
182533
|
const dpxPath = dpxSessionTokenPath();
|
|
181925
182534
|
let dpx;
|
|
181926
182535
|
try {
|
|
181927
|
-
dpx =
|
|
182536
|
+
dpx = readFileSync97(dpxPath, "utf8").trim();
|
|
181928
182537
|
} catch {
|
|
181929
182538
|
io2.error(JSON.stringify({ error: `no dpx session at ${dpxPath} \u2014 run \`dpx auth login\` then \`dpx auth token > ${dpxPath}\` (dpx 2.x keeps its own state in ~/.dpx/auth.json and does NOT write the legacy session file), or omit --dpx` }));
|
|
181930
182539
|
return 1;
|
|
@@ -182345,7 +182954,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
|
|
|
182345
182954
|
const path2 = dpxSessionTokenPath();
|
|
182346
182955
|
let raw;
|
|
182347
182956
|
try {
|
|
182348
|
-
raw =
|
|
182957
|
+
raw = readFileSync97(path2, "utf8");
|
|
182349
182958
|
} catch {
|
|
182350
182959
|
io2.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
182351
182960
|
return 1;
|