@wix/himalaya-cli 0.1310.0 → 0.1312.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/wix-payments-contract.d.ts +20 -1
- 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/iap.mjs +8 -0
- package/dist/cli.mjs +1321 -692
- 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/sdk-reference.json +19 -1
- package/guides/web-page-native-sdk.md +18 -8
- package/guides/webview-page-sdk.md +9 -3
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +25 -25
- package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/beauty-salon/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/beauty-salon-owner/dev/index.ts +844 -510
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/beauty-salon-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/branded-lite/dev/index.ts +120 -120
- package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/branded-lite/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/community-club/dev/index.ts +20 -20
- package/templates/community-club/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/community-club/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/community-club-owner/dev/index.ts +957 -595
- package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/community-club-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/community-club-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/events-meetups/dev/index.ts +15 -15
- package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/events-meetups/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/events-meetups-owner/dev/index.ts +726 -433
- package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/events-meetups-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/events-meetups-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/gym-fitness/dev/index.ts +30 -30
- package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/gym-fitness/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/gym-fitness-owner/dev/index.ts +1041 -644
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/gym-fitness-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/nonprofit-cause/dev/index.ts +20 -20
- package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/nonprofit-cause/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +810 -482
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/nonprofit-cause-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/owner-lite/dev/index.ts +1066 -648
- package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/owner-lite/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/owner-lite/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/owner-lite/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/podcast-creator/dev/index.ts +20 -20
- package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/podcast-creator/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/podcast-creator-owner/dev/index.ts +957 -595
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/podcast-creator-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/portfolio-creative/dev/index.ts +20 -20
- package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/portfolio-creative/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/portfolio-creative-owner/dev/index.ts +844 -510
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/portfolio-creative-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/restaurant/dev/index.ts +15 -15
- package/templates/restaurant/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/restaurant/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/restaurant-owner/dev/index.ts +1041 -644
- package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/restaurant-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/restaurant-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
- package/templates/retail-store/dev/index.ts +10 -10
- package/templates/retail-store/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/retail-store/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/retail-store-owner/dev/index.ts +760 -461
- package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/retail-store-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/retail-store-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/retail-store-owner/tier5-src/_shared/offset-page.ts +10 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/yoga-studio/dev/index.ts +30 -30
- package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/yoga-studio/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/yoga-studio-owner/dev/index.ts +810 -482
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +10 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-service.ts +3 -1
- package/templates/yoga-studio-owner/tier5-src/_shared/detail-facts.ts +26 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
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
|
});
|
|
@@ -7586,7 +7586,6 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
|
|
|
7586
7586
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
7587
7587
|
var init_bindings = __esm({
|
|
7588
7588
|
"../../core/ts/src/bindings.ts"() {
|
|
7589
|
-
"use strict";
|
|
7590
7589
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
7591
7590
|
BINDING_SIGIL_RE = new RegExp(
|
|
7592
7591
|
`^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -10357,11 +10356,11 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
10357
10356
|
}
|
|
10358
10357
|
message = typeof asJson === "string" ? asJson : String(raw);
|
|
10359
10358
|
} else message = String(raw);
|
|
10360
|
-
const
|
|
10361
|
-
if (prev.status === "loading")
|
|
10362
|
-
if (prev.loading === true)
|
|
10363
|
-
if (typeof prev.error === "string")
|
|
10364
|
-
def.state =
|
|
10359
|
+
const failed3 = { ...prev, _error: message };
|
|
10360
|
+
if (prev.status === "loading") failed3.status = "error";
|
|
10361
|
+
if (prev.loading === true) failed3.loading = false;
|
|
10362
|
+
if (typeof prev.error === "string") failed3.error = message;
|
|
10363
|
+
def.state = failed3;
|
|
10365
10364
|
};
|
|
10366
10365
|
const runAction = async (def, label2, fn2, args) => {
|
|
10367
10366
|
let timer;
|
|
@@ -18563,9 +18562,9 @@ async function offRepoFontBytes(plan, opts = {}) {
|
|
|
18563
18562
|
out2.hostProvided.push(r2.family);
|
|
18564
18563
|
continue;
|
|
18565
18564
|
}
|
|
18566
|
-
const
|
|
18567
|
-
if (
|
|
18568
|
-
out2.unavailable.push({ family: r2.family, reason:
|
|
18565
|
+
const failed3 = r2.faces.find((f2) => !f2.got.ok);
|
|
18566
|
+
if (failed3 && !failed3.got.ok) {
|
|
18567
|
+
out2.unavailable.push({ family: r2.family, reason: failed3.got.reason });
|
|
18569
18568
|
continue;
|
|
18570
18569
|
}
|
|
18571
18570
|
out2.ready.push({
|
|
@@ -37156,9 +37155,9 @@ var init_presigned_upload_policy = __esm({
|
|
|
37156
37155
|
function mediaFieldName(label2) {
|
|
37157
37156
|
return typeof label2 === "string" && label2.trim() !== "" ? label2 : MEDIA_FIELD_DEFAULT_LABEL;
|
|
37158
37157
|
}
|
|
37159
|
-
function mediaFieldState(uploading, hasPhoto,
|
|
37158
|
+
function mediaFieldState(uploading, hasPhoto, failed3 = false) {
|
|
37160
37159
|
if (uploading) return "Uploading";
|
|
37161
|
-
if (
|
|
37160
|
+
if (failed3) return MEDIA_FIELD_UPLOAD_FAILED;
|
|
37162
37161
|
return hasPhoto ? "Photo added" : void 0;
|
|
37163
37162
|
}
|
|
37164
37163
|
function mediaFieldServicePath(valuePath) {
|
|
@@ -42270,7 +42269,7 @@ var init_pdf = __esm({
|
|
|
42270
42269
|
var defineProperty = Object.defineProperty;
|
|
42271
42270
|
var stringSlice = uncurryThis("".slice);
|
|
42272
42271
|
var replace = uncurryThis("".replace);
|
|
42273
|
-
var
|
|
42272
|
+
var join82 = uncurryThis([].join);
|
|
42274
42273
|
var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
|
|
42275
42274
|
return defineProperty(function() {
|
|
42276
42275
|
}, "length", { value: 8 }).length !== 8;
|
|
@@ -42297,7 +42296,7 @@ var init_pdf = __esm({
|
|
|
42297
42296
|
}
|
|
42298
42297
|
var state = enforceInternalState(value);
|
|
42299
42298
|
if (!hasOwn(state, "source")) {
|
|
42300
|
-
state.source =
|
|
42299
|
+
state.source = join82(TEMPLATE, typeof name == "string" ? name : "");
|
|
42301
42300
|
}
|
|
42302
42301
|
return value;
|
|
42303
42302
|
};
|
|
@@ -44820,7 +44819,7 @@ var init_pdf = __esm({
|
|
|
44820
44819
|
var charAt = uncurryThis("".charAt);
|
|
44821
44820
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
44822
44821
|
var $Array = globalThis2.Array;
|
|
44823
|
-
var
|
|
44822
|
+
var join82 = uncurryThis([].join);
|
|
44824
44823
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toBase64 || !(function() {
|
|
44825
44824
|
try {
|
|
44826
44825
|
var target = new Uint8Array2();
|
|
@@ -44866,7 +44865,7 @@ var init_pdf = __esm({
|
|
|
44866
44865
|
result[written++] = "=";
|
|
44867
44866
|
}
|
|
44868
44867
|
}
|
|
44869
|
-
return
|
|
44868
|
+
return join82(result, "");
|
|
44870
44869
|
}
|
|
44871
44870
|
});
|
|
44872
44871
|
},
|
|
@@ -44878,7 +44877,7 @@ var init_pdf = __esm({
|
|
|
44878
44877
|
var anUint8Array = __webpack_require__3(4154);
|
|
44879
44878
|
var notDetached = __webpack_require__3(5169);
|
|
44880
44879
|
var numberToString2 = uncurryThis(1.1.toString);
|
|
44881
|
-
var
|
|
44880
|
+
var join82 = uncurryThis([].join);
|
|
44882
44881
|
var $Array = Array;
|
|
44883
44882
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
44884
44883
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toHex || !(function() {
|
|
@@ -44898,7 +44897,7 @@ var init_pdf = __esm({
|
|
|
44898
44897
|
var hex2 = numberToString2(this[i2], 16);
|
|
44899
44898
|
result[i2] = hex2.length === 1 ? "0" + hex2 : hex2;
|
|
44900
44899
|
}
|
|
44901
|
-
return
|
|
44900
|
+
return join82(result, "");
|
|
44902
44901
|
}
|
|
44903
44902
|
});
|
|
44904
44903
|
},
|
|
@@ -119637,7 +119636,7 @@ function PdfDocument({ src, nativeSrc, title, height, startPage, zoomPercent, st
|
|
|
119637
119636
|
const [pages2, setPages] = React8.useState(0);
|
|
119638
119637
|
const [failedRequest, setFailedRequest] = React8.useState(null);
|
|
119639
119638
|
const request = JSON.stringify([src, startPage, zoomPercent]);
|
|
119640
|
-
const
|
|
119639
|
+
const failed3 = failedRequest === request;
|
|
119641
119640
|
const containerRef = React8.useRef(null);
|
|
119642
119641
|
React8.useEffect(() => {
|
|
119643
119642
|
let live3 = true;
|
|
@@ -119681,7 +119680,7 @@ function PdfDocument({ src, nativeSrc, title, height, startPage, zoomPercent, st
|
|
|
119681
119680
|
// PDF pages need their own scroll viewport so every page remains reachable.
|
|
119682
119681
|
overflow: "auto"
|
|
119683
119682
|
};
|
|
119684
|
-
if (
|
|
119683
|
+
if (failed3) {
|
|
119685
119684
|
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 });
|
|
119686
119685
|
}
|
|
119687
119686
|
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: [
|
|
@@ -122776,12 +122775,12 @@ var init_renderNode = __esm({
|
|
|
122776
122775
|
const bound = useBoundValue(ctx, servicePathStr ? String(props.valuePath) : "");
|
|
122777
122776
|
const imageUrl = typeof bound === "string" ? bound : "";
|
|
122778
122777
|
const [uploading, setUploading] = React9.useState(false);
|
|
122779
|
-
const [
|
|
122778
|
+
const [failed3, setFailed] = React9.useState(false);
|
|
122780
122779
|
const fileRef = React9.useRef(null);
|
|
122781
122780
|
const uploadService = typeof props.uploadService === "string" ? props.uploadService : "";
|
|
122782
122781
|
const resolvedLabel = asText2(resolveScalarStatic(props.label, ctx));
|
|
122783
122782
|
const name = mediaFieldName(resolvedLabel);
|
|
122784
|
-
const state = mediaFieldState(uploading, imageUrl !== "",
|
|
122783
|
+
const state = mediaFieldState(uploading, imageUrl !== "", failed3);
|
|
122785
122784
|
const open = () => {
|
|
122786
122785
|
if (!uploading) fileRef.current?.click();
|
|
122787
122786
|
};
|
|
@@ -122837,7 +122836,7 @@ var init_renderNode = __esm({
|
|
|
122837
122836
|
/* @__PURE__ */ jsx10("span", { style: { fontFamily: fontStack(f2.family, ctx.idiom), fontWeight: f2.weight, fontSize: f2.remSize }, children: name })
|
|
122838
122837
|
] }),
|
|
122839
122838
|
uploading ? /* @__PURE__ */ jsx10("div", { "aria-hidden": "true", "data-media-uploading": "true", style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.35)" } }) : null,
|
|
122840
|
-
|
|
122839
|
+
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
|
|
122841
122840
|
]
|
|
122842
122841
|
}
|
|
122843
122842
|
);
|
|
@@ -123279,7 +123278,8 @@ var init_renderNode = __esm({
|
|
|
123279
123278
|
};
|
|
123280
123279
|
}, [open]);
|
|
123281
123280
|
const modal = isOverlayModal("Menu", props.modal);
|
|
123282
|
-
const
|
|
123281
|
+
const rawAnchorLabel = props.anchor?.modifiers?.accessibilityLabel;
|
|
123282
|
+
const anchorLabel = String((typeof rawAnchorLabel === "string" && rawAnchorLabel.startsWith("$item") ? resolveItemDeep2(rawAnchorLabel, ctx) : rawAnchorLabel) || "More actions");
|
|
123283
123283
|
const flexGrow = typeof wrap?.flex === "string" ? parseFloat(wrap.flex) : typeof wrap?.flex === "number" ? wrap.flex : Number(wrap?.flexGrow ?? 0);
|
|
123284
123284
|
const fill = wrap?.width === "100%" || Number.isFinite(flexGrow) && flexGrow > 0;
|
|
123285
123285
|
const popupPlacement = fill ? { position: "absolute", top: "100%", left: 0, right: 0, zIndex: 20, marginTop: 4 } : { position: "absolute", top: "100%", right: 0, zIndex: 20, marginTop: 4 };
|
|
@@ -127770,13 +127770,13 @@ async function pngFontFaceCss(tokens2, opts = {}) {
|
|
|
127770
127770
|
for (const [name, family] of Object.entries(catalog3.bundled)) {
|
|
127771
127771
|
for (const face of family.faces) want(name, face, family.variable);
|
|
127772
127772
|
}
|
|
127773
|
-
let
|
|
127773
|
+
let planned2 = [];
|
|
127774
127774
|
try {
|
|
127775
|
-
|
|
127775
|
+
planned2 = planFonts(tokens2 ?? {}, { families: declaredFamilies(tokens2) }, catalog3).families;
|
|
127776
127776
|
} catch {
|
|
127777
|
-
|
|
127777
|
+
planned2 = [];
|
|
127778
127778
|
}
|
|
127779
|
-
for (const family of
|
|
127779
|
+
for (const family of planned2) {
|
|
127780
127780
|
if (family.builtin) continue;
|
|
127781
127781
|
for (const face of family.faces) want(family.name, face, family.variable);
|
|
127782
127782
|
}
|
|
@@ -128993,6 +128993,9 @@ import { readFileSync as readFileSync49, existsSync as existsSync45, watch, mkdi
|
|
|
128993
128993
|
import { basename as basename10, dirname as dirname28, extname as extname2, join as join44, relative as relative8, resolve as resolve37, normalize as normalize3, sep as sep10 } from "node:path";
|
|
128994
128994
|
import { createHash as createHash20, randomUUID as randomUUID5 } from "node:crypto";
|
|
128995
128995
|
import { fileURLToPath as fileURLToPath20, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
128996
|
+
function readLogicBundle(read, tier5Dir, name) {
|
|
128997
|
+
return read(tier5Dir ?? TIER5_ROOT2, name) ?? (tier5Dir && tier5Dir !== TIER5_ROOT2 ? read(TIER5_ROOT2, name) : void 0);
|
|
128998
|
+
}
|
|
128996
128999
|
function deepMerge3(base, patch) {
|
|
128997
129000
|
if (patch === null || typeof patch !== "object" || Array.isArray(patch)) return patch;
|
|
128998
129001
|
const out2 = Array.isArray(base) ? [...base] : { ...base };
|
|
@@ -129145,7 +129148,7 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
129145
129148
|
const nativeActions = await nativeActionsFor(state);
|
|
129146
129149
|
const lb = descriptor.logicBundle;
|
|
129147
129150
|
const bundleName = lb?.url ? /\/v1\/bundles\/([A-Za-z0-9_-]+)/.exec(lb.url)?.[1] : void 0;
|
|
129148
|
-
const bundleJs = bundleName ? readBuiltBundle2
|
|
129151
|
+
const bundleJs = bundleName ? readLogicBundle(readBuiltBundle2, state.tier5Dir, bundleName) : void 0;
|
|
129149
129152
|
const appWorkerActions = appWorkerActionsFor2(
|
|
129150
129153
|
state.app?.module.config,
|
|
129151
129154
|
state.tier5Dir ?? TIER5_ROOT2
|
|
@@ -131052,7 +131055,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
131052
131055
|
const nativeActions = await nativeActionsFor(state);
|
|
131053
131056
|
const lb = descriptor.logicBundle;
|
|
131054
131057
|
const bundleName = lb?.url ? /\/v1\/bundles\/([A-Za-z0-9_-]+)/.exec(lb.url)?.[1] : void 0;
|
|
131055
|
-
const bundleJs = bundleName ? readBuiltBundle2
|
|
131058
|
+
const bundleJs = bundleName ? readLogicBundle(readBuiltBundle2, state.tier5Dir, bundleName) : void 0;
|
|
131056
131059
|
const appWorkerActions = appWorkerActionsFor2(
|
|
131057
131060
|
state.app?.module.config,
|
|
131058
131061
|
state.tier5Dir ?? TIER5_ROOT2
|
|
@@ -135696,6 +135699,20 @@ function readTokensForLint(preloaded) {
|
|
|
135696
135699
|
async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
135697
135700
|
const app = preloaded.name;
|
|
135698
135701
|
const tier5Dir = opts.tier5Dir ?? TIER5_DIR;
|
|
135702
|
+
const bundlePath = (name) => {
|
|
135703
|
+
const own4 = join45(tier5Dir, `${name}.bundle.js`);
|
|
135704
|
+
if (existsSync46(own4)) return own4;
|
|
135705
|
+
const shared = join45(TIER5_DIR, `${name}.bundle.js`);
|
|
135706
|
+
return resolve38(tier5Dir) !== TIER5_DIR && existsSync46(shared) ? shared : void 0;
|
|
135707
|
+
};
|
|
135708
|
+
const bundleDirFor = (name) => {
|
|
135709
|
+
const path2 = name ? bundlePath(name) : void 0;
|
|
135710
|
+
return path2 ? dirname29(path2) : tier5Dir;
|
|
135711
|
+
};
|
|
135712
|
+
const readBundle = (name) => {
|
|
135713
|
+
const path2 = bundlePath(name);
|
|
135714
|
+
return path2 ? readFileSync50(path2, "utf8") : void 0;
|
|
135715
|
+
};
|
|
135699
135716
|
const collect2 = opts.collect;
|
|
135700
135717
|
const config = preloaded.module.config;
|
|
135701
135718
|
if (isFunctionsOnlyConfig(config)) {
|
|
@@ -135773,7 +135790,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
135773
135790
|
let mockBootFailed;
|
|
135774
135791
|
let mockUnserved;
|
|
135775
135792
|
if (collect2?.render?.live) {
|
|
135776
|
-
const bundleJs = bundleName ?
|
|
135793
|
+
const bundleJs = bundleName ? readBundle(bundleName) : void 0;
|
|
135777
135794
|
if (!bundleJs) {
|
|
135778
135795
|
base2 = null;
|
|
135779
135796
|
} else {
|
|
@@ -135790,14 +135807,14 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
135790
135807
|
liveReturned = counting.returned();
|
|
135791
135808
|
liveErrors = live3.errors;
|
|
135792
135809
|
}
|
|
135793
|
-
} else if (collect2?.render?.mocks && collect2.render.hydrate !== false && bundleName &&
|
|
135810
|
+
} else if (collect2?.render?.mocks && collect2.render.hydrate !== false && bundleName && readBundle(bundleName)) {
|
|
135794
135811
|
const calls = [];
|
|
135795
135812
|
const unserved = [];
|
|
135796
135813
|
const snap = await bootAndSnapshotState({
|
|
135797
135814
|
screenId: renderedScreenId ?? String(descriptor?.screenId ?? bundleName),
|
|
135798
135815
|
// `--input` rides on the descriptor's own input, as a navigator hands it over.
|
|
135799
135816
|
descriptor: collect2.render.input && descriptor && typeof descriptor === "object" ? { ...descriptor, input } : descriptor,
|
|
135800
|
-
bundleJs:
|
|
135817
|
+
bundleJs: readBundle(bundleName),
|
|
135801
135818
|
knownScreenIds: /* @__PURE__ */ new Set(),
|
|
135802
135819
|
rules: collect2.render.mocks.rules ?? null,
|
|
135803
135820
|
...collect2.render.mocks.cmsSeed ? { cmsSeed: collect2.render.mocks.cmsSeed } : {},
|
|
@@ -135820,11 +135837,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
135820
135837
|
mockUnserved = unserved;
|
|
135821
135838
|
} else {
|
|
135822
135839
|
mockBootFailed = true;
|
|
135823
|
-
base2 = hydrationServices(
|
|
135840
|
+
base2 = hydrationServices(bundleDirFor(bundleName), bundleName, input);
|
|
135824
135841
|
}
|
|
135825
135842
|
} else {
|
|
135826
135843
|
base2 = collect2?.render?.hydrate === false ? null : hydrationServices(
|
|
135827
|
-
|
|
135844
|
+
bundleDirFor(bundleName),
|
|
135828
135845
|
bundleName,
|
|
135829
135846
|
input
|
|
135830
135847
|
);
|
|
@@ -135879,7 +135896,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
135879
135896
|
if (addrCache.has(name)) return addrCache.get(name);
|
|
135880
135897
|
let bytes2;
|
|
135881
135898
|
try {
|
|
135882
|
-
|
|
135899
|
+
const path2 = bundlePath(name);
|
|
135900
|
+
if (!path2) return null;
|
|
135901
|
+
bytes2 = readFileSync50(path2);
|
|
135883
135902
|
} catch {
|
|
135884
135903
|
return null;
|
|
135885
135904
|
}
|
|
@@ -136106,12 +136125,12 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
136106
136125
|
descriptor: JSON.parse(json6),
|
|
136107
136126
|
descriptorJson: json6,
|
|
136108
136127
|
bundleName,
|
|
136109
|
-
bundleJs: bundleName ?
|
|
136128
|
+
bundleJs: bundleName ? readBundle(bundleName) ?? null : null,
|
|
136110
136129
|
...bundleMapFor(tier5Dir, bundleName ?? void 0)
|
|
136111
136130
|
});
|
|
136112
136131
|
}
|
|
136113
136132
|
if (collect2?.lint) {
|
|
136114
|
-
const bundleJs = bundleName ?
|
|
136133
|
+
const bundleJs = bundleName ? readBundle(bundleName) : void 0;
|
|
136115
136134
|
const report3 = validateScreenDescriptor(screenId, descriptor, {
|
|
136116
136135
|
tokens: lintTokens,
|
|
136117
136136
|
allowedComponents,
|
|
@@ -136143,7 +136162,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
136143
136162
|
const lb = logicBundleOf(descriptor);
|
|
136144
136163
|
const bundleName = lb ? bundleNameFromUrl(lb.url) : null;
|
|
136145
136164
|
if (collect2?.lint) {
|
|
136146
|
-
const bundleJs = bundleName ?
|
|
136165
|
+
const bundleJs = bundleName ? readBundle(bundleName) : void 0;
|
|
136147
136166
|
const report3 = validateScreenDescriptor(wantedRender, descriptor, {
|
|
136148
136167
|
tokens: lintTokens,
|
|
136149
136168
|
allowedComponents,
|
|
@@ -136259,7 +136278,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
136259
136278
|
// for ANY of its screens.
|
|
136260
136279
|
descriptorJson: json6,
|
|
136261
136280
|
bundleName,
|
|
136262
|
-
bundleJs: bundleName ?
|
|
136281
|
+
bundleJs: bundleName ? readBundle(bundleName) ?? null : null,
|
|
136263
136282
|
...bundleMapFor(tier5Dir, bundleName ?? void 0)
|
|
136264
136283
|
});
|
|
136265
136284
|
}
|
|
@@ -136365,7 +136384,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
136365
136384
|
if (store.putDoc) {
|
|
136366
136385
|
for (const [name, meta] of Object.entries(bundles)) {
|
|
136367
136386
|
if (name.startsWith("__handlers__")) continue;
|
|
136368
|
-
const js2 =
|
|
136387
|
+
const js2 = readBundle(name);
|
|
136369
136388
|
if (!js2) continue;
|
|
136370
136389
|
try {
|
|
136371
136390
|
const input = bundleInputs.get(name);
|
|
@@ -136432,7 +136451,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
136432
136451
|
if (collect2?.lint) {
|
|
136433
136452
|
for (const name of Object.keys(bundles)) {
|
|
136434
136453
|
if (name.startsWith("__handlers__")) continue;
|
|
136435
|
-
const js2 =
|
|
136454
|
+
const js2 = readBundle(name);
|
|
136436
136455
|
if (!js2) continue;
|
|
136437
136456
|
const input = bundleInputs.get(name);
|
|
136438
136457
|
const drifting = bundles[name]?.servicesHash ? nondeterministicServices(js2, input ? { input } : {}) : [];
|
|
@@ -137294,9 +137313,9 @@ function stateOf(view) {
|
|
|
137294
137313
|
build: b2 && view.live ? { ok: b2.ok, ms: b2.ms, screens: b2.screens, at: b2.at, run: view.live.runId } : null
|
|
137295
137314
|
};
|
|
137296
137315
|
}
|
|
137297
|
-
function frameFor(state, prev,
|
|
137298
|
-
if (key2 || !prev) return { ts:
|
|
137299
|
-
const f2 = { ts:
|
|
137316
|
+
function frameFor(state, prev, ts10, v2, key2) {
|
|
137317
|
+
if (key2 || !prev) return { ts: ts10, v: v2, key: true, ...state };
|
|
137318
|
+
const f2 = { ts: ts10, v: v2 };
|
|
137300
137319
|
if (!same2(state.step, prev.step)) f2.step = state.step;
|
|
137301
137320
|
if (!same2(state.now, prev.now)) f2.now = state.now;
|
|
137302
137321
|
const screens = {};
|
|
@@ -145719,6 +145738,137 @@ var init_hosted_owner = __esm({
|
|
|
145719
145738
|
}
|
|
145720
145739
|
});
|
|
145721
145740
|
|
|
145741
|
+
// src/config-source-edit.ts
|
|
145742
|
+
import { lstatSync as lstatSync14 } from "node:fs";
|
|
145743
|
+
import { join as join50 } from "node:path";
|
|
145744
|
+
import ts5 from "typescript";
|
|
145745
|
+
function defineAppLiteral(file2) {
|
|
145746
|
+
for (const statement of file2.statements) {
|
|
145747
|
+
if (!ts5.isExportAssignment(statement)) continue;
|
|
145748
|
+
const exported = localValue(file2, unwrap(statement.expression));
|
|
145749
|
+
if (ts5.isObjectLiteralExpression(exported)) return exported;
|
|
145750
|
+
const [first] = ts5.isCallExpression(exported) ? exported.arguments : [];
|
|
145751
|
+
return first && ts5.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
|
|
145752
|
+
}
|
|
145753
|
+
return void 0;
|
|
145754
|
+
}
|
|
145755
|
+
function loginOf(app) {
|
|
145756
|
+
const auth = lookup2(app, "auth");
|
|
145757
|
+
if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
|
|
145758
|
+
const value = unwrap(auth.node.initializer);
|
|
145759
|
+
if (ts5.isObjectLiteralExpression(value)) return { kind: "other" };
|
|
145760
|
+
if (!ts5.isCallExpression(value)) return { kind: "opaque" };
|
|
145761
|
+
const provider = calleeName(value);
|
|
145762
|
+
if (provider === "WixOwnerAuthProvider" || provider === "WixAuthProvider") return { kind: "owner" };
|
|
145763
|
+
if (provider === "WixNativeAuthProvider") return nativeMode(value) === "owner" ? { kind: "owner" } : { kind: "other" };
|
|
145764
|
+
if (provider !== "WixConsumerAuthProvider") return { kind: "other" };
|
|
145765
|
+
const [first] = value.arguments;
|
|
145766
|
+
return first && ts5.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
|
|
145767
|
+
}
|
|
145768
|
+
function nativeMode(call) {
|
|
145769
|
+
const [first] = call.arguments;
|
|
145770
|
+
return first && ts5.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
|
|
145771
|
+
}
|
|
145772
|
+
function calleeName(call) {
|
|
145773
|
+
const callee = call.expression;
|
|
145774
|
+
if (ts5.isIdentifier(callee)) return callee.text;
|
|
145775
|
+
return ts5.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
|
|
145776
|
+
}
|
|
145777
|
+
function unwrap(node) {
|
|
145778
|
+
let current = node;
|
|
145779
|
+
while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current)) {
|
|
145780
|
+
current = current.expression;
|
|
145781
|
+
}
|
|
145782
|
+
return current;
|
|
145783
|
+
}
|
|
145784
|
+
function lookup2(literal, name) {
|
|
145785
|
+
let found = { kind: "absent" };
|
|
145786
|
+
for (const p2 of literal.properties) {
|
|
145787
|
+
const key2 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
|
|
145788
|
+
if (ts5.isPropertyAssignment(p2) && key2 === name) found = { kind: "written", node: p2 };
|
|
145789
|
+
else if (ts5.isSpreadAssignment(p2) || p2.name && ts5.isComputedPropertyName(p2.name) || key2 === name) found = { kind: "opaque" };
|
|
145790
|
+
}
|
|
145791
|
+
return found;
|
|
145792
|
+
}
|
|
145793
|
+
function stringValue(node, name) {
|
|
145794
|
+
const literal = unwrap(node);
|
|
145795
|
+
const found = ts5.isObjectLiteralExpression(literal) ? lookup2(literal, name) : void 0;
|
|
145796
|
+
const value = found?.kind === "written" ? found.node.initializer : void 0;
|
|
145797
|
+
return value && ts5.isStringLiteralLike(value) ? value.text : void 0;
|
|
145798
|
+
}
|
|
145799
|
+
function appendProperties(literal, file2, lines) {
|
|
145800
|
+
const inline = () => lines.filter((line) => !line.trimStart().startsWith("//")).join(" ");
|
|
145801
|
+
if (literal.properties.length === 0) {
|
|
145802
|
+
const at3 = literal.getStart(file2) + 1;
|
|
145803
|
+
return { at: at3, end: literal.end - 1, text: ` ${inline().replace(/,$/, "")} ` };
|
|
145804
|
+
}
|
|
145805
|
+
const last = literal.properties[literal.properties.length - 1];
|
|
145806
|
+
const trailing = literal.properties.hasTrailingComma;
|
|
145807
|
+
const at2 = trailing ? literal.properties.end : last.end;
|
|
145808
|
+
const lead = trailing ? "" : ",";
|
|
145809
|
+
if (onOneLine(literal, file2)) {
|
|
145810
|
+
const text9 = inline();
|
|
145811
|
+
return { at: at2, end: at2, text: `${lead} ${trailing ? text9 : text9.replace(/,$/, "")}` };
|
|
145812
|
+
}
|
|
145813
|
+
const indent = lineIndent2(file2.text, last.getStart(file2));
|
|
145814
|
+
return { at: at2, end: at2, text: lead + lines.map((line) => `
|
|
145815
|
+
${indent}${line}`).join("") };
|
|
145816
|
+
}
|
|
145817
|
+
function onOneLine(node, file2) {
|
|
145818
|
+
const line = (position) => file2.getLineAndCharacterOfPosition(position).line;
|
|
145819
|
+
return line(node.getStart(file2)) === line(node.getEnd());
|
|
145820
|
+
}
|
|
145821
|
+
function lineIndent2(text9, position) {
|
|
145822
|
+
const lineStart = text9.lastIndexOf("\n", position - 1) + 1;
|
|
145823
|
+
return /^[ \t]*/.exec(text9.slice(lineStart))[0];
|
|
145824
|
+
}
|
|
145825
|
+
function applySplices(source, splices) {
|
|
145826
|
+
return [...splices].sort((a2, b2) => b2.at - a2.at).reduce((out2, s2) => out2.slice(0, s2.at) + s2.text + out2.slice(s2.end), source);
|
|
145827
|
+
}
|
|
145828
|
+
function localValue(file2, node) {
|
|
145829
|
+
if (!ts5.isIdentifier(node)) return node;
|
|
145830
|
+
for (const statement of file2.statements) {
|
|
145831
|
+
if (!ts5.isVariableStatement(statement) || !(statement.declarationList.flags & ts5.NodeFlags.Const)) continue;
|
|
145832
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
145833
|
+
if (ts5.isIdentifier(declaration.name) && declaration.name.text === node.text && declaration.initializer) return unwrap(declaration.initializer);
|
|
145834
|
+
}
|
|
145835
|
+
}
|
|
145836
|
+
return node;
|
|
145837
|
+
}
|
|
145838
|
+
function backUpConfig(dir, folder, fileName, original) {
|
|
145839
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
145840
|
+
const backupDir = realDirIn(dir, `.himi/${folder}/${stamp}`);
|
|
145841
|
+
if (!backupDir) return void 0;
|
|
145842
|
+
const backup = join50(backupDir, fileName);
|
|
145843
|
+
writeFileAtomic(backup, original);
|
|
145844
|
+
return backup;
|
|
145845
|
+
}
|
|
145846
|
+
function isSymlink2(path2) {
|
|
145847
|
+
try {
|
|
145848
|
+
return lstatSync14(path2).isSymbolicLink();
|
|
145849
|
+
} catch {
|
|
145850
|
+
return false;
|
|
145851
|
+
}
|
|
145852
|
+
}
|
|
145853
|
+
async function introducedErrors(dir, validate4, file2, isOwnFinding) {
|
|
145854
|
+
const edited = await validate4(dir, { fresh: true });
|
|
145855
|
+
if (edited.code === 0) return void 0;
|
|
145856
|
+
if (!comparable(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
|
|
145857
|
+
if (edited.errors.every((e2) => isOwnFinding(e2.ruleCode))) return void 0;
|
|
145858
|
+
file2.restore();
|
|
145859
|
+
const baseline = await validate4(dir, { fresh: true });
|
|
145860
|
+
file2.reapply();
|
|
145861
|
+
if (!comparable(baseline)) return "himi validate could not check the original config.ts to compare against";
|
|
145862
|
+
const introduced = compareErrors(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isOwnFinding(e2.ruleCode));
|
|
145863
|
+
return introduced.length ? `the edit introduced ${introduced.length === 1 ? "an error" : `${introduced.length} errors`}: ` + introduced.map((e2) => e2.message).join("; ") : void 0;
|
|
145864
|
+
}
|
|
145865
|
+
var init_config_source_edit = __esm({
|
|
145866
|
+
"src/config-source-edit.ts"() {
|
|
145867
|
+
init_progress();
|
|
145868
|
+
init_template_trim();
|
|
145869
|
+
}
|
|
145870
|
+
});
|
|
145871
|
+
|
|
145722
145872
|
// src/config-push-edit.ts
|
|
145723
145873
|
var config_push_edit_exports = {};
|
|
145724
145874
|
__export(config_push_edit_exports, {
|
|
@@ -145726,14 +145876,14 @@ __export(config_push_edit_exports, {
|
|
|
145726
145876
|
enablePushInConfig: () => enablePushInConfig,
|
|
145727
145877
|
previewPushConfigEdit: () => previewPushConfigEdit
|
|
145728
145878
|
});
|
|
145729
|
-
import {
|
|
145730
|
-
import { basename as basename13
|
|
145731
|
-
import
|
|
145879
|
+
import { readFileSync as readFileSync58 } from "node:fs";
|
|
145880
|
+
import { basename as basename13 } from "node:path";
|
|
145881
|
+
import ts6 from "typescript";
|
|
145732
145882
|
function enablePushInConfig(source, options) {
|
|
145733
145883
|
const pingAppName = DEFAULT_PING_APP_NAME;
|
|
145734
145884
|
const fileName = options.fileName ?? "config.ts";
|
|
145735
|
-
const kind = fileName.endsWith(".ts") ?
|
|
145736
|
-
const file2 =
|
|
145885
|
+
const kind = fileName.endsWith(".ts") ? ts6.ScriptKind.TS : ts6.ScriptKind.JS;
|
|
145886
|
+
const file2 = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true, kind);
|
|
145737
145887
|
const app = defineAppLiteral(file2);
|
|
145738
145888
|
const named = (instruction) => instruction.replaceAll("config.ts", fileName);
|
|
145739
145889
|
const unchanged = (instruction) => ({ source, changed: false, applied: [], instructions: [named(instruction)], pushOn: false });
|
|
@@ -145785,9 +145935,9 @@ function planPush(app, pingAppName, plan) {
|
|
|
145785
145935
|
}
|
|
145786
145936
|
function planRetiredFamily(block, plan) {
|
|
145787
145937
|
const literal = unwrap(block);
|
|
145788
|
-
const found =
|
|
145938
|
+
const found = ts6.isObjectLiteralExpression(literal) ? lookup2(literal, "pingAppName") : void 0;
|
|
145789
145939
|
const value = found?.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
145790
|
-
const replacement = value &&
|
|
145940
|
+
const replacement = value && ts6.isStringLiteralLike(value) ? replacementPingFamily(value.text) : void 0;
|
|
145791
145941
|
if (!value || !replacement) return;
|
|
145792
145942
|
plan.splices.push({ at: value.getStart(), end: value.end, text: JSON.stringify(replacement) });
|
|
145793
145943
|
plan.applied.push(`pingAppName ${JSON.stringify(replacement)} in place of ${value.getText()}`);
|
|
@@ -145800,11 +145950,11 @@ function planCapability(app, plan) {
|
|
|
145800
145950
|
return;
|
|
145801
145951
|
}
|
|
145802
145952
|
const list = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
|
|
145803
|
-
if (!list || !
|
|
145953
|
+
if (!list || !ts6.isArrayLiteralExpression(list)) {
|
|
145804
145954
|
plan.instructions.push('Add "push" to capabilities: Wix push needs the push capability, and config.ts does not list it inline.');
|
|
145805
145955
|
return;
|
|
145806
145956
|
}
|
|
145807
|
-
if (list.elements.some((e2) =>
|
|
145957
|
+
if (list.elements.some((e2) => ts6.isStringLiteralLike(e2) && e2.text === "push")) return;
|
|
145808
145958
|
const last = list.elements[list.elements.length - 1];
|
|
145809
145959
|
plan.splices.push(last ? { at: last.end, end: last.end, text: ', "push"' } : { at: list.getStart(), end: list.end, text: '["push"]' });
|
|
145810
145960
|
plan.applied.push("push capability");
|
|
@@ -145832,7 +145982,7 @@ function planAuthSite(login, file2, site, plan) {
|
|
|
145832
145982
|
const current = siteId.kind === "written" ? unwrap(siteId.node.initializer) : void 0;
|
|
145833
145983
|
if (!current) {
|
|
145834
145984
|
plan.instructions.push(`auth may get its siteId from elsewhere, so none was added. Wix push needs ${wanted}.`);
|
|
145835
|
-
} else if (!
|
|
145985
|
+
} else if (!ts6.isStringLiteralLike(current)) {
|
|
145836
145986
|
plan.instructions.push(`auth's siteId is computed, so it was not checked: make sure it evaluates to ${JSON.stringify(site)}.`);
|
|
145837
145987
|
} else if (current.text !== site) {
|
|
145838
145988
|
plan.instructions.push(
|
|
@@ -145843,89 +145993,6 @@ function planAuthSite(login, file2, site, plan) {
|
|
|
145843
145993
|
function noLiteralInstruction(pingAppName) {
|
|
145844
145994
|
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.`;
|
|
145845
145995
|
}
|
|
145846
|
-
function defineAppLiteral(file2) {
|
|
145847
|
-
for (const statement of file2.statements) {
|
|
145848
|
-
if (!ts5.isExportAssignment(statement)) continue;
|
|
145849
|
-
const exported = unwrap(statement.expression);
|
|
145850
|
-
if (ts5.isObjectLiteralExpression(exported)) return exported;
|
|
145851
|
-
const [first] = ts5.isCallExpression(exported) ? exported.arguments : [];
|
|
145852
|
-
return first && ts5.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
|
|
145853
|
-
}
|
|
145854
|
-
return void 0;
|
|
145855
|
-
}
|
|
145856
|
-
function loginOf(app) {
|
|
145857
|
-
const auth = lookup2(app, "auth");
|
|
145858
|
-
if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
|
|
145859
|
-
const value = unwrap(auth.node.initializer);
|
|
145860
|
-
if (ts5.isObjectLiteralExpression(value)) return { kind: "other" };
|
|
145861
|
-
if (!ts5.isCallExpression(value)) return { kind: "opaque" };
|
|
145862
|
-
const provider = calleeName(value);
|
|
145863
|
-
if (provider === "WixOwnerAuthProvider" || provider === "WixAuthProvider") return { kind: "owner" };
|
|
145864
|
-
if (provider === "WixNativeAuthProvider") return nativeMode(value) === "owner" ? { kind: "owner" } : { kind: "other" };
|
|
145865
|
-
if (provider !== "WixConsumerAuthProvider") return { kind: "other" };
|
|
145866
|
-
const [first] = value.arguments;
|
|
145867
|
-
return first && ts5.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
|
|
145868
|
-
}
|
|
145869
|
-
function nativeMode(call) {
|
|
145870
|
-
const [first] = call.arguments;
|
|
145871
|
-
return first && ts5.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
|
|
145872
|
-
}
|
|
145873
|
-
function calleeName(call) {
|
|
145874
|
-
const callee = call.expression;
|
|
145875
|
-
if (ts5.isIdentifier(callee)) return callee.text;
|
|
145876
|
-
return ts5.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
|
|
145877
|
-
}
|
|
145878
|
-
function unwrap(node) {
|
|
145879
|
-
let current = node;
|
|
145880
|
-
while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current)) {
|
|
145881
|
-
current = current.expression;
|
|
145882
|
-
}
|
|
145883
|
-
return current;
|
|
145884
|
-
}
|
|
145885
|
-
function lookup2(literal, name) {
|
|
145886
|
-
let found = { kind: "absent" };
|
|
145887
|
-
for (const p2 of literal.properties) {
|
|
145888
|
-
const key2 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
|
|
145889
|
-
if (ts5.isPropertyAssignment(p2) && key2 === name) found = { kind: "written", node: p2 };
|
|
145890
|
-
else if (ts5.isSpreadAssignment(p2) || p2.name && ts5.isComputedPropertyName(p2.name) || key2 === name) found = { kind: "opaque" };
|
|
145891
|
-
}
|
|
145892
|
-
return found;
|
|
145893
|
-
}
|
|
145894
|
-
function stringValue(node, name) {
|
|
145895
|
-
const literal = unwrap(node);
|
|
145896
|
-
const found = ts5.isObjectLiteralExpression(literal) ? lookup2(literal, name) : void 0;
|
|
145897
|
-
const value = found?.kind === "written" ? found.node.initializer : void 0;
|
|
145898
|
-
return value && ts5.isStringLiteralLike(value) ? value.text : void 0;
|
|
145899
|
-
}
|
|
145900
|
-
function appendProperties(literal, file2, lines) {
|
|
145901
|
-
const inline = () => lines.filter((line) => !line.trimStart().startsWith("//")).join(" ");
|
|
145902
|
-
if (literal.properties.length === 0) {
|
|
145903
|
-
const at3 = literal.getStart(file2) + 1;
|
|
145904
|
-
return { at: at3, end: literal.end - 1, text: ` ${inline().replace(/,$/, "")} ` };
|
|
145905
|
-
}
|
|
145906
|
-
const last = literal.properties[literal.properties.length - 1];
|
|
145907
|
-
const trailing = literal.properties.hasTrailingComma;
|
|
145908
|
-
const at2 = trailing ? literal.properties.end : last.end;
|
|
145909
|
-
const lead = trailing ? "" : ",";
|
|
145910
|
-
if (onOneLine(literal, file2)) {
|
|
145911
|
-
const text9 = inline();
|
|
145912
|
-
return { at: at2, end: at2, text: `${lead} ${trailing ? text9 : text9.replace(/,$/, "")}` };
|
|
145913
|
-
}
|
|
145914
|
-
const indent = lineIndent2(file2.text, last.getStart(file2));
|
|
145915
|
-
return { at: at2, end: at2, text: lead + lines.map((line) => `
|
|
145916
|
-
${indent}${line}`).join("") };
|
|
145917
|
-
}
|
|
145918
|
-
function onOneLine(node, file2) {
|
|
145919
|
-
const line = (position) => file2.getLineAndCharacterOfPosition(position).line;
|
|
145920
|
-
return line(node.getStart(file2)) === line(node.getEnd());
|
|
145921
|
-
}
|
|
145922
|
-
function lineIndent2(text9, position) {
|
|
145923
|
-
const lineStart = text9.lastIndexOf("\n", position - 1) + 1;
|
|
145924
|
-
return /^[ \t]*/.exec(text9.slice(lineStart))[0];
|
|
145925
|
-
}
|
|
145926
|
-
function applySplices(source, splices) {
|
|
145927
|
-
return [...splices].sort((a2, b2) => b2.at - a2.at).reduce((out2, s2) => out2.slice(0, s2.at) + s2.text + out2.slice(s2.end), source);
|
|
145928
|
-
}
|
|
145929
145996
|
function previewPushConfigEdit(dir, options) {
|
|
145930
145997
|
const path2 = configEntry(dir);
|
|
145931
145998
|
if (!path2) return void 0;
|
|
@@ -145942,13 +146009,13 @@ async function applyPushConfigEdit(dir, options, validate4) {
|
|
|
145942
146009
|
const edit = enablePushInConfig(original, { ...options, fileName });
|
|
145943
146010
|
const { applied, instructions, pushOn } = edit;
|
|
145944
146011
|
if (!edit.changed) return { changed: false, pushOn, applied, instructions };
|
|
145945
|
-
const backup =
|
|
146012
|
+
const backup = backUpConfig(dir, "notify-setup-backup", fileName, original);
|
|
145946
146013
|
if (!backup) return refuse7(`.himi is not a plain directory in this package (a symlink?), so ${fileName} was not edited.`);
|
|
145947
146014
|
writeFileAtomic(path2, edit.source);
|
|
145948
146015
|
const introduced = await introducedErrors(dir, validate4, {
|
|
145949
146016
|
restore: () => writeFileAtomic(path2, original),
|
|
145950
146017
|
reapply: () => writeFileAtomic(path2, edit.source)
|
|
145951
|
-
}).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
146018
|
+
}, isPushFinding).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
145952
146019
|
if (introduced) {
|
|
145953
146020
|
writeFileAtomic(path2, original);
|
|
145954
146021
|
const byHand = `Add to ${fileName} by hand: ${applied.join(", ")}.`;
|
|
@@ -145956,40 +146023,13 @@ async function applyPushConfigEdit(dir, options, validate4) {
|
|
|
145956
146023
|
}
|
|
145957
146024
|
return { changed: true, pushOn, applied, instructions, backup };
|
|
145958
146025
|
}
|
|
145959
|
-
function backUp(dir, fileName, original) {
|
|
145960
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
145961
|
-
const backupDir = realDirIn(dir, `.himi/notify-setup-backup/${stamp}`);
|
|
145962
|
-
if (!backupDir) return void 0;
|
|
145963
|
-
const backup = join50(backupDir, fileName);
|
|
145964
|
-
writeFileAtomic(backup, original);
|
|
145965
|
-
return backup;
|
|
145966
|
-
}
|
|
145967
|
-
function isSymlink2(path2) {
|
|
145968
|
-
try {
|
|
145969
|
-
return lstatSync14(path2).isSymbolicLink();
|
|
145970
|
-
} catch {
|
|
145971
|
-
return false;
|
|
145972
|
-
}
|
|
145973
|
-
}
|
|
145974
|
-
async function introducedErrors(dir, validate4, file2) {
|
|
145975
|
-
const edited = await validate4(dir, { fresh: true });
|
|
145976
|
-
if (edited.code === 0) return void 0;
|
|
145977
|
-
if (!comparable(edited)) return `himi validate failed and its report could not be read: ${edited.tail ?? "no output"}`;
|
|
145978
|
-
if (edited.errors.every((e2) => isPushFinding(e2.ruleCode))) return void 0;
|
|
145979
|
-
file2.restore();
|
|
145980
|
-
const baseline = await validate4(dir, { fresh: true });
|
|
145981
|
-
file2.reapply();
|
|
145982
|
-
if (!comparable(baseline)) return "himi validate could not check the original config.ts to compare against";
|
|
145983
|
-
const introduced = compareErrors(edited.errors, baseline.errors ?? []).introduced.filter((e2) => !isPushFinding(e2.ruleCode));
|
|
145984
|
-
return introduced.length ? `the edit introduced ${introduced.length === 1 ? "an error" : `${introduced.length} errors`}: ` + introduced.map((e2) => e2.message).join("; ") : void 0;
|
|
145985
|
-
}
|
|
145986
146026
|
var ROUTES_COMMENT, OWNER_INSTRUCTION, isPushFinding;
|
|
145987
146027
|
var init_config_push_edit = __esm({
|
|
145988
146028
|
"src/config-push-edit.ts"() {
|
|
145989
146029
|
init_wix_push_links();
|
|
145990
146030
|
init_app_config_loader();
|
|
146031
|
+
init_config_source_edit();
|
|
145991
146032
|
init_progress();
|
|
145992
|
-
init_template_trim();
|
|
145993
146033
|
ROUTES_COMMENT = "// Routes are derived at build time from provisioning.json and your screens; see himi validate.";
|
|
145994
146034
|
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).";
|
|
145995
146035
|
isPushFinding = (ruleCode) => ruleCode?.startsWith("push-") === true;
|
|
@@ -147082,8 +147122,8 @@ function watchFlagConflict(opts) {
|
|
|
147082
147122
|
return null;
|
|
147083
147123
|
}
|
|
147084
147124
|
function rebuildBlocker(outcome, servedMissing) {
|
|
147085
|
-
const
|
|
147086
|
-
if (
|
|
147125
|
+
const failed3 = outcome.failedToBuild[0];
|
|
147126
|
+
if (failed3) return `${failed3.screenId}: ${failed3.error.split("\n")[0]}`;
|
|
147087
147127
|
const had = new Set(servedMissing.map((m2) => `${m2.screen}\0${m2.bundle}`));
|
|
147088
147128
|
const lost = outcome.missingBundles.find((m2) => !had.has(`${m2.screen}\0${m2.bundle}`));
|
|
147089
147129
|
if (lost) return `${lost.screen}: its worker bundle "${lost.bundle}" is referenced but was not built`;
|
|
@@ -147426,15 +147466,15 @@ function loadMemory2(dir) {
|
|
|
147426
147466
|
for (const t2 of m2.timeline) {
|
|
147427
147467
|
if (!isObj3(t2)) continue;
|
|
147428
147468
|
const file2 = historyName(t2.sha, t2.ext);
|
|
147429
|
-
const
|
|
147469
|
+
const ts10 = str4(t2.ts);
|
|
147430
147470
|
const id = str4(t2.id);
|
|
147431
|
-
if (file2 &&
|
|
147471
|
+
if (file2 && ts10 && id) timeline.push({ ts: ts10, id, file: file2 });
|
|
147432
147472
|
}
|
|
147433
147473
|
return { createdAt: str4(m2.createdAt), shots, timeline };
|
|
147434
147474
|
}
|
|
147435
|
-
function captionAt(entries,
|
|
147475
|
+
function captionAt(entries, ts10) {
|
|
147436
147476
|
let best = null;
|
|
147437
|
-
for (const e2 of entries) if (e2.ts <=
|
|
147477
|
+
for (const e2 of entries) if (e2.ts <= ts10) best = e2;
|
|
147438
147478
|
return best ? best.message : null;
|
|
147439
147479
|
}
|
|
147440
147480
|
function thin(items, max) {
|
|
@@ -147554,13 +147594,13 @@ function duration(ms2) {
|
|
|
147554
147594
|
const m2 = Math.round(ms2 / 6e4);
|
|
147555
147595
|
return m2 < 60 ? `${m2} min` : `${Math.floor(m2 / 60)} h ${m2 % 60} min`;
|
|
147556
147596
|
}
|
|
147557
|
-
function utcDay(
|
|
147558
|
-
const d2 = new Date(
|
|
147597
|
+
function utcDay(ts10) {
|
|
147598
|
+
const d2 = new Date(ts10);
|
|
147559
147599
|
return Number.isNaN(d2.getTime()) ? "" : `${d2.toUTCString().slice(0, 16)} (UTC)`;
|
|
147560
147600
|
}
|
|
147561
|
-
function sinceStart(start,
|
|
147601
|
+
function sinceStart(start, ts10) {
|
|
147562
147602
|
if (!start) return "";
|
|
147563
|
-
const s2 = Math.max(0, Math.round((Date.parse(
|
|
147603
|
+
const s2 = Math.max(0, Math.round((Date.parse(ts10) - Date.parse(start)) / 1e3));
|
|
147564
147604
|
const h2 = Math.floor(s2 / 3600);
|
|
147565
147605
|
const m2 = Math.floor(s2 % 3600 / 60);
|
|
147566
147606
|
const sec = String(s2 % 60).padStart(2, "0");
|
|
@@ -147570,7 +147610,7 @@ function renderReel(plan, images) {
|
|
|
147570
147610
|
const img = (f2, alt, cls = "") => f2 && images.has(f2) ? `<img class="${cls}" src="${images.get(f2)}" alt="${escapeHtml(alt)}">` : "";
|
|
147571
147611
|
const count2 = (n2) => escapeHtml(String(Number.isSafeInteger(n2) && n2 >= 0 ? n2 : 0));
|
|
147572
147612
|
const accent = ACCENT.test(plan.accent) ? plan.accent : DEFAULT_ACCENT;
|
|
147573
|
-
const clock = (
|
|
147613
|
+
const clock = (ts10) => sinceStart(plan.startedAt, ts10);
|
|
147574
147614
|
const frames = plan.frames.filter((f2) => images.has(f2.file));
|
|
147575
147615
|
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>
|
|
147576
147616
|
<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>`;
|
|
@@ -148447,17 +148487,17 @@ __export(template_sweep_exports, {
|
|
|
148447
148487
|
});
|
|
148448
148488
|
import { readFileSync as readFileSync65, writeFileSync as writeFileSync24 } from "node:fs";
|
|
148449
148489
|
import { join as join57 } from "node:path";
|
|
148450
|
-
import
|
|
148490
|
+
import ts7 from "typescript";
|
|
148451
148491
|
function isCopy(node, file2) {
|
|
148452
148492
|
const parent = node.parent;
|
|
148453
|
-
if (
|
|
148454
|
-
if (
|
|
148455
|
-
if (
|
|
148456
|
-
if (
|
|
148493
|
+
if (ts7.isPropertyAssignment(parent) && parent.name === node) return false;
|
|
148494
|
+
if (ts7.isImportDeclaration(parent) || ts7.isExportDeclaration(parent) || ts7.isExternalModuleReference(parent)) return false;
|
|
148495
|
+
if (ts7.isLiteralTypeNode(parent) || ts7.isImportTypeNode(parent)) return false;
|
|
148496
|
+
if (ts7.isCallExpression(parent) && ts7.isIdentifier(parent.expression) && parent.expression.text === "require") return false;
|
|
148457
148497
|
const value = node.text;
|
|
148458
148498
|
if (/\s/.test(value) || PLACEHOLDER.test(value)) return true;
|
|
148459
148499
|
if (ID_LIKE.test(value)) return false;
|
|
148460
|
-
const key2 =
|
|
148500
|
+
const key2 = ts7.isPropertyAssignment(parent) ? propName4(parent.name) : void 0;
|
|
148461
148501
|
if (!key2) return false;
|
|
148462
148502
|
return COPY_KEYS.has(key2) || key2 === "name" && file2 === "config.ts";
|
|
148463
148503
|
}
|
|
@@ -148475,8 +148515,8 @@ function syntaxErrors(file2, text9) {
|
|
|
148475
148515
|
return [e2.message];
|
|
148476
148516
|
}
|
|
148477
148517
|
}
|
|
148478
|
-
const out2 =
|
|
148479
|
-
return (out2.diagnostics ?? []).map((d2) =>
|
|
148518
|
+
const out2 = ts7.transpileModule(text9, { fileName: file2, reportDiagnostics: true, compilerOptions: { target: ts7.ScriptTarget.ES2022 } });
|
|
148519
|
+
return (out2.diagnostics ?? []).map((d2) => ts7.flattenDiagnosticMessageText(d2.messageText, "\n"));
|
|
148480
148520
|
}
|
|
148481
148521
|
function sweepCopy(dir, pairs, dryRun) {
|
|
148482
148522
|
for (const [from] of pairs) {
|
|
@@ -148489,11 +148529,11 @@ function sweepCopy(dir, pairs, dryRun) {
|
|
|
148489
148529
|
for (const f2 of files) {
|
|
148490
148530
|
const text9 = readFileSync65(join57(dir, f2), "utf8");
|
|
148491
148531
|
if (!pairs.some(([from]) => text9.includes(from) || text9.includes(JSON.stringify(from).slice(1, -1)))) continue;
|
|
148492
|
-
const kind = f2.endsWith(".json") ?
|
|
148493
|
-
const sf2 =
|
|
148532
|
+
const kind = f2.endsWith(".json") ? ts7.ScriptKind.JSON : f2.endsWith("x") ? ts7.ScriptKind.TSX : ts7.ScriptKind.TS;
|
|
148533
|
+
const sf2 = ts7.createSourceFile(f2, text9, ts7.ScriptTarget.Latest, true, kind);
|
|
148494
148534
|
const edits = [];
|
|
148495
148535
|
const visit = (node) => {
|
|
148496
|
-
if ((
|
|
148536
|
+
if ((ts7.isStringLiteral(node) || ts7.isNoSubstitutionTemplateLiteral(node)) && isCopy(node, f2)) {
|
|
148497
148537
|
let value = node.text;
|
|
148498
148538
|
pairs.forEach(([from, to2], i2) => {
|
|
148499
148539
|
const n2 = value.split(from).length - 1;
|
|
@@ -148506,7 +148546,7 @@ function sweepCopy(dir, pairs, dryRun) {
|
|
|
148506
148546
|
edits.push({ start, end: node.end, text: encode(value, text9[start]) });
|
|
148507
148547
|
}
|
|
148508
148548
|
}
|
|
148509
|
-
|
|
148549
|
+
ts7.forEachChild(node, visit);
|
|
148510
148550
|
};
|
|
148511
148551
|
visit(sf2);
|
|
148512
148552
|
if (!edits.length) continue;
|
|
@@ -148578,7 +148618,7 @@ var init_template_sweep = __esm({
|
|
|
148578
148618
|
"appName",
|
|
148579
148619
|
"displayName"
|
|
148580
148620
|
]);
|
|
148581
|
-
propName4 = (n2) =>
|
|
148621
|
+
propName4 = (n2) => ts7.isIdentifier(n2) || ts7.isStringLiteral(n2) || ts7.isNoSubstitutionTemplateLiteral(n2) ? n2.text : void 0;
|
|
148582
148622
|
}
|
|
148583
148623
|
});
|
|
148584
148624
|
|
|
@@ -152330,7 +152370,7 @@ function fileTools() {
|
|
|
152330
152370
|
if (typeof app !== "string") return app;
|
|
152331
152371
|
const files = Array.isArray(a2.files) ? a2.files : [];
|
|
152332
152372
|
if (!files.length || files.length > MAX_FILES_PER_WRITE) return refuse5("bad_request", `between 1 and ${MAX_FILES_PER_WRITE} files per call`);
|
|
152333
|
-
const
|
|
152373
|
+
const planned2 = [];
|
|
152334
152374
|
const refused2 = [];
|
|
152335
152375
|
for (const f2 of files) {
|
|
152336
152376
|
const p2 = confinedPath(app, f2.path);
|
|
@@ -152338,12 +152378,12 @@ function fileTools() {
|
|
|
152338
152378
|
else if (typeof f2.content !== "string") refused2.push({ path: f2.path, error: "content must be text" });
|
|
152339
152379
|
else if (Buffer.byteLength(f2.content) > MAX_FILE_BYTES) refused2.push({ path: f2.path, error: `over the ${MAX_FILE_BYTES}-byte limit` });
|
|
152340
152380
|
else if (existsSync63(p2) && !lstatSync20(p2).isFile()) refused2.push({ path: f2.path, error: "not a regular file" });
|
|
152341
|
-
else if (
|
|
152342
|
-
else
|
|
152381
|
+
else if (planned2.some((q2) => q2.abs === p2)) refused2.push({ path: f2.path, error: "the same file twice in one call" });
|
|
152382
|
+
else planned2.push({ abs: p2, rel: String(f2.path), content: f2.content });
|
|
152343
152383
|
}
|
|
152344
152384
|
if (refused2.length) return { ...ok({ ok: false, error: "refused", written: [], refused: refused2 }), isError: true };
|
|
152345
152385
|
const written = [];
|
|
152346
|
-
for (const f2 of
|
|
152386
|
+
for (const f2 of planned2) {
|
|
152347
152387
|
try {
|
|
152348
152388
|
writeNoFollow2(app, f2.abs, f2.content);
|
|
152349
152389
|
written.push(f2.rel);
|
|
@@ -152364,7 +152404,7 @@ function fileTools() {
|
|
|
152364
152404
|
const app = await confinedAppDir(a2, d2);
|
|
152365
152405
|
if (typeof app !== "string") return app;
|
|
152366
152406
|
const paths = Array.isArray(a2.paths) ? a2.paths : [];
|
|
152367
|
-
const
|
|
152407
|
+
const planned2 = [];
|
|
152368
152408
|
const deleted = [];
|
|
152369
152409
|
const refused2 = [];
|
|
152370
152410
|
for (const rel of paths) {
|
|
@@ -152372,13 +152412,13 @@ function fileTools() {
|
|
|
152372
152412
|
if (typeof p2 !== "string") refused2.push({ path: rel, error: p2.error });
|
|
152373
152413
|
else if (!existsSync63(p2)) refused2.push({ path: rel, error: "no such file" });
|
|
152374
152414
|
else if (!lstatSync20(p2).isFile()) refused2.push({ path: rel, error: "not a regular file" });
|
|
152375
|
-
else if (!
|
|
152376
|
-
|
|
152415
|
+
else if (!planned2.includes(p2)) {
|
|
152416
|
+
planned2.push(p2);
|
|
152377
152417
|
deleted.push(rel);
|
|
152378
152418
|
}
|
|
152379
152419
|
}
|
|
152380
152420
|
if (refused2.length) return { ...ok({ ok: false, error: "refused", deleted: [], refused: refused2 }), isError: true };
|
|
152381
|
-
for (const p2 of
|
|
152421
|
+
for (const p2 of planned2) rmSync15(p2);
|
|
152382
152422
|
return ok({ ok: true, dir: app, deleted });
|
|
152383
152423
|
}
|
|
152384
152424
|
}
|
|
@@ -155739,25 +155779,25 @@ var init_preview_assets_generated = __esm({
|
|
|
155739
155779
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
155740
155780
|
init_preview_assets_format();
|
|
155741
155781
|
PREVIEW_ASSET_MANIFEST = [
|
|
155742
|
-
{ key: "assets/index-
|
|
155743
|
-
{ key: "assets/pdf-
|
|
155744
|
-
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset:
|
|
155745
|
-
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset:
|
|
155746
|
-
{ key: "assets/pdfDocument-
|
|
155747
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
155748
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
155749
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
155750
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
155751
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
155752
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
155753
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
155754
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
155755
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
155756
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
155757
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
155758
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
155759
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
155760
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
155782
|
+
{ key: "assets/index-BIlXpj1h.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1257735, sha256: "6d808a71fd48dfe402d9cdace4e2a6ce1a8d686068d1812eb08ef418f2284533" },
|
|
155783
|
+
{ key: "assets/pdf-DKCzctsR.js", contentType: "application/javascript; charset=utf-8", offset: 1257743, length: 488199, sha256: "580e24333dcc9b041e8720577be50a8da5a50800f4d5e948e28edf9c8dd7d9e0" },
|
|
155784
|
+
{ key: "assets/pdf.worker.min-BQa_JDET.js", contentType: "application/javascript; charset=utf-8", offset: 1745942, length: 73, sha256: "41bcfda4f3c8c0a81c785ea87c69afc8e7d0ed8c333324aee94c273d881bb6aa" },
|
|
155785
|
+
{ key: "assets/pdf.worker.min-BmVo14Nb.mjs", contentType: "application/javascript; charset=utf-8", offset: 1746015, length: 1317034, sha256: "a33cfe728c584fdba4fcc1fd54bcdc2f9f2f13889ddbb5b2bd1d0f8cbe49b84e" },
|
|
155786
|
+
{ key: "assets/pdfDocument-DCdoA9nd.js", contentType: "application/javascript; charset=utf-8", offset: 3063049, length: 2858, sha256: "ea99eb8d79920cd5c7ca2c83faa495c5287ff04d1c96bbfe3d034b8925075ad2" },
|
|
155787
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 3065907, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
155788
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 3070517, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
155789
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 3559101, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
155790
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 3650025, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
155791
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 3741009, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
155792
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 3831989, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
155793
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 3922861, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
155794
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 4013841, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
155795
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 4122477, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
155796
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 4231561, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
155797
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 4340609, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
155798
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 4448309, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
155799
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 4536417, length: 4947, sha256: "31a68c99003ad579052a0dccccfa5d861146fe209bbc6ea0c264162026d7b35f" },
|
|
155800
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 4541364, length: 17344, sha256: "d057298d75e7373e5e2c4d11b7d1bcbea88e03af555ba63d97641c78509c58e4" }
|
|
155761
155801
|
];
|
|
155762
155802
|
}
|
|
155763
155803
|
});
|
|
@@ -157508,17 +157548,17 @@ var init_iap_plan = __esm({
|
|
|
157508
157548
|
function sameOp(a2, b2) {
|
|
157509
157549
|
return a2.kind === b2.kind && ("locale" in a2 ? a2.locale : void 0) === ("locale" in b2 ? b2.locale : void 0);
|
|
157510
157550
|
}
|
|
157511
|
-
function assertSameAccount(
|
|
157512
|
-
if (
|
|
157551
|
+
function assertSameAccount(planned2, current) {
|
|
157552
|
+
if (planned2.profile === current.profile && planned2.team === current.team && planned2.fingerprint === current.fingerprint) return;
|
|
157513
157553
|
throw new IapProvisionError(
|
|
157514
157554
|
"account",
|
|
157515
|
-
`the plan was made with profile "${
|
|
157555
|
+
`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.`
|
|
157516
157556
|
);
|
|
157517
157557
|
}
|
|
157518
|
-
function driftOf(
|
|
157519
|
-
if (
|
|
157558
|
+
function driftOf(planned2, live3) {
|
|
157559
|
+
if (planned2.decision === "conflict") return void 0;
|
|
157520
157560
|
if (live3.decision === "conflict") return `${live3.productId} now conflicts: ${live3.conflicts.join("; ")}`;
|
|
157521
|
-
const unplanned = live3.ops.filter((op) => !
|
|
157561
|
+
const unplanned = live3.ops.filter((op) => !planned2.ops.some((p2) => sameOp(p2, op)));
|
|
157522
157562
|
return unplanned.length ? `${live3.productId} now needs ${unplanned.map(describeOp).join(", ")}, which the plan did not list` : void 0;
|
|
157523
157563
|
}
|
|
157524
157564
|
function assertNoDrift(plan, live3) {
|
|
@@ -157670,8 +157710,8 @@ async function runOps(run2, ops, context, manifest) {
|
|
|
157670
157710
|
return steps;
|
|
157671
157711
|
}
|
|
157672
157712
|
function outcomeOf(ops, steps, unmet) {
|
|
157673
|
-
const
|
|
157674
|
-
if (
|
|
157713
|
+
const failed3 = steps.some((s2) => s2.state === "failed");
|
|
157714
|
+
if (failed3) return steps.some((s2) => s2.state === "done" || s2.state === "reconciled") ? "partial" : "failed";
|
|
157675
157715
|
if (unmet.length) return "partial";
|
|
157676
157716
|
if (ops.some((op) => op.kind === "createProduct")) return "created";
|
|
157677
157717
|
return ops.length ? "updated" : "reused";
|
|
@@ -157688,9 +157728,9 @@ async function readBack(run2, context, manifest) {
|
|
|
157688
157728
|
async function unmetFor(item, observed, context) {
|
|
157689
157729
|
return observed ? metadataDiffs(item, observed, await context.pricing.targetAmount(item.price, observed.resourceId)) : [];
|
|
157690
157730
|
}
|
|
157691
|
-
async function knownUnmetFor(item,
|
|
157692
|
-
if (!
|
|
157693
|
-
return metadataDiffs(item,
|
|
157731
|
+
async function knownUnmetFor(item, planned2, context) {
|
|
157732
|
+
if (!planned2.observed) return [];
|
|
157733
|
+
return metadataDiffs(item, planned2.observed, planned2.targetPrice ?? await context.pricing.targetAmount(item.price));
|
|
157694
157734
|
}
|
|
157695
157735
|
async function applyItem(item, live3, context, manifest) {
|
|
157696
157736
|
const base = { target: manifest.target, item, readAt: context.now() };
|
|
@@ -157714,19 +157754,19 @@ function deferredResult(item, live3, context, manifest) {
|
|
|
157714
157754
|
const steps = live3.ops.map((op) => stepFor(op, "notRun"));
|
|
157715
157755
|
return itemResult({ target: manifest.target, item, observed: live3.observed, outcome: "deferred", steps, requirements: [DEFERRED_REQUIREMENT], readAt: context.now() });
|
|
157716
157756
|
}
|
|
157717
|
-
function needsRefresh(
|
|
157718
|
-
return
|
|
157757
|
+
function needsRefresh(planned2) {
|
|
157758
|
+
return planned2.decision !== "conflict" && planned2.ops.length > 0;
|
|
157719
157759
|
}
|
|
157720
|
-
function plannedResult(item,
|
|
157721
|
-
if (
|
|
157722
|
-
return itemResult({ target: manifest.target, item, observed:
|
|
157760
|
+
function plannedResult(item, planned2, plan, context, manifest) {
|
|
157761
|
+
if (planned2.decision === "conflict") return applyItem(item, planned2, context, manifest);
|
|
157762
|
+
return itemResult({ target: manifest.target, item, observed: planned2.observed, outcome: "reused", readAt: new Date(plan.createdAt) });
|
|
157723
157763
|
}
|
|
157724
157764
|
async function applyIap(planDoc, applyContext) {
|
|
157725
157765
|
const plan = verifyPlan2(planDoc);
|
|
157726
157766
|
assertSameAccount(plan.identity, applyContext.identity);
|
|
157727
157767
|
const context = { ...applyContext, pricing: applyContext.pricing ?? new PriceGrid(applyContext.api) };
|
|
157728
157768
|
const manifest = plan.manifest;
|
|
157729
|
-
const refresh = plan.items.flatMap((
|
|
157769
|
+
const refresh = plan.items.flatMap((planned2, i2) => needsRefresh(planned2) ? [i2] : []);
|
|
157730
157770
|
const live3 = await planItemsAt(context, manifest, refresh);
|
|
157731
157771
|
assertNoDrift(plan, live3);
|
|
157732
157772
|
const items = [];
|
|
@@ -157955,6 +157995,17 @@ var init_iap_credentials = __esm({
|
|
|
157955
157995
|
}
|
|
157956
157996
|
});
|
|
157957
157997
|
|
|
157998
|
+
// ../../core/sdk/iap/src/wix-payments-contract.ts
|
|
157999
|
+
var HIMALAYA_SERVE_IAP_ROUTE, APPLE_SALE_RULES;
|
|
158000
|
+
var init_wix_payments_contract = __esm({
|
|
158001
|
+
"../../core/sdk/iap/src/wix-payments-contract.ts"() {
|
|
158002
|
+
HIMALAYA_SERVE_IAP_ROUTE = { prefix: "/himalaya-serve/v1/iap" };
|
|
158003
|
+
APPLE_SALE_RULES = {
|
|
158004
|
+
onlineProgram: { appProductId: (id) => id, productType: "NON_CONSUMABLE" }
|
|
158005
|
+
};
|
|
158006
|
+
}
|
|
158007
|
+
});
|
|
158008
|
+
|
|
157958
158009
|
// ../store-release/iap-draft.ts
|
|
157959
158010
|
import { createHash as createHash38 } from "node:crypto";
|
|
157960
158011
|
function fit(text9, max) {
|
|
@@ -158214,6 +158265,327 @@ var init_redact = __esm({
|
|
|
158214
158265
|
}
|
|
158215
158266
|
});
|
|
158216
158267
|
|
|
158268
|
+
// ../store-release/version.ts
|
|
158269
|
+
var version_exports = {};
|
|
158270
|
+
__export(version_exports, {
|
|
158271
|
+
bumpVersion: () => bumpVersion,
|
|
158272
|
+
readAndroidVersion: () => readAndroidVersion,
|
|
158273
|
+
readAndroidVersionName: () => readAndroidVersionName,
|
|
158274
|
+
readIosMarketingVersion: () => readIosMarketingVersion,
|
|
158275
|
+
readIosVersion: () => readIosVersion,
|
|
158276
|
+
readIosVersionStrings: () => readIosVersionStrings,
|
|
158277
|
+
readIosVersionStringsOrNull: () => readIosVersionStringsOrNull,
|
|
158278
|
+
readTargetVersionKeys: () => readTargetVersionKeys,
|
|
158279
|
+
readTargetVersionStrings: () => readTargetVersionStrings,
|
|
158280
|
+
setAndroidVersion: () => setAndroidVersion,
|
|
158281
|
+
setIosVersion: () => setIosVersion,
|
|
158282
|
+
stampIosVersionStrings: () => stampIosVersionStrings,
|
|
158283
|
+
stampTargetVersion: () => stampTargetVersion,
|
|
158284
|
+
stampVersionKeys: () => stampVersionKeys
|
|
158285
|
+
});
|
|
158286
|
+
import { readFileSync as readFileSync85, writeFileSync as writeFileSync29 } from "node:fs";
|
|
158287
|
+
function readIosVersion(projectYml) {
|
|
158288
|
+
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158289
|
+
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
158290
|
+
if (marketing === null || build3 === null) {
|
|
158291
|
+
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
158292
|
+
}
|
|
158293
|
+
return { marketing, build: Number(build3) };
|
|
158294
|
+
}
|
|
158295
|
+
function setIosVersion(projectYml, v2) {
|
|
158296
|
+
let out2 = replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing);
|
|
158297
|
+
out2 = replaceScalar(out2, "CFBundleVersion", String(v2.build));
|
|
158298
|
+
out2 = out2.replace(
|
|
158299
|
+
/(^[ \t]*# >>> himalaya:live-activity:target[^\n]*\n)([\s\S]*?)(^[ \t]*# <<< himalaya:live-activity:target[^\n]*$)/m,
|
|
158300
|
+
(_match, start, body, end) => {
|
|
158301
|
+
if (!body.trim()) return start + body + end;
|
|
158302
|
+
return start + replaceScalar(replaceScalar(body, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", String(v2.build)) + end;
|
|
158303
|
+
}
|
|
158304
|
+
);
|
|
158305
|
+
return out2;
|
|
158306
|
+
}
|
|
158307
|
+
function readIosVersionStrings(projectYml) {
|
|
158308
|
+
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158309
|
+
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
158310
|
+
if (marketing === null || build3 === null) {
|
|
158311
|
+
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
158312
|
+
}
|
|
158313
|
+
return { marketing, build: build3 };
|
|
158314
|
+
}
|
|
158315
|
+
function readIosVersionStringsOrNull(projectYml) {
|
|
158316
|
+
try {
|
|
158317
|
+
return readIosVersionStrings(projectYml);
|
|
158318
|
+
} catch {
|
|
158319
|
+
return null;
|
|
158320
|
+
}
|
|
158321
|
+
}
|
|
158322
|
+
function stampIosVersionStrings(projectYml, v2) {
|
|
158323
|
+
return replaceScalar(replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", v2.build);
|
|
158324
|
+
}
|
|
158325
|
+
function stampVersionKeys(projectYml, v2) {
|
|
158326
|
+
let out2 = projectYml;
|
|
158327
|
+
if (v2.marketing !== void 0) out2 = replaceScalar(out2, "CFBundleShortVersionString", v2.marketing);
|
|
158328
|
+
if (v2.build !== void 0) out2 = replaceScalar(out2, "CFBundleVersion", v2.build);
|
|
158329
|
+
return out2;
|
|
158330
|
+
}
|
|
158331
|
+
function targetBlock(lines, target) {
|
|
158332
|
+
const head = new RegExp(`^ {2}${target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*$`);
|
|
158333
|
+
const start = lines.findIndex((l2) => head.test(l2));
|
|
158334
|
+
if (start < 0) return null;
|
|
158335
|
+
let end = start + 1;
|
|
158336
|
+
while (end < lines.length && !/^ {0,2}\S/.test(lines[end])) end++;
|
|
158337
|
+
return { start, end };
|
|
158338
|
+
}
|
|
158339
|
+
function readTargetVersionStrings(projectYml, target) {
|
|
158340
|
+
const lines = projectYml.split("\n");
|
|
158341
|
+
const block = targetBlock(lines, target);
|
|
158342
|
+
if (!block) return null;
|
|
158343
|
+
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
158344
|
+
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
158345
|
+
const build3 = matchScalar(body, "CFBundleVersion");
|
|
158346
|
+
return marketing !== null && build3 !== null ? { marketing, build: build3 } : null;
|
|
158347
|
+
}
|
|
158348
|
+
function readTargetVersionKeys(projectYml, target) {
|
|
158349
|
+
const lines = projectYml.split("\n");
|
|
158350
|
+
const block = targetBlock(lines, target);
|
|
158351
|
+
if (!block) return null;
|
|
158352
|
+
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
158353
|
+
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
158354
|
+
const build3 = matchScalar(body, "CFBundleVersion");
|
|
158355
|
+
if (marketing === null && build3 === null) return null;
|
|
158356
|
+
return { ...marketing !== null ? { marketing } : {}, ...build3 !== null ? { build: build3 } : {} };
|
|
158357
|
+
}
|
|
158358
|
+
function stampTargetVersion(yml, target, v2) {
|
|
158359
|
+
const lines = yml.split("\n");
|
|
158360
|
+
const block = targetBlock(lines, target);
|
|
158361
|
+
if (!block) return yml;
|
|
158362
|
+
for (let i2 = block.start + 1; i2 < block.end; i2++) {
|
|
158363
|
+
const inline = /^ {4}info:\s*\{\s*path:\s*([^\s,}]+)\s*\}\s*(#.*)?$/.exec(lines[i2]);
|
|
158364
|
+
if (inline) {
|
|
158365
|
+
lines.splice(i2, 1, " info:", ` path: ${inline[1]}`);
|
|
158366
|
+
block.end++;
|
|
158367
|
+
break;
|
|
158368
|
+
}
|
|
158369
|
+
}
|
|
158370
|
+
const { start, end } = block;
|
|
158371
|
+
const want = {};
|
|
158372
|
+
if (v2.marketing !== void 0) want.CFBundleShortVersionString = v2.marketing;
|
|
158373
|
+
if (v2.build !== void 0) want.CFBundleVersion = v2.build;
|
|
158374
|
+
const seen = /* @__PURE__ */ new Set();
|
|
158375
|
+
let infoAt = -1;
|
|
158376
|
+
let propsAt = -1;
|
|
158377
|
+
for (let i2 = start + 1; i2 < end; i2++) {
|
|
158378
|
+
if (/^ {4}info:\s*$/.test(lines[i2])) infoAt = i2;
|
|
158379
|
+
if (infoAt >= 0 && /^ {6}properties:\s*$/.test(lines[i2]) && lines.slice(infoAt + 1, i2).every((l2) => !/^ {4}\S/.test(l2))) propsAt = i2;
|
|
158380
|
+
const m2 = /^(\s+)(CFBundleShortVersionString|CFBundleVersion):\s*.*$/.exec(lines[i2]);
|
|
158381
|
+
if (m2 && m2[2] in want) {
|
|
158382
|
+
lines[i2] = `${m2[1]}${m2[2]}: "${want[m2[2]]}"`;
|
|
158383
|
+
seen.add(m2[2]);
|
|
158384
|
+
}
|
|
158385
|
+
}
|
|
158386
|
+
const missing = Object.keys(want).filter((k2) => !seen.has(k2)).map((k2) => ` ${k2}: "${want[k2]}"`);
|
|
158387
|
+
if (missing.length && propsAt >= 0) {
|
|
158388
|
+
lines.splice(propsAt + 1, 0, ...missing);
|
|
158389
|
+
} else if (missing.length && infoAt >= 0) {
|
|
158390
|
+
let after = infoAt + 1;
|
|
158391
|
+
while (after < end && /^ {6}\S/.test(lines[after])) after++;
|
|
158392
|
+
lines.splice(after, 0, " properties:", ...missing);
|
|
158393
|
+
}
|
|
158394
|
+
return lines.join("\n");
|
|
158395
|
+
}
|
|
158396
|
+
function readIosMarketingVersion(projectYml) {
|
|
158397
|
+
return matchScalar(projectYml, "CFBundleShortVersionString");
|
|
158398
|
+
}
|
|
158399
|
+
function scalarRe(key2) {
|
|
158400
|
+
return new RegExp(`^(\\s*${key2}:\\s*)("?)([^"\\n#]*?)("?)(\\s*(?:#.*)?)$`, "m");
|
|
158401
|
+
}
|
|
158402
|
+
function matchScalar(content, key2) {
|
|
158403
|
+
const m2 = scalarRe(key2).exec(content);
|
|
158404
|
+
return m2 ? m2[3].trim() : null;
|
|
158405
|
+
}
|
|
158406
|
+
function replaceScalar(content, key2, value) {
|
|
158407
|
+
const re2 = scalarRe(key2);
|
|
158408
|
+
if (!re2.test(content)) throw new Error(`could not locate \`${key2}:\` in project.yml`);
|
|
158409
|
+
return content.replace(re2, (_full, pre, openQ, _oldVal, _closeQ, tail) => {
|
|
158410
|
+
const q2 = openQ ? '"' : "";
|
|
158411
|
+
return `${pre}${q2}${value}${q2}${tail}`;
|
|
158412
|
+
});
|
|
158413
|
+
}
|
|
158414
|
+
function readAndroidVersion(gradle) {
|
|
158415
|
+
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
158416
|
+
const code = /(\bversionCode\s*=\s*)(\d+)/.exec(gradle);
|
|
158417
|
+
if (!name || !code) throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
158418
|
+
return { marketing: name[2], build: Number(code[2]) };
|
|
158419
|
+
}
|
|
158420
|
+
function readAndroidVersionName(gradle) {
|
|
158421
|
+
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
158422
|
+
return name ? name[2] : null;
|
|
158423
|
+
}
|
|
158424
|
+
function setAndroidVersion(gradle, v2) {
|
|
158425
|
+
if (!/\bversionName\s*=\s*"/.test(gradle) || !/\bversionCode\s*=\s*\d+/.test(gradle)) {
|
|
158426
|
+
throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
158427
|
+
}
|
|
158428
|
+
return gradle.replace(/(\bversionName\s*=\s*")[^"]*(")/, `$1${v2.marketing}$2`).replace(/(\bversionCode\s*=\s*)\d+/, `$1${v2.build}`);
|
|
158429
|
+
}
|
|
158430
|
+
function bumpVersion(app, opts) {
|
|
158431
|
+
const iosPath = iosProjectYml(app);
|
|
158432
|
+
const gradlePath = androidGradle(app);
|
|
158433
|
+
const iosYml = readFileSync85(iosPath, "utf8");
|
|
158434
|
+
const gradle = readFileSync85(gradlePath, "utf8");
|
|
158435
|
+
const current = readIosVersion(iosYml);
|
|
158436
|
+
const next = {
|
|
158437
|
+
marketing: opts.marketing ?? current.marketing,
|
|
158438
|
+
build: opts.build === "increment" || opts.build === void 0 ? current.build + (opts.build === "increment" ? 1 : 0) : opts.build
|
|
158439
|
+
};
|
|
158440
|
+
writeFileSync29(iosPath, setIosVersion(iosYml, next));
|
|
158441
|
+
writeFileSync29(gradlePath, setAndroidVersion(gradle, next));
|
|
158442
|
+
return next;
|
|
158443
|
+
}
|
|
158444
|
+
var init_version = __esm({
|
|
158445
|
+
"../store-release/version.ts"() {
|
|
158446
|
+
init_paths2();
|
|
158447
|
+
}
|
|
158448
|
+
});
|
|
158449
|
+
|
|
158450
|
+
// ../store-release/store-spec.ts
|
|
158451
|
+
function defaultProdBundleId(devBundleId) {
|
|
158452
|
+
return devBundleId.replace(/\.dev$/, "");
|
|
158453
|
+
}
|
|
158454
|
+
var init_store_spec = __esm({
|
|
158455
|
+
"../store-release/store-spec.ts"() {
|
|
158456
|
+
init_paths2();
|
|
158457
|
+
init_version();
|
|
158458
|
+
init_embedded_bundles();
|
|
158459
|
+
init_embedded_bundles();
|
|
158460
|
+
}
|
|
158461
|
+
});
|
|
158462
|
+
|
|
158463
|
+
// src/iap-config-edit.ts
|
|
158464
|
+
import { existsSync as existsSync73, readFileSync as readFileSync86 } from "node:fs";
|
|
158465
|
+
import { basename as basename18, join as join72 } from "node:path";
|
|
158466
|
+
import ts8 from "typescript";
|
|
158467
|
+
function bindPurchasesAppInConfig(source, options) {
|
|
158468
|
+
const fileName = options.fileName ?? "config.ts";
|
|
158469
|
+
const kind = fileName.endsWith(".ts") ? ts8.ScriptKind.TS : ts8.ScriptKind.JS;
|
|
158470
|
+
const file2 = ts8.createSourceFile(fileName, source, ts8.ScriptTarget.Latest, true, kind);
|
|
158471
|
+
const wanted = `wixIap: { purchasesAppId: ${JSON.stringify(options.purchasesAppId)} }`;
|
|
158472
|
+
const unchanged = (result) => ({ source, changed: false, applied: [], conflicts: [], instructions: [], ...result });
|
|
158473
|
+
const app = defineAppLiteral(file2);
|
|
158474
|
+
if (!app || app.properties.length === 0) {
|
|
158475
|
+
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.`] });
|
|
158476
|
+
}
|
|
158477
|
+
const site = siteFinding(app, options.siteId, fileName);
|
|
158478
|
+
const bundle = bundleFinding(app, options, fileName);
|
|
158479
|
+
const binding2 = bindingFinding(app, file2, options.purchasesAppId, wanted, fileName);
|
|
158480
|
+
const conflicts = [site, bundle, binding2].flatMap((f2) => f2.conflict ? [f2.conflict] : []);
|
|
158481
|
+
if (conflicts.length) return unchanged({ conflicts });
|
|
158482
|
+
const capability = capabilityFinding(app, fileName);
|
|
158483
|
+
const splices = [binding2.splice, capability.splice].filter((s2) => !!s2);
|
|
158484
|
+
return {
|
|
158485
|
+
source: applySplices(source, splices),
|
|
158486
|
+
changed: splices.length > 0,
|
|
158487
|
+
applied: [binding2.applied, capability.applied].filter((a2) => !!a2),
|
|
158488
|
+
conflicts: [],
|
|
158489
|
+
instructions: [site.instruction, binding2.instruction, capability.instruction, bundle.instruction].filter((i2) => !!i2)
|
|
158490
|
+
};
|
|
158491
|
+
}
|
|
158492
|
+
function siteFinding(app, siteId, fileName) {
|
|
158493
|
+
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.`;
|
|
158494
|
+
const login = loginOf(app);
|
|
158495
|
+
if (login.kind !== "member") return { instruction: `${fileName} does not write auth as a WixConsumerAuthProvider({ \u2026 }) call it can read, so ${check}` };
|
|
158496
|
+
const found = lookup2(login.literal, "siteId");
|
|
158497
|
+
const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
158498
|
+
if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `auth's siteId is not written as a literal, so ${check}` };
|
|
158499
|
+
if (value.text.toLowerCase() === siteId.toLowerCase()) return {};
|
|
158500
|
+
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.` };
|
|
158501
|
+
}
|
|
158502
|
+
function bundleFinding(app, { bundleId, storeBundleId }, fileName) {
|
|
158503
|
+
if (storeBundleId) {
|
|
158504
|
+
if (storeBundleId === bundleId) return {};
|
|
158505
|
+
return { conflict: `store/store.config.yaml builds bundle "${storeBundleId}", but the purchases app is registered for "${bundleId}". ${fileName} was not edited.` };
|
|
158506
|
+
}
|
|
158507
|
+
const found = lookup2(app, "bundleId");
|
|
158508
|
+
const value = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
|
|
158509
|
+
if (!value || !ts8.isStringLiteralLike(value)) {
|
|
158510
|
+
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.` };
|
|
158511
|
+
}
|
|
158512
|
+
if (value.text === bundleId || defaultProdBundleId(value.text) === bundleId) return {};
|
|
158513
|
+
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.` };
|
|
158514
|
+
}
|
|
158515
|
+
function bindingFinding(app, file2, purchasesAppId, wanted, fileName) {
|
|
158516
|
+
const wixIap = lookup2(app, "wixIap");
|
|
158517
|
+
if (wixIap.kind === "absent") return { splice: appendProperties(app, file2, [`${wanted},`]), applied: "wixIap.purchasesAppId" };
|
|
158518
|
+
const literal = wixIap.kind === "written" ? unwrap(wixIap.node.initializer) : void 0;
|
|
158519
|
+
if (!literal || !ts8.isObjectLiteralExpression(literal)) return { instruction: `${fileName} computes wixIap, so it was not edited: it must evaluate to ${wanted}.` };
|
|
158520
|
+
const current = lookup2(literal, "purchasesAppId");
|
|
158521
|
+
if (current.kind === "absent") return { splice: appendProperties(literal, file2, [`purchasesAppId: ${JSON.stringify(purchasesAppId)},`]), applied: "wixIap.purchasesAppId" };
|
|
158522
|
+
const value = current.kind === "written" ? unwrap(current.node.initializer) : void 0;
|
|
158523
|
+
if (!value || !ts8.isStringLiteralLike(value)) return { instruction: `${fileName} computes wixIap.purchasesAppId, so it was not edited: it must evaluate to ${JSON.stringify(purchasesAppId)}.` };
|
|
158524
|
+
if (value.text === purchasesAppId) return {};
|
|
158525
|
+
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.` };
|
|
158526
|
+
}
|
|
158527
|
+
function capabilityFinding(app, fileName) {
|
|
158528
|
+
const capabilities = lookup2(app, "capabilities");
|
|
158529
|
+
const list = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
|
|
158530
|
+
if (capabilities.kind !== "absent" && (!list || !ts8.isArrayLiteralExpression(list))) {
|
|
158531
|
+
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.` };
|
|
158532
|
+
}
|
|
158533
|
+
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.` };
|
|
158534
|
+
const elements = list.elements;
|
|
158535
|
+
if (elements.some((e2) => ts8.isStringLiteralLike(e2) && e2.text === "iap")) return {};
|
|
158536
|
+
const last = elements[elements.length - 1];
|
|
158537
|
+
return {
|
|
158538
|
+
splice: last ? { at: last.end, end: last.end, text: ', "iap"' } : { at: list.getStart(), end: list.end, text: '["iap"]' },
|
|
158539
|
+
applied: "iap capability"
|
|
158540
|
+
};
|
|
158541
|
+
}
|
|
158542
|
+
function withStoreBundle(dir, options) {
|
|
158543
|
+
if (options.storeBundleId) return options;
|
|
158544
|
+
const path2 = join72(dir, "store", "store.config.yaml");
|
|
158545
|
+
if (!existsSync73(path2)) return options;
|
|
158546
|
+
const storeBundleId = parseStoreConfig(readFileSync86(path2, "utf8")).ios?.bundleId;
|
|
158547
|
+
return storeBundleId ? { ...options, storeBundleId } : options;
|
|
158548
|
+
}
|
|
158549
|
+
function previewIapConfigEdit(dir, options) {
|
|
158550
|
+
const path2 = configEntry(dir);
|
|
158551
|
+
if (!path2) return void 0;
|
|
158552
|
+
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.`] };
|
|
158553
|
+
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync86(path2, "utf8"), { ...withStoreBundle(dir, options), fileName: basename18(path2) });
|
|
158554
|
+
return { path: path2, changed, applied, conflicts, instructions };
|
|
158555
|
+
}
|
|
158556
|
+
async function applyIapConfigEdit(dir, options, validate4) {
|
|
158557
|
+
const path2 = configEntry(dir);
|
|
158558
|
+
if (!path2) return void 0;
|
|
158559
|
+
const fileName = basename18(path2);
|
|
158560
|
+
const refuse7 = (why) => ({ path: path2, changed: false, applied: [], conflicts: [], instructions: [why] });
|
|
158561
|
+
if (isSymlink2(path2)) return refuse7(`${fileName} is a symlink, so it was not edited: add the purchases app in the file it points to.`);
|
|
158562
|
+
const original = readFileSync86(path2, "utf8");
|
|
158563
|
+
const edit = bindPurchasesAppInConfig(original, { ...withStoreBundle(dir, options), fileName });
|
|
158564
|
+
const { applied, conflicts, instructions } = edit;
|
|
158565
|
+
if (!edit.changed) return { path: path2, changed: false, applied, conflicts, instructions };
|
|
158566
|
+
const backup = backUpConfig(dir, "store-iap-backup", fileName, original);
|
|
158567
|
+
if (!backup) return refuse7(`.himi is not a plain directory in this package (a symlink?), so ${fileName} was not edited.`);
|
|
158568
|
+
writeFileAtomic(path2, edit.source);
|
|
158569
|
+
const introduced = await introducedErrors(dir, validate4, {
|
|
158570
|
+
restore: () => writeFileAtomic(path2, original),
|
|
158571
|
+
reapply: () => writeFileAtomic(path2, edit.source)
|
|
158572
|
+
}, () => false).catch((error) => `himi validate could not run, so the edit was not checked: ${error.message}`);
|
|
158573
|
+
if (introduced) {
|
|
158574
|
+
writeFileAtomic(path2, original);
|
|
158575
|
+
return { path: path2, changed: false, applied: [], conflicts, instructions: [`Add to ${fileName} by hand: ${applied.join(", ")}.`, ...instructions], backup, rolledBack: introduced };
|
|
158576
|
+
}
|
|
158577
|
+
return { path: path2, changed: true, applied, conflicts, instructions, backup };
|
|
158578
|
+
}
|
|
158579
|
+
var init_iap_config_edit = __esm({
|
|
158580
|
+
"src/iap-config-edit.ts"() {
|
|
158581
|
+
init_app_config_loader();
|
|
158582
|
+
init_config_source_edit();
|
|
158583
|
+
init_progress();
|
|
158584
|
+
init_preflight();
|
|
158585
|
+
init_store_spec();
|
|
158586
|
+
}
|
|
158587
|
+
});
|
|
158588
|
+
|
|
158217
158589
|
// src/store-iap-catalog.ts
|
|
158218
158590
|
function amountText(value) {
|
|
158219
158591
|
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
@@ -158369,6 +158741,287 @@ var init_store_iap_catalog = __esm({
|
|
|
158369
158741
|
}
|
|
158370
158742
|
});
|
|
158371
158743
|
|
|
158744
|
+
// src/store-iap-purchases.ts
|
|
158745
|
+
function createPurchasesOwnerApi(call) {
|
|
158746
|
+
return {
|
|
158747
|
+
listApps: async () => (await allPages(call, `${PURCHASES}/apps/query`, "apps")).map(decodeApp),
|
|
158748
|
+
registerApp: async ({ name, bundleId }) => {
|
|
158749
|
+
const reply = await call("POST", `${PURCHASES}/apps`, { app: { name, appleConfig: { bundleId } } });
|
|
158750
|
+
return decodeApp(reply.app);
|
|
158751
|
+
},
|
|
158752
|
+
setAppleCredentials: async (appId2, key2) => {
|
|
158753
|
+
await call("POST", `${PURCHASES}/apps/${encodeURIComponent(appId2)}/apple-credentials`, {
|
|
158754
|
+
inAppPurchaseKeyId: key2.keyId,
|
|
158755
|
+
issuerId: key2.issuerId,
|
|
158756
|
+
privateKey: key2.privateKey
|
|
158757
|
+
});
|
|
158758
|
+
},
|
|
158759
|
+
listProducts: async (appId2) => (await allPages(call, `${PURCHASES}/apps/${encodeURIComponent(appId2)}/products/query`, "products")).map(decodeProduct),
|
|
158760
|
+
addProduct: async (appId2, product) => {
|
|
158761
|
+
const reply = await call("POST", `${PURCHASES}/apps/${encodeURIComponent(appId2)}/products`, { product: { ...product, active: true } });
|
|
158762
|
+
return decodeProduct(reply.product);
|
|
158763
|
+
}
|
|
158764
|
+
};
|
|
158765
|
+
}
|
|
158766
|
+
function wixIapProviderConnector(call, route) {
|
|
158767
|
+
return {
|
|
158768
|
+
connect: async (appId2) => {
|
|
158769
|
+
const reply = await call("POST", `${route.prefix}/provider-account/connect`, { appId: appId2 });
|
|
158770
|
+
return { connected: reply.readiness?.providerAccountConnected === true };
|
|
158771
|
+
}
|
|
158772
|
+
};
|
|
158773
|
+
}
|
|
158774
|
+
function refusalCode(error) {
|
|
158775
|
+
const code = error?.body?.details?.applicationError?.code;
|
|
158776
|
+
return typeof code === "string" ? code : void 0;
|
|
158777
|
+
}
|
|
158778
|
+
async function allPages(call, path2, field) {
|
|
158779
|
+
const items = [];
|
|
158780
|
+
let cursor;
|
|
158781
|
+
for (let pages2 = 0; pages2 < MAX_PAGES3; pages2++) {
|
|
158782
|
+
const reply = await call("POST", path2, { query: { cursorPaging: { limit: PAGE3, ...cursor ? { cursor } : {} } } });
|
|
158783
|
+
const page = reply[field];
|
|
158784
|
+
if (!Array.isArray(page)) throw new Error(`the purchases service answered ${path2} without a ${field} list`);
|
|
158785
|
+
items.push(...page);
|
|
158786
|
+
const paging = reply.pagingMetadata;
|
|
158787
|
+
cursor = paging?.hasNext !== false && typeof paging?.cursors?.next === "string" && paging.cursors.next ? paging.cursors.next : void 0;
|
|
158788
|
+
if (!cursor) return items;
|
|
158789
|
+
}
|
|
158790
|
+
throw new Error(`${path2} had more than ${MAX_PAGES3} pages; refusing to plan from a partial ${field} list`);
|
|
158791
|
+
}
|
|
158792
|
+
function decodeApp(raw) {
|
|
158793
|
+
const app = raw;
|
|
158794
|
+
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");
|
|
158795
|
+
return { id: app.id, name: typeof app.name === "string" ? app.name : "", bundleId: app.appleConfig.bundleId, privateKeyStored: app.appleConfig.privateKeyStored === true };
|
|
158796
|
+
}
|
|
158797
|
+
function decodeProduct(raw) {
|
|
158798
|
+
const p2 = raw;
|
|
158799
|
+
if (typeof p2?.id !== "string" || typeof p2.appProductId !== "string" || typeof p2.storeProductId !== "string") {
|
|
158800
|
+
throw new Error("the purchases service returned a product without its ids");
|
|
158801
|
+
}
|
|
158802
|
+
return { id: p2.id, appProductId: p2.appProductId, storeProductId: p2.storeProductId, type: String(p2.type ?? ""), active: p2.active === true };
|
|
158803
|
+
}
|
|
158804
|
+
var PURCHASES, PAGE3, MAX_PAGES3;
|
|
158805
|
+
var init_store_iap_purchases = __esm({
|
|
158806
|
+
"src/store-iap-purchases.ts"() {
|
|
158807
|
+
PURCHASES = "/_api/mobile-apps-iap-purchases/v1";
|
|
158808
|
+
PAGE3 = 100;
|
|
158809
|
+
MAX_PAGES3 = 100;
|
|
158810
|
+
}
|
|
158811
|
+
});
|
|
158812
|
+
|
|
158813
|
+
// src/store-iap-connect.ts
|
|
158814
|
+
async function connectIap(manifest, deps, options) {
|
|
158815
|
+
const { target } = manifest;
|
|
158816
|
+
const report3 = (app2, appId2, rest) => {
|
|
158817
|
+
const steps = [app2, rest.credentials, rest.provider, ...rest.mappings];
|
|
158818
|
+
return {
|
|
158819
|
+
site: target.wixSiteId,
|
|
158820
|
+
bundleId: target.bundleId,
|
|
158821
|
+
applied: options.apply,
|
|
158822
|
+
complete: steps.every((step) => step.state === "reused" || step.state === "done"),
|
|
158823
|
+
purchasesAppId: appId2,
|
|
158824
|
+
app: app2,
|
|
158825
|
+
...rest
|
|
158826
|
+
};
|
|
158827
|
+
};
|
|
158828
|
+
const found = await findOrRegister(deps.api, manifest, options.apply);
|
|
158829
|
+
if (!found.app) {
|
|
158830
|
+
const skipped = found.step.state === "planned" ? planned : noApp;
|
|
158831
|
+
return report3(found.step, null, {
|
|
158832
|
+
credentials: found.step.state === "planned" ? credentialsPlan(deps.appleKey) : skipped("the app is not registered"),
|
|
158833
|
+
provider: found.step.state === "planned" ? providerPlan(deps.provider) : skipped("the app is not registered"),
|
|
158834
|
+
mappings: manifest.items.map((item) => mappingWithoutApp(item, found.step.state === "planned"))
|
|
158835
|
+
});
|
|
158836
|
+
}
|
|
158837
|
+
const { app } = found;
|
|
158838
|
+
const credentials = await storeKey(deps, app, options.apply);
|
|
158839
|
+
const provider = await connectProvider(deps.provider, app.id, options.apply);
|
|
158840
|
+
const mappings = await mapItems(deps.api, app.id, manifest.items, options.apply);
|
|
158841
|
+
return report3(found.step, app.id, { credentials, provider, mappings });
|
|
158842
|
+
}
|
|
158843
|
+
async function findOrRegister(api2, manifest, apply) {
|
|
158844
|
+
const { bundleId, himiApp, wixSiteId } = manifest.target;
|
|
158845
|
+
const existing = (await api2.listApps()).find((app) => app.bundleId === bundleId);
|
|
158846
|
+
if (existing) return { app: existing, step: { state: "reused", detail: `purchases app ${existing.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158847
|
+
if (!apply) return { step: { state: "planned", detail: `register ${bundleId} on site ${wixSiteId}` } };
|
|
158848
|
+
try {
|
|
158849
|
+
const app = await api2.registerApp({ name: himiApp, bundleId });
|
|
158850
|
+
return { app, step: { state: "done", detail: `registered purchases app ${app.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158851
|
+
} catch (error) {
|
|
158852
|
+
if (refusalCode(error) !== "ALREADY_EXISTS") return { step: failed("register the app", error) };
|
|
158853
|
+
let apps;
|
|
158854
|
+
try {
|
|
158855
|
+
apps = await api2.listApps();
|
|
158856
|
+
} catch (rereadError) {
|
|
158857
|
+
return { step: failed("re-read the site's purchases apps after the bundle was reported registered", rereadError) };
|
|
158858
|
+
}
|
|
158859
|
+
const raced = apps.find((app) => app.bundleId === bundleId);
|
|
158860
|
+
if (raced) return { app: raced, step: { state: "reused", detail: `purchases app ${raced.id} for ${bundleId} on site ${wixSiteId}` } };
|
|
158861
|
+
return {
|
|
158862
|
+
step: {
|
|
158863
|
+
state: "conflict",
|
|
158864
|
+
code: "bundle_registered_elsewhere",
|
|
158865
|
+
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.`
|
|
158866
|
+
}
|
|
158867
|
+
};
|
|
158868
|
+
}
|
|
158869
|
+
}
|
|
158870
|
+
async function storeKey(deps, app, apply) {
|
|
158871
|
+
if (app.privateKeyStored) return { state: "reused", detail: "an In-App Purchase key is already stored" };
|
|
158872
|
+
if (!deps.appleKey) return credentialsPlan(null);
|
|
158873
|
+
if (!apply) return credentialsPlan(deps.appleKey);
|
|
158874
|
+
try {
|
|
158875
|
+
await deps.api.setAppleCredentials(app.id, deps.appleKey);
|
|
158876
|
+
return { state: "done", detail: "stored the In-App Purchase key" };
|
|
158877
|
+
} catch (error) {
|
|
158878
|
+
return failed("store the In-App Purchase key", error);
|
|
158879
|
+
}
|
|
158880
|
+
}
|
|
158881
|
+
function credentialsPlan(key2) {
|
|
158882
|
+
return key2 ? { state: "planned", detail: "store the In-App Purchase key" } : {
|
|
158883
|
+
state: "blocked",
|
|
158884
|
+
code: "apple_key_missing",
|
|
158885
|
+
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)."
|
|
158886
|
+
};
|
|
158887
|
+
}
|
|
158888
|
+
async function connectProvider(provider, appId2, apply) {
|
|
158889
|
+
if (!provider || !apply) return providerPlan(provider);
|
|
158890
|
+
try {
|
|
158891
|
+
const { connected } = await provider.connect(appId2);
|
|
158892
|
+
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" };
|
|
158893
|
+
} catch (error) {
|
|
158894
|
+
const e2 = error;
|
|
158895
|
+
if (e2?.status === 404 && !e2.body?.details?.applicationError?.code) return providerPlan(null);
|
|
158896
|
+
return failed("connect the appleIAP provider", error);
|
|
158897
|
+
}
|
|
158898
|
+
}
|
|
158899
|
+
function providerPlan(provider) {
|
|
158900
|
+
return provider ? { state: "planned", detail: "connect the appleIAP payment provider through wix-iap" } : {
|
|
158901
|
+
state: "blocked",
|
|
158902
|
+
code: "provider_route_unavailable",
|
|
158903
|
+
detail: "the appleIAP provider is connected through Serve's IAP routes (wix-iap ConnectProviderAccount), and this Serve target has none."
|
|
158904
|
+
};
|
|
158905
|
+
}
|
|
158906
|
+
async function mapItems(api2, appId2, items, apply) {
|
|
158907
|
+
let catalog3;
|
|
158908
|
+
try {
|
|
158909
|
+
catalog3 = await api2.listProducts(appId2);
|
|
158910
|
+
} catch (error) {
|
|
158911
|
+
return items.map((item) => {
|
|
158912
|
+
const target = mappingTarget(item);
|
|
158913
|
+
return "skip" in target ? target.skip : { ...target, ...failed("read the app's catalog", error) };
|
|
158914
|
+
});
|
|
158915
|
+
}
|
|
158916
|
+
const steps = [];
|
|
158917
|
+
for (const item of items) {
|
|
158918
|
+
const target = mappingTarget(item);
|
|
158919
|
+
if ("skip" in target) {
|
|
158920
|
+
steps.push(target.skip);
|
|
158921
|
+
continue;
|
|
158922
|
+
}
|
|
158923
|
+
const decided = decide(catalog3, target);
|
|
158924
|
+
if (decided || !apply) {
|
|
158925
|
+
steps.push(decided ?? { ...target, state: "planned", detail: `map ${target.appProductId} \u2192 ${target.storeProductId}` });
|
|
158926
|
+
continue;
|
|
158927
|
+
}
|
|
158928
|
+
try {
|
|
158929
|
+
catalog3.push(await api2.addProduct(appId2, { appProductId: target.appProductId, storeProductId: target.storeProductId, type: target.type }));
|
|
158930
|
+
steps.push({ ...target, state: "done", detail: `mapped ${target.appProductId} \u2192 ${target.storeProductId}` });
|
|
158931
|
+
} catch (error) {
|
|
158932
|
+
const now = await api2.listProducts(appId2).catch(() => catalog3);
|
|
158933
|
+
steps.push(decide(now, target) ?? { ...target, ...failed("map the item", error) });
|
|
158934
|
+
}
|
|
158935
|
+
}
|
|
158936
|
+
return steps;
|
|
158937
|
+
}
|
|
158938
|
+
function mappingTarget(item) {
|
|
158939
|
+
const skip = (entity2, detail) => ({ skip: { entity: entity2, appProductId: null, storeProductId: item.productId, state: "skipped", code: "mapping_unsupported", detail } });
|
|
158940
|
+
if (!item.wix || item.unlocks?.length) {
|
|
158941
|
+
return skip(item.productId, "a consumable tier unlocks several Wix items, but a purchase pays one order item, so it cannot be mapped");
|
|
158942
|
+
}
|
|
158943
|
+
const entity = `${item.wix.entityType}:${item.wix.entityId}`;
|
|
158944
|
+
const rule = APPLE_SALE_RULES[item.wix.entityType];
|
|
158945
|
+
if (!rule) return skip(entity, `the App Store purchase flow does not support ${item.wix.entityType} items yet`);
|
|
158946
|
+
if (PRODUCT_TYPE[item.type] !== rule.productType) {
|
|
158947
|
+
return skip(entity, `the App Store purchase flow sells ${item.wix.entityType} items only as ${rule.productType}, not ${PRODUCT_TYPE[item.type]}`);
|
|
158948
|
+
}
|
|
158949
|
+
return { entity, appProductId: rule.appProductId(item.wix.entityId), storeProductId: item.productId, type: rule.productType };
|
|
158950
|
+
}
|
|
158951
|
+
function decide(catalog3, target) {
|
|
158952
|
+
const byWixItem = catalog3.find((p2) => p2.appProductId === target.appProductId);
|
|
158953
|
+
if (byWixItem) {
|
|
158954
|
+
if (byWixItem.storeProductId !== target.storeProductId) {
|
|
158955
|
+
return { ...target, state: "conflict", code: "mapping_conflict", detail: `${target.appProductId} is already mapped to ${byWixItem.storeProductId}; it was left as it is` };
|
|
158956
|
+
}
|
|
158957
|
+
if (byWixItem.type !== target.type) {
|
|
158958
|
+
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` };
|
|
158959
|
+
}
|
|
158960
|
+
if (!byWixItem.active) {
|
|
158961
|
+
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` };
|
|
158962
|
+
}
|
|
158963
|
+
return { ...target, state: "reused", detail: `${target.appProductId} \u2192 ${target.storeProductId}` };
|
|
158964
|
+
}
|
|
158965
|
+
const bySku = catalog3.find((p2) => p2.storeProductId === target.storeProductId);
|
|
158966
|
+
if (bySku) {
|
|
158967
|
+
return { ...target, state: "conflict", code: "sku_in_use", detail: `${target.storeProductId} is already mapped to ${bySku.appProductId}; it was left as it is` };
|
|
158968
|
+
}
|
|
158969
|
+
return void 0;
|
|
158970
|
+
}
|
|
158971
|
+
function mappingWithoutApp(item, planning) {
|
|
158972
|
+
const target = mappingTarget(item);
|
|
158973
|
+
if ("skip" in target) return target.skip;
|
|
158974
|
+
return planning ? { ...target, state: "planned", detail: `map ${target.appProductId} \u2192 ${target.storeProductId}` } : { ...target, ...noApp("the app is not registered") };
|
|
158975
|
+
}
|
|
158976
|
+
function planned(detail) {
|
|
158977
|
+
return { state: "planned", detail };
|
|
158978
|
+
}
|
|
158979
|
+
function noApp(why) {
|
|
158980
|
+
return { state: "skipped", code: "no_purchases_app", detail: `${why}, so this step did not run` };
|
|
158981
|
+
}
|
|
158982
|
+
function failed(what, error) {
|
|
158983
|
+
return { state: "failed", code: "request_failed", detail: `could not ${what}: ${error instanceof Error ? error.message : String(error)}` };
|
|
158984
|
+
}
|
|
158985
|
+
var PRODUCT_TYPE;
|
|
158986
|
+
var init_store_iap_connect = __esm({
|
|
158987
|
+
"src/store-iap-connect.ts"() {
|
|
158988
|
+
init_wix_payments_contract();
|
|
158989
|
+
init_store_iap_purchases();
|
|
158990
|
+
PRODUCT_TYPE = { nonConsumable: "NON_CONSUMABLE", consumable: "CONSUMABLE" };
|
|
158991
|
+
}
|
|
158992
|
+
});
|
|
158993
|
+
|
|
158994
|
+
// src/serve-preview.ts
|
|
158995
|
+
function parsePreviewTag(value) {
|
|
158996
|
+
if (value === void 0 || value === "") return void 0;
|
|
158997
|
+
if (!TAG.test(value)) throw new PreviewTagError(`invalid Serve preview tag ${JSON.stringify(value)}: expected dp-<tag> as dpx deploy-preview prints it`);
|
|
158998
|
+
return value;
|
|
158999
|
+
}
|
|
159000
|
+
function isServeRequest(url) {
|
|
159001
|
+
const u2 = new URL(String(url));
|
|
159002
|
+
return u2.protocol === "https:" && WIX_HOSTS.has(u2.hostname) && SERVE_MOUNTS.some((mount) => u2.pathname.startsWith(mount));
|
|
159003
|
+
}
|
|
159004
|
+
function servePreviewFetch(fetchImpl, previewTag) {
|
|
159005
|
+
if (!previewTag) return fetchImpl;
|
|
159006
|
+
return ((input, init) => {
|
|
159007
|
+
const url = input instanceof Request ? input.url : String(input);
|
|
159008
|
+
if (!isServeRequest(url)) return fetchImpl(input, init);
|
|
159009
|
+
const headers2 = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
159010
|
+
headers2.set("x-wix-route-serve", previewTag);
|
|
159011
|
+
return fetchImpl(input, { ...init, headers: headers2 });
|
|
159012
|
+
});
|
|
159013
|
+
}
|
|
159014
|
+
var TAG, WIX_HOSTS, SERVE_MOUNTS, PreviewTagError;
|
|
159015
|
+
var init_serve_preview = __esm({
|
|
159016
|
+
"src/serve-preview.ts"() {
|
|
159017
|
+
TAG = /^dp-[a-z0-9]+$/;
|
|
159018
|
+
WIX_HOSTS = /* @__PURE__ */ new Set(["www.wixapis.com", "bo.wix.com", "www.wix.com"]);
|
|
159019
|
+
SERVE_MOUNTS = ["/himalaya-serve/", "/_api/himalaya-serve/"];
|
|
159020
|
+
PreviewTagError = class extends Error {
|
|
159021
|
+
};
|
|
159022
|
+
}
|
|
159023
|
+
});
|
|
159024
|
+
|
|
158372
159025
|
// src/store-iap.ts
|
|
158373
159026
|
var store_iap_exports = {};
|
|
158374
159027
|
__export(store_iap_exports, {
|
|
@@ -158379,9 +159032,9 @@ __export(store_iap_exports, {
|
|
|
158379
159032
|
runStoreIap: () => runStoreIap
|
|
158380
159033
|
});
|
|
158381
159034
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
158382
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as
|
|
159035
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as readFileSync87, realpathSync as realpathSync13, rmSync as rmSync18, writeFileSync as writeFileSync30 } from "node:fs";
|
|
158383
159036
|
import { homedir as homedir8, hostname } from "node:os";
|
|
158384
|
-
import { join as
|
|
159037
|
+
import { join as join73 } from "node:path";
|
|
158385
159038
|
function scrubDeep(value, scrub) {
|
|
158386
159039
|
if (typeof value === "string") return scrub(value);
|
|
158387
159040
|
if (Array.isArray(value)) return value.map((v2) => scrubDeep(v2, scrub));
|
|
@@ -158687,6 +159340,136 @@ async function draftCommand(flags, deps, out2) {
|
|
|
158687
159340
|
}
|
|
158688
159341
|
return draft.manifest ? 0 : 1;
|
|
158689
159342
|
}
|
|
159343
|
+
function readInAppPurchaseKey(flags, deps, creds) {
|
|
159344
|
+
const path2 = textFlag(flags, "iap-key");
|
|
159345
|
+
const keyId = textFlag(flags, "iap-key-id");
|
|
159346
|
+
if (!path2 && !keyId) return null;
|
|
159347
|
+
if (!path2 || !keyId) throw new UsageError("store iap connect needs --iap-key <AuthKey.p8> and --iap-key-id <id> together");
|
|
159348
|
+
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}"`);
|
|
159349
|
+
let privateKey;
|
|
159350
|
+
try {
|
|
159351
|
+
assertCredentialOutsideRepo("--iap-key", (deps.realpath ?? realpathSync13)(path2));
|
|
159352
|
+
privateKey = readInput(deps, path2, "In-App Purchase key");
|
|
159353
|
+
} catch (error) {
|
|
159354
|
+
throw new KeyError(error.message);
|
|
159355
|
+
}
|
|
159356
|
+
if (!/-----BEGIN PRIVATE KEY-----/.test(privateKey)) throw new KeyError(`${path2} is not a PEM private key (an App Store Connect .p8 file)`);
|
|
159357
|
+
return { keyId, issuerId: creds.key.issuerId, privateKey };
|
|
159358
|
+
}
|
|
159359
|
+
function firstProblem(report3) {
|
|
159360
|
+
const steps = [report3.app, report3.credentials, report3.provider, ...report3.mappings];
|
|
159361
|
+
return steps.find((step) => step.code)?.code ?? (report3.complete ? void 0 : "setup_incomplete");
|
|
159362
|
+
}
|
|
159363
|
+
function printConnect(out2, report3, heading) {
|
|
159364
|
+
out2.line(`himi store iap connect \u2014 ${heading}`);
|
|
159365
|
+
out2.line(` ${pad("site")}${report3.site} \xB7 bundle ${report3.bundleId}`);
|
|
159366
|
+
const row = (label2, step) => out2.line(` ${pad(label2)}${step.state.padEnd(9)}${step.detail}`);
|
|
159367
|
+
row("app", report3.app);
|
|
159368
|
+
row("key", report3.credentials);
|
|
159369
|
+
row("provider", report3.provider);
|
|
159370
|
+
for (const mapping of report3.mappings) row("mapping", mapping);
|
|
159371
|
+
if (report3.purchasesAppId) out2.line(` ${pad("binding")}wixIap: { purchasesAppId: "${report3.purchasesAppId}" }`);
|
|
159372
|
+
}
|
|
159373
|
+
function printConfig(out2, config, note) {
|
|
159374
|
+
if (note) out2.line(` ${pad("config")}${note}`);
|
|
159375
|
+
if (!config) return;
|
|
159376
|
+
out2.line(` ${pad("config")}${config.changed ? `recorded ${config.applied.join(", ")} in ${config.path}` : `${config.path} unchanged`}`);
|
|
159377
|
+
for (const line of [...config.conflicts, ...config.instructions]) out2.line(` ${pad("")}${line}`);
|
|
159378
|
+
}
|
|
159379
|
+
async function recordBinding(flags, deps, report3, apply) {
|
|
159380
|
+
const dir = textFlag(flags, "content");
|
|
159381
|
+
const wanted = report3.purchasesAppId ? `wixIap: { purchasesAppId: "${report3.purchasesAppId}" }` : void 0;
|
|
159382
|
+
if (!dir) return { note: wanted ? `add ${wanted} and "iap" in capabilities to the app's config (or rerun with --content <dir>)` : void 0 };
|
|
159383
|
+
if (!report3.purchasesAppId) return { note: `${dir} was not edited: there is no purchases app on the site yet`, unapplied: true };
|
|
159384
|
+
const options = { purchasesAppId: report3.purchasesAppId, siteId: report3.site, bundleId: report3.bundleId };
|
|
159385
|
+
const validate4 = deps.validateConfig;
|
|
159386
|
+
let config;
|
|
159387
|
+
if (!apply) config = previewIapConfigEdit(dir, options);
|
|
159388
|
+
else if (!validate4) return { note: `${dir} was not edited (himi validate is unavailable here): add ${wanted} by hand`, unapplied: true };
|
|
159389
|
+
else config = await applyIapConfigEdit(dir, options, validate4);
|
|
159390
|
+
if (!config) return { note: `${dir} has no config.ts, so it was not edited: add ${wanted} to the app's config`, unapplied: true };
|
|
159391
|
+
return { config, unapplied: config.instructions.length > 0 };
|
|
159392
|
+
}
|
|
159393
|
+
async function connectCommand(flags, deps, out2) {
|
|
159394
|
+
try {
|
|
159395
|
+
return await connectWith(flags, deps, out2);
|
|
159396
|
+
} catch (error) {
|
|
159397
|
+
if (error instanceof UsageError) return out2.fail(error.message, { ok: false, code: "invalid_usage", usage: STORE_IAP_USAGE });
|
|
159398
|
+
if (error instanceof IapManifestError) {
|
|
159399
|
+
return out2.fail(`${error.label} is not a valid IAP manifest`, { ok: false, code: "manifest_invalid", problems: error.problems });
|
|
159400
|
+
}
|
|
159401
|
+
if (error instanceof CredentialsError) return out2.fail(error.message, { ok: false, code: "credentials_unavailable" });
|
|
159402
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "connect_failed" });
|
|
159403
|
+
}
|
|
159404
|
+
}
|
|
159405
|
+
async function connectWith(flags, deps, out2) {
|
|
159406
|
+
const manifestPath = requireFlag(flags, "manifest", "connect");
|
|
159407
|
+
const profile = requireFlag(flags, "profile", "connect");
|
|
159408
|
+
const dryRun = flags["dry-run"] === true;
|
|
159409
|
+
let previewTag;
|
|
159410
|
+
try {
|
|
159411
|
+
previewTag = parsePreviewTag(textFlag(flags, "preview-tag") ?? process.env.HIMI_SERVE_PREVIEW_TAG);
|
|
159412
|
+
} catch (error) {
|
|
159413
|
+
throw new UsageError(error.message);
|
|
159414
|
+
}
|
|
159415
|
+
const manifest = readManifest2(deps, manifestPath);
|
|
159416
|
+
let creds;
|
|
159417
|
+
try {
|
|
159418
|
+
creds = deps.resolveCredentials({ profileFlag: profile, target: manifest.target });
|
|
159419
|
+
} catch (error) {
|
|
159420
|
+
throw new CredentialsError(error instanceof Error ? error.message : String(error));
|
|
159421
|
+
}
|
|
159422
|
+
out2.protect(creds);
|
|
159423
|
+
let appleKey;
|
|
159424
|
+
try {
|
|
159425
|
+
appleKey = readInAppPurchaseKey(flags, deps, creds);
|
|
159426
|
+
} catch (error) {
|
|
159427
|
+
if (error instanceof KeyError) return out2.fail(error.message, { ok: false, code: "iap_key_unreadable" });
|
|
159428
|
+
throw error;
|
|
159429
|
+
}
|
|
159430
|
+
if (appleKey) out2.protectKey(appleKey);
|
|
159431
|
+
const transport = deps.wixTransport(manifest.target.wixSiteId);
|
|
159432
|
+
const route = deps.wixIapRoute();
|
|
159433
|
+
const serve = route ? deps.serveTransport?.(manifest.target.wixSiteId, previewTag) ?? transport : transport;
|
|
159434
|
+
const connectDeps = { api: createPurchasesOwnerApi(transport), appleKey, provider: route ? wixIapProviderConnector(serve, route) : null };
|
|
159435
|
+
let plan;
|
|
159436
|
+
try {
|
|
159437
|
+
plan = await connectIap(manifest, connectDeps, { apply: false });
|
|
159438
|
+
} catch (error) {
|
|
159439
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "request_failed" });
|
|
159440
|
+
}
|
|
159441
|
+
let report3 = plan;
|
|
159442
|
+
if (!dryRun && writesPlanned(plan)) {
|
|
159443
|
+
const confirmed = flags.yes === true;
|
|
159444
|
+
if (!confirmed && !(out2.interactive && !out2.json && deps.canPrompt())) {
|
|
159445
|
+
return out2.fail(
|
|
159446
|
+
"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.",
|
|
159447
|
+
{ ok: false, code: "confirmation_required", manifest: manifestPath }
|
|
159448
|
+
);
|
|
159449
|
+
}
|
|
159450
|
+
if (!out2.json) printConnect(out2, plan, "plan");
|
|
159451
|
+
if (!confirmed && !await deps.confirm(`Apply this In-App Purchases setup to Wix site ${manifest.target.wixSiteId}?`)) {
|
|
159452
|
+
out2.line(" aborted \u2014 nothing was changed on the Wix site.");
|
|
159453
|
+
return 1;
|
|
159454
|
+
}
|
|
159455
|
+
try {
|
|
159456
|
+
report3 = await connectIap(manifest, connectDeps, { apply: true });
|
|
159457
|
+
} catch (error) {
|
|
159458
|
+
return out2.fail(error instanceof Error ? error.message : String(error), { ok: false, code: "request_failed" });
|
|
159459
|
+
}
|
|
159460
|
+
}
|
|
159461
|
+
const { config, note, unapplied } = await recordBinding(flags, deps, report3, !dryRun);
|
|
159462
|
+
const outPath = textFlag(flags, "out");
|
|
159463
|
+
if (outPath) writeJson(deps, out2, outPath, { report: report3, config });
|
|
159464
|
+
const configProblem = config?.conflicts.length ? "config_conflict" : unapplied ? "config_not_applied" : void 0;
|
|
159465
|
+
const code = firstProblem(report3) ?? configProblem;
|
|
159466
|
+
if (out2.json) out2.print({ ok: !code, ...code ? { code } : {}, dryRun, report: report3, config, ...note ? { note } : {} });
|
|
159467
|
+
else {
|
|
159468
|
+
printConnect(out2, report3, dryRun ? "dry run (nothing was written)" : "result");
|
|
159469
|
+
printConfig(out2, config, note);
|
|
159470
|
+
}
|
|
159471
|
+
return code ? 1 : 0;
|
|
159472
|
+
}
|
|
158690
159473
|
async function runStoreIap(pos, flags, io2, deps) {
|
|
158691
159474
|
const out2 = new CommandOutput(io2, flags.json === true);
|
|
158692
159475
|
const sub = pos[2];
|
|
@@ -158707,17 +159490,17 @@ function fileJournal(path2) {
|
|
|
158707
159490
|
}
|
|
158708
159491
|
function readLockSummary(path2) {
|
|
158709
159492
|
try {
|
|
158710
|
-
const { pid, host, at: at2 } = JSON.parse(
|
|
159493
|
+
const { pid, host, at: at2 } = JSON.parse(readFileSync87(path2, "utf8"));
|
|
158711
159494
|
return `pid ${pid} on ${host} since ${at2}`;
|
|
158712
159495
|
} catch {
|
|
158713
159496
|
return "unreadable lock";
|
|
158714
159497
|
}
|
|
158715
159498
|
}
|
|
158716
159499
|
function acquireApplyLock(dir, appleAppId) {
|
|
158717
|
-
const path2 =
|
|
159500
|
+
const path2 = join73(dir, "apply.lock");
|
|
158718
159501
|
const stamp = JSON.stringify({ pid: process.pid, host: hostname(), at: (/* @__PURE__ */ new Date()).toISOString(), token: randomUUID8() });
|
|
158719
159502
|
try {
|
|
158720
|
-
|
|
159503
|
+
writeFileSync30(path2, stamp, { flag: "wx", mode: 384 });
|
|
158721
159504
|
} catch (e2) {
|
|
158722
159505
|
if (e2.code !== "EEXIST") throw e2;
|
|
158723
159506
|
throw new Error(
|
|
@@ -158727,7 +159510,7 @@ function acquireApplyLock(dir, appleAppId) {
|
|
|
158727
159510
|
return () => {
|
|
158728
159511
|
let current = "";
|
|
158729
159512
|
try {
|
|
158730
|
-
current =
|
|
159513
|
+
current = readFileSync87(path2, "utf8");
|
|
158731
159514
|
} catch {
|
|
158732
159515
|
return;
|
|
158733
159516
|
}
|
|
@@ -158735,7 +159518,7 @@ function acquireApplyLock(dir, appleAppId) {
|
|
|
158735
159518
|
};
|
|
158736
159519
|
}
|
|
158737
159520
|
function stateDir(appleAppId) {
|
|
158738
|
-
const dir =
|
|
159521
|
+
const dir = join73(homedir8(), ".himalaya", "store-iap", appleAppId);
|
|
158739
159522
|
mkdirSync34(dir, { recursive: true, mode: 448 });
|
|
158740
159523
|
return dir;
|
|
158741
159524
|
}
|
|
@@ -158751,21 +159534,25 @@ async function confirmOnTerminal(question) {
|
|
|
158751
159534
|
}
|
|
158752
159535
|
function defaultStoreIapDeps() {
|
|
158753
159536
|
return {
|
|
158754
|
-
readFile: (path2) =>
|
|
159537
|
+
readFile: (path2) => readFileSync87(path2, "utf8"),
|
|
158755
159538
|
writeFileAtomic,
|
|
158756
159539
|
resolveCredentials: ({ profileFlag, target }) => resolveIapCredentials({ profileFlag, target }),
|
|
158757
159540
|
createApi: (key2) => createIapApi(createAscClient({ key: key2 })),
|
|
158758
|
-
openJournal: (appleAppId) => fileJournal(
|
|
159541
|
+
openJournal: (appleAppId) => fileJournal(join73(stateDir(appleAppId), "journal.jsonl")),
|
|
158759
159542
|
acquireLock: (appleAppId) => acquireApplyLock(stateDir(appleAppId), appleAppId),
|
|
158760
159543
|
canPrompt: () => process.stdin.isTTY === true,
|
|
158761
159544
|
wixTransport: (siteId) => ownerTransport(siteId),
|
|
159545
|
+
// Serve's owner-only ConnectProviderAccount route; Serve answers 404 while its IAP routes are off.
|
|
159546
|
+
wixIapRoute: () => HIMALAYA_SERVE_IAP_ROUTE,
|
|
159547
|
+
// Serve's provider route requires a Wix user, so never the API key the purchases calls may use.
|
|
159548
|
+
serveTransport: (siteId, previewTag) => ownerTransport(siteId, servePreviewFetch(fetch, previewTag), void 0, userSiteToken),
|
|
158762
159549
|
profileTeam: (profile) => resolveStoreCredentials({ app: profile, cfg: {}, profileFlag: profile, env: {} }).team,
|
|
158763
159550
|
confirm: confirmOnTerminal,
|
|
158764
159551
|
now: () => /* @__PURE__ */ new Date(),
|
|
158765
159552
|
sleep: (ms2) => new Promise((resolve61) => setTimeout(resolve61, ms2))
|
|
158766
159553
|
};
|
|
158767
159554
|
}
|
|
158768
|
-
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;
|
|
159555
|
+
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;
|
|
158769
159556
|
var init_store_iap = __esm({
|
|
158770
159557
|
"src/store-iap.ts"() {
|
|
158771
159558
|
init_iap_api();
|
|
@@ -158773,15 +159560,21 @@ var init_store_iap = __esm({
|
|
|
158773
159560
|
init_iap_client();
|
|
158774
159561
|
init_credential_profile();
|
|
158775
159562
|
init_iap_credentials();
|
|
159563
|
+
init_preflight();
|
|
159564
|
+
init_wix_payments_contract();
|
|
158776
159565
|
init_iap_draft();
|
|
158777
159566
|
init_iap_manifest();
|
|
158778
159567
|
init_iap_pricing();
|
|
158779
159568
|
init_iap_plan();
|
|
158780
159569
|
init_redact();
|
|
158781
159570
|
init_progress();
|
|
159571
|
+
init_iap_config_edit();
|
|
158782
159572
|
init_store_iap_catalog();
|
|
159573
|
+
init_store_iap_connect();
|
|
159574
|
+
init_store_iap_purchases();
|
|
159575
|
+
init_serve_preview();
|
|
158783
159576
|
init_wix_owner();
|
|
158784
|
-
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>]";
|
|
159577
|
+
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>]";
|
|
158785
159578
|
SUMMARY_THRESHOLD = 50;
|
|
158786
159579
|
SUMMARY_DETAIL_LIMIT = 20;
|
|
158787
159580
|
UsageError = class extends Error {
|
|
@@ -158798,6 +159591,9 @@ var init_store_iap = __esm({
|
|
|
158798
159591
|
protect(creds) {
|
|
158799
159592
|
this.secrets.push(creds.key.privateKeyPem, creds.key.issuerId, creds.key.keyId);
|
|
158800
159593
|
}
|
|
159594
|
+
protectKey(key2) {
|
|
159595
|
+
this.secrets.push(key2.privateKey, key2.keyId);
|
|
159596
|
+
}
|
|
158801
159597
|
line(text9 = "") {
|
|
158802
159598
|
this.io.log(this.scrub(text9));
|
|
158803
159599
|
}
|
|
@@ -158829,11 +159625,17 @@ var init_store_iap = __esm({
|
|
|
158829
159625
|
TERRITORY_CODE = /^[A-Z]{3}$/;
|
|
158830
159626
|
LOCALE_CODE = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
158831
159627
|
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";
|
|
159628
|
+
KeyError = class extends Error {
|
|
159629
|
+
};
|
|
159630
|
+
CredentialsError = class extends Error {
|
|
159631
|
+
};
|
|
159632
|
+
writesPlanned = (report3) => [report3.app, report3.credentials, report3.provider, ...report3.mappings].some((step) => step.state === "planned");
|
|
158832
159633
|
COMMANDS = {
|
|
158833
159634
|
draft: draftCommand,
|
|
158834
159635
|
plan: planCommand,
|
|
158835
159636
|
apply: applyCommand,
|
|
158836
|
-
status: statusCommand
|
|
159637
|
+
status: statusCommand,
|
|
159638
|
+
connect: connectCommand
|
|
158837
159639
|
};
|
|
158838
159640
|
}
|
|
158839
159641
|
});
|
|
@@ -159214,9 +160016,9 @@ __export(preflight_app_exports, {
|
|
|
159214
160016
|
preflightApp: () => preflightApp,
|
|
159215
160017
|
profileAccount: () => profileAccount
|
|
159216
160018
|
});
|
|
159217
|
-
import { readFileSync as
|
|
160019
|
+
import { readFileSync as readFileSync88, existsSync as existsSync74, readdirSync as readdirSync33, statSync as statSync19 } from "node:fs";
|
|
159218
160020
|
import { createHash as createHash39 } from "node:crypto";
|
|
159219
|
-
import { join as
|
|
160021
|
+
import { join as join74 } from "node:path";
|
|
159220
160022
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
159221
160023
|
const f2 = [];
|
|
159222
160024
|
const has = (re2, s2) => re2.test(s2);
|
|
@@ -159280,13 +160082,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
159280
160082
|
}
|
|
159281
160083
|
}
|
|
159282
160084
|
async function preflightApp(app, opts = {}) {
|
|
159283
|
-
const projectYml =
|
|
159284
|
-
const storeConfig =
|
|
160085
|
+
const projectYml = existsSync74(iosProjectYml(app)) ? readFileSync88(iosProjectYml(app), "utf8") : "";
|
|
160086
|
+
const storeConfig = existsSync74(storeConfigPath(app)) ? readFileSync88(storeConfigPath(app), "utf8") : "";
|
|
159285
160087
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
159286
160088
|
const findings = analyze(
|
|
159287
160089
|
projectYml,
|
|
159288
160090
|
storeConfig,
|
|
159289
|
-
await appIconState(
|
|
160091
|
+
await appIconState(join74(appDir(app), "ios")),
|
|
159290
160092
|
profileAccount(app, storeConfig, opts)
|
|
159291
160093
|
);
|
|
159292
160094
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -159315,17 +160117,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
159315
160117
|
return f2;
|
|
159316
160118
|
}
|
|
159317
160119
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
159318
|
-
const root =
|
|
160120
|
+
const root = join74(storeDir(app), "metadata");
|
|
159319
160121
|
const out2 = /* @__PURE__ */ new Set();
|
|
159320
|
-
if (
|
|
160122
|
+
if (existsSync74(root)) {
|
|
159321
160123
|
for (const n2 of readdirSync33(root)) if (n2.endsWith(".txt")) out2.add(n2);
|
|
159322
160124
|
}
|
|
159323
|
-
if (
|
|
160125
|
+
if (existsSync74(join74(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
|
|
159324
160126
|
return out2;
|
|
159325
160127
|
}
|
|
159326
160128
|
function reviewInfoFiles(app) {
|
|
159327
|
-
const dir =
|
|
159328
|
-
if (!
|
|
160129
|
+
const dir = join74(storeDir(app), "review_information");
|
|
160130
|
+
if (!existsSync74(dir)) return /* @__PURE__ */ new Set();
|
|
159329
160131
|
return new Set(readdirSync33(dir).filter((n2) => n2.endsWith(".txt")));
|
|
159330
160132
|
}
|
|
159331
160133
|
function isValidAppStoreSize(w2, h2) {
|
|
@@ -159435,12 +160237,12 @@ function analyzePlayListing(assets) {
|
|
|
159435
160237
|
return f2;
|
|
159436
160238
|
}
|
|
159437
160239
|
function playListingAssets(app, locale = "en-US") {
|
|
159438
|
-
const dir =
|
|
160240
|
+
const dir = join74(storeDir(app), "play", locale, "images");
|
|
159439
160241
|
const read = (names) => {
|
|
159440
160242
|
for (const name of names) {
|
|
159441
|
-
const p2 =
|
|
160243
|
+
const p2 = join74(dir, name);
|
|
159442
160244
|
try {
|
|
159443
|
-
if (statSync19(p2).isFile()) return { name, bytes:
|
|
160245
|
+
if (statSync19(p2).isFile()) return { name, bytes: readFileSync88(p2) };
|
|
159444
160246
|
} catch {
|
|
159445
160247
|
}
|
|
159446
160248
|
}
|
|
@@ -159471,26 +160273,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
159471
160273
|
return f2;
|
|
159472
160274
|
}
|
|
159473
160275
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
159474
|
-
const dir =
|
|
159475
|
-
if (!
|
|
160276
|
+
const dir = join74(storeDir(app), "metadata", locale);
|
|
160277
|
+
if (!existsSync74(dir)) return /* @__PURE__ */ new Set();
|
|
159476
160278
|
return new Set(readdirSync33(dir).filter((n2) => n2.endsWith(".txt")));
|
|
159477
160279
|
}
|
|
159478
160280
|
function listScreenshots(app, locale = "en-US") {
|
|
159479
160281
|
const out2 = [];
|
|
159480
|
-
const flat =
|
|
159481
|
-
if (
|
|
160282
|
+
const flat = join74(storeDir(app), "screenshots", locale);
|
|
160283
|
+
if (existsSync74(flat)) {
|
|
159482
160284
|
for (const png of readdirSync33(flat).filter((n2) => n2.endsWith(".png"))) {
|
|
159483
|
-
const sz = pngSize(
|
|
160285
|
+
const sz = pngSize(readFileSync88(join74(flat, png)));
|
|
159484
160286
|
if (sz) out2.push({ name: png, w: sz.w, h: sz.h });
|
|
159485
160287
|
}
|
|
159486
160288
|
}
|
|
159487
|
-
const legacy =
|
|
159488
|
-
if (
|
|
160289
|
+
const legacy = join74(storeDir(app), "metadata", locale, "screenshots");
|
|
160290
|
+
if (existsSync74(legacy)) {
|
|
159489
160291
|
for (const deviceDir of readdirSync33(legacy)) {
|
|
159490
|
-
const d2 =
|
|
160292
|
+
const d2 = join74(legacy, deviceDir);
|
|
159491
160293
|
if (!statSync19(d2).isDirectory()) continue;
|
|
159492
160294
|
for (const png of readdirSync33(d2).filter((n2) => n2.endsWith(".png"))) {
|
|
159493
|
-
const sz = pngSize(
|
|
160295
|
+
const sz = pngSize(readFileSync88(join74(d2, png)));
|
|
159494
160296
|
if (sz) out2.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
159495
160297
|
}
|
|
159496
160298
|
}
|
|
@@ -159498,13 +160300,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
159498
160300
|
return out2;
|
|
159499
160301
|
}
|
|
159500
160302
|
function placeholderHashes2() {
|
|
159501
|
-
const templateIos =
|
|
159502
|
-
if (!
|
|
160303
|
+
const templateIos = join74(appDir("_template"), "ios");
|
|
160304
|
+
if (!existsSync74(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
159503
160305
|
for (const target of readdirSync33(templateIos)) {
|
|
159504
|
-
const p2 =
|
|
160306
|
+
const p2 = join74(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
159505
160307
|
try {
|
|
159506
160308
|
if (!statSync19(p2).isFile()) continue;
|
|
159507
|
-
return [LEGACY_PLACEHOLDER_SHA2562, createHash39("sha256").update(
|
|
160309
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash39("sha256").update(readFileSync88(p2)).digest("hex")];
|
|
159508
160310
|
} catch {
|
|
159509
160311
|
}
|
|
159510
160312
|
}
|
|
@@ -159535,12 +160337,12 @@ async function pixelIssues(bytes2) {
|
|
|
159535
160337
|
}
|
|
159536
160338
|
}
|
|
159537
160339
|
async function appIconState(iosDir) {
|
|
159538
|
-
if (!
|
|
160340
|
+
if (!existsSync74(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
159539
160341
|
for (const target of readdirSync33(iosDir)) {
|
|
159540
|
-
const p2 =
|
|
160342
|
+
const p2 = join74(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
159541
160343
|
try {
|
|
159542
160344
|
if (!statSync19(p2).isFile()) continue;
|
|
159543
|
-
const bytes2 =
|
|
160345
|
+
const bytes2 = readFileSync88(p2);
|
|
159544
160346
|
const hash2 = createHash39("sha256").update(bytes2).digest("hex");
|
|
159545
160347
|
const pixels = await pixelIssues(bytes2);
|
|
159546
160348
|
return {
|
|
@@ -159601,195 +160403,13 @@ var init_preflight_app = __esm({
|
|
|
159601
160403
|
}
|
|
159602
160404
|
});
|
|
159603
160405
|
|
|
159604
|
-
// ../store-release/version.ts
|
|
159605
|
-
var version_exports = {};
|
|
159606
|
-
__export(version_exports, {
|
|
159607
|
-
bumpVersion: () => bumpVersion,
|
|
159608
|
-
readAndroidVersion: () => readAndroidVersion,
|
|
159609
|
-
readAndroidVersionName: () => readAndroidVersionName,
|
|
159610
|
-
readIosMarketingVersion: () => readIosMarketingVersion,
|
|
159611
|
-
readIosVersion: () => readIosVersion,
|
|
159612
|
-
readIosVersionStrings: () => readIosVersionStrings,
|
|
159613
|
-
readIosVersionStringsOrNull: () => readIosVersionStringsOrNull,
|
|
159614
|
-
readTargetVersionKeys: () => readTargetVersionKeys,
|
|
159615
|
-
readTargetVersionStrings: () => readTargetVersionStrings,
|
|
159616
|
-
setAndroidVersion: () => setAndroidVersion,
|
|
159617
|
-
setIosVersion: () => setIosVersion,
|
|
159618
|
-
stampIosVersionStrings: () => stampIosVersionStrings,
|
|
159619
|
-
stampTargetVersion: () => stampTargetVersion,
|
|
159620
|
-
stampVersionKeys: () => stampVersionKeys
|
|
159621
|
-
});
|
|
159622
|
-
import { readFileSync as readFileSync87, writeFileSync as writeFileSync30 } from "node:fs";
|
|
159623
|
-
function readIosVersion(projectYml) {
|
|
159624
|
-
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159625
|
-
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
159626
|
-
if (marketing === null || build3 === null) {
|
|
159627
|
-
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
159628
|
-
}
|
|
159629
|
-
return { marketing, build: Number(build3) };
|
|
159630
|
-
}
|
|
159631
|
-
function setIosVersion(projectYml, v2) {
|
|
159632
|
-
let out2 = replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing);
|
|
159633
|
-
out2 = replaceScalar(out2, "CFBundleVersion", String(v2.build));
|
|
159634
|
-
out2 = out2.replace(
|
|
159635
|
-
/(^[ \t]*# >>> himalaya:live-activity:target[^\n]*\n)([\s\S]*?)(^[ \t]*# <<< himalaya:live-activity:target[^\n]*$)/m,
|
|
159636
|
-
(_match, start, body, end) => {
|
|
159637
|
-
if (!body.trim()) return start + body + end;
|
|
159638
|
-
return start + replaceScalar(replaceScalar(body, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", String(v2.build)) + end;
|
|
159639
|
-
}
|
|
159640
|
-
);
|
|
159641
|
-
return out2;
|
|
159642
|
-
}
|
|
159643
|
-
function readIosVersionStrings(projectYml) {
|
|
159644
|
-
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159645
|
-
const build3 = matchScalar(projectYml, "CFBundleVersion");
|
|
159646
|
-
if (marketing === null || build3 === null) {
|
|
159647
|
-
throw new Error("project.yml is missing CFBundleShortVersionString / CFBundleVersion");
|
|
159648
|
-
}
|
|
159649
|
-
return { marketing, build: build3 };
|
|
159650
|
-
}
|
|
159651
|
-
function readIosVersionStringsOrNull(projectYml) {
|
|
159652
|
-
try {
|
|
159653
|
-
return readIosVersionStrings(projectYml);
|
|
159654
|
-
} catch {
|
|
159655
|
-
return null;
|
|
159656
|
-
}
|
|
159657
|
-
}
|
|
159658
|
-
function stampIosVersionStrings(projectYml, v2) {
|
|
159659
|
-
return replaceScalar(replaceScalar(projectYml, "CFBundleShortVersionString", v2.marketing), "CFBundleVersion", v2.build);
|
|
159660
|
-
}
|
|
159661
|
-
function stampVersionKeys(projectYml, v2) {
|
|
159662
|
-
let out2 = projectYml;
|
|
159663
|
-
if (v2.marketing !== void 0) out2 = replaceScalar(out2, "CFBundleShortVersionString", v2.marketing);
|
|
159664
|
-
if (v2.build !== void 0) out2 = replaceScalar(out2, "CFBundleVersion", v2.build);
|
|
159665
|
-
return out2;
|
|
159666
|
-
}
|
|
159667
|
-
function targetBlock(lines, target) {
|
|
159668
|
-
const head = new RegExp(`^ {2}${target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*$`);
|
|
159669
|
-
const start = lines.findIndex((l2) => head.test(l2));
|
|
159670
|
-
if (start < 0) return null;
|
|
159671
|
-
let end = start + 1;
|
|
159672
|
-
while (end < lines.length && !/^ {0,2}\S/.test(lines[end])) end++;
|
|
159673
|
-
return { start, end };
|
|
159674
|
-
}
|
|
159675
|
-
function readTargetVersionStrings(projectYml, target) {
|
|
159676
|
-
const lines = projectYml.split("\n");
|
|
159677
|
-
const block = targetBlock(lines, target);
|
|
159678
|
-
if (!block) return null;
|
|
159679
|
-
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
159680
|
-
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
159681
|
-
const build3 = matchScalar(body, "CFBundleVersion");
|
|
159682
|
-
return marketing !== null && build3 !== null ? { marketing, build: build3 } : null;
|
|
159683
|
-
}
|
|
159684
|
-
function readTargetVersionKeys(projectYml, target) {
|
|
159685
|
-
const lines = projectYml.split("\n");
|
|
159686
|
-
const block = targetBlock(lines, target);
|
|
159687
|
-
if (!block) return null;
|
|
159688
|
-
const body = lines.slice(block.start + 1, block.end).join("\n");
|
|
159689
|
-
const marketing = matchScalar(body, "CFBundleShortVersionString");
|
|
159690
|
-
const build3 = matchScalar(body, "CFBundleVersion");
|
|
159691
|
-
if (marketing === null && build3 === null) return null;
|
|
159692
|
-
return { ...marketing !== null ? { marketing } : {}, ...build3 !== null ? { build: build3 } : {} };
|
|
159693
|
-
}
|
|
159694
|
-
function stampTargetVersion(yml, target, v2) {
|
|
159695
|
-
const lines = yml.split("\n");
|
|
159696
|
-
const block = targetBlock(lines, target);
|
|
159697
|
-
if (!block) return yml;
|
|
159698
|
-
for (let i2 = block.start + 1; i2 < block.end; i2++) {
|
|
159699
|
-
const inline = /^ {4}info:\s*\{\s*path:\s*([^\s,}]+)\s*\}\s*(#.*)?$/.exec(lines[i2]);
|
|
159700
|
-
if (inline) {
|
|
159701
|
-
lines.splice(i2, 1, " info:", ` path: ${inline[1]}`);
|
|
159702
|
-
block.end++;
|
|
159703
|
-
break;
|
|
159704
|
-
}
|
|
159705
|
-
}
|
|
159706
|
-
const { start, end } = block;
|
|
159707
|
-
const want = {};
|
|
159708
|
-
if (v2.marketing !== void 0) want.CFBundleShortVersionString = v2.marketing;
|
|
159709
|
-
if (v2.build !== void 0) want.CFBundleVersion = v2.build;
|
|
159710
|
-
const seen = /* @__PURE__ */ new Set();
|
|
159711
|
-
let infoAt = -1;
|
|
159712
|
-
let propsAt = -1;
|
|
159713
|
-
for (let i2 = start + 1; i2 < end; i2++) {
|
|
159714
|
-
if (/^ {4}info:\s*$/.test(lines[i2])) infoAt = i2;
|
|
159715
|
-
if (infoAt >= 0 && /^ {6}properties:\s*$/.test(lines[i2]) && lines.slice(infoAt + 1, i2).every((l2) => !/^ {4}\S/.test(l2))) propsAt = i2;
|
|
159716
|
-
const m2 = /^(\s+)(CFBundleShortVersionString|CFBundleVersion):\s*.*$/.exec(lines[i2]);
|
|
159717
|
-
if (m2 && m2[2] in want) {
|
|
159718
|
-
lines[i2] = `${m2[1]}${m2[2]}: "${want[m2[2]]}"`;
|
|
159719
|
-
seen.add(m2[2]);
|
|
159720
|
-
}
|
|
159721
|
-
}
|
|
159722
|
-
const missing = Object.keys(want).filter((k2) => !seen.has(k2)).map((k2) => ` ${k2}: "${want[k2]}"`);
|
|
159723
|
-
if (missing.length && propsAt >= 0) {
|
|
159724
|
-
lines.splice(propsAt + 1, 0, ...missing);
|
|
159725
|
-
} else if (missing.length && infoAt >= 0) {
|
|
159726
|
-
let after = infoAt + 1;
|
|
159727
|
-
while (after < end && /^ {6}\S/.test(lines[after])) after++;
|
|
159728
|
-
lines.splice(after, 0, " properties:", ...missing);
|
|
159729
|
-
}
|
|
159730
|
-
return lines.join("\n");
|
|
159731
|
-
}
|
|
159732
|
-
function readIosMarketingVersion(projectYml) {
|
|
159733
|
-
return matchScalar(projectYml, "CFBundleShortVersionString");
|
|
159734
|
-
}
|
|
159735
|
-
function scalarRe(key2) {
|
|
159736
|
-
return new RegExp(`^(\\s*${key2}:\\s*)("?)([^"\\n#]*?)("?)(\\s*(?:#.*)?)$`, "m");
|
|
159737
|
-
}
|
|
159738
|
-
function matchScalar(content, key2) {
|
|
159739
|
-
const m2 = scalarRe(key2).exec(content);
|
|
159740
|
-
return m2 ? m2[3].trim() : null;
|
|
159741
|
-
}
|
|
159742
|
-
function replaceScalar(content, key2, value) {
|
|
159743
|
-
const re2 = scalarRe(key2);
|
|
159744
|
-
if (!re2.test(content)) throw new Error(`could not locate \`${key2}:\` in project.yml`);
|
|
159745
|
-
return content.replace(re2, (_full, pre, openQ, _oldVal, _closeQ, tail) => {
|
|
159746
|
-
const q2 = openQ ? '"' : "";
|
|
159747
|
-
return `${pre}${q2}${value}${q2}${tail}`;
|
|
159748
|
-
});
|
|
159749
|
-
}
|
|
159750
|
-
function readAndroidVersion(gradle) {
|
|
159751
|
-
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
159752
|
-
const code = /(\bversionCode\s*=\s*)(\d+)/.exec(gradle);
|
|
159753
|
-
if (!name || !code) throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
159754
|
-
return { marketing: name[2], build: Number(code[2]) };
|
|
159755
|
-
}
|
|
159756
|
-
function readAndroidVersionName(gradle) {
|
|
159757
|
-
const name = /(\bversionName\s*=\s*")([^"]*)(")/.exec(gradle);
|
|
159758
|
-
return name ? name[2] : null;
|
|
159759
|
-
}
|
|
159760
|
-
function setAndroidVersion(gradle, v2) {
|
|
159761
|
-
if (!/\bversionName\s*=\s*"/.test(gradle) || !/\bversionCode\s*=\s*\d+/.test(gradle)) {
|
|
159762
|
-
throw new Error("build.gradle.kts is missing versionName / versionCode");
|
|
159763
|
-
}
|
|
159764
|
-
return gradle.replace(/(\bversionName\s*=\s*")[^"]*(")/, `$1${v2.marketing}$2`).replace(/(\bversionCode\s*=\s*)\d+/, `$1${v2.build}`);
|
|
159765
|
-
}
|
|
159766
|
-
function bumpVersion(app, opts) {
|
|
159767
|
-
const iosPath = iosProjectYml(app);
|
|
159768
|
-
const gradlePath = androidGradle(app);
|
|
159769
|
-
const iosYml = readFileSync87(iosPath, "utf8");
|
|
159770
|
-
const gradle = readFileSync87(gradlePath, "utf8");
|
|
159771
|
-
const current = readIosVersion(iosYml);
|
|
159772
|
-
const next = {
|
|
159773
|
-
marketing: opts.marketing ?? current.marketing,
|
|
159774
|
-
build: opts.build === "increment" || opts.build === void 0 ? current.build + (opts.build === "increment" ? 1 : 0) : opts.build
|
|
159775
|
-
};
|
|
159776
|
-
writeFileSync30(iosPath, setIosVersion(iosYml, next));
|
|
159777
|
-
writeFileSync30(gradlePath, setAndroidVersion(gradle, next));
|
|
159778
|
-
return next;
|
|
159779
|
-
}
|
|
159780
|
-
var init_version = __esm({
|
|
159781
|
-
"../store-release/version.ts"() {
|
|
159782
|
-
init_paths2();
|
|
159783
|
-
}
|
|
159784
|
-
});
|
|
159785
|
-
|
|
159786
160406
|
// ../store-release/asc-status.ts
|
|
159787
160407
|
var asc_status_exports = {};
|
|
159788
160408
|
__export(asc_status_exports, {
|
|
159789
160409
|
ascStatus: () => ascStatus,
|
|
159790
160410
|
buildVerdict: () => buildVerdict
|
|
159791
160411
|
});
|
|
159792
|
-
import { readFileSync as
|
|
160412
|
+
import { readFileSync as readFileSync89 } from "node:fs";
|
|
159793
160413
|
function buildVerdict(builds) {
|
|
159794
160414
|
if (!builds.length) {
|
|
159795
160415
|
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).";
|
|
@@ -159803,7 +160423,7 @@ function buildVerdict(builds) {
|
|
|
159803
160423
|
function client(creds) {
|
|
159804
160424
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
159805
160425
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
159806
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
160426
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync89(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
159807
160427
|
return async (path2) => {
|
|
159808
160428
|
const r2 = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
159809
160429
|
return { status: r2.status, json: await r2.json().catch(() => ({})) };
|
|
@@ -159963,7 +160583,7 @@ __export(secrets_exports, {
|
|
|
159963
160583
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
159964
160584
|
runSecretsCommand: () => runSecretsCommand
|
|
159965
160585
|
});
|
|
159966
|
-
import { readFileSync as
|
|
160586
|
+
import { readFileSync as readFileSync90 } from "node:fs";
|
|
159967
160587
|
function environment(value) {
|
|
159968
160588
|
if (value === "preview" || value === "production") return value;
|
|
159969
160589
|
throw new Error("--environment must be preview or production");
|
|
@@ -159994,7 +160614,7 @@ async function runSecretsCommand(operation, flags, io2, options = {}) {
|
|
|
159994
160614
|
io2.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
159995
160615
|
return 0;
|
|
159996
160616
|
}
|
|
159997
|
-
const value = options.readValue ? options.readValue() :
|
|
160617
|
+
const value = options.readValue ? options.readValue() : readFileSync90(0, "utf8").replace(/\r?\n$/, "");
|
|
159998
160618
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
159999
160619
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
160000
160620
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -160023,7 +160643,7 @@ async function runRemoteSecretsCommand(operation, flags, io2, options) {
|
|
|
160023
160643
|
}
|
|
160024
160644
|
let body;
|
|
160025
160645
|
if (operation !== "list") {
|
|
160026
|
-
const value = options.readValue ? options.readValue() :
|
|
160646
|
+
const value = options.readValue ? options.readValue() : readFileSync90(0, "utf8").replace(/\r?\n$/, "");
|
|
160027
160647
|
body = JSON.stringify({ value });
|
|
160028
160648
|
}
|
|
160029
160649
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -160407,7 +161027,7 @@ async function runAllMembers(args) {
|
|
|
160407
161027
|
if (flags["dry-run"] === true) {
|
|
160408
161028
|
if (recipients.length) {
|
|
160409
161029
|
const result = await send2(recipients[0], requestId2, true);
|
|
160410
|
-
const code =
|
|
161030
|
+
const code = refusalCode2(result);
|
|
160411
161031
|
if (code) return refuse6(io2, code, HINTS[code], 1);
|
|
160412
161032
|
}
|
|
160413
161033
|
io2.log(JSON.stringify({ ok: true, state: "dry_run", campaignId: requestId2, recipients: recipients.length, sent: false }));
|
|
@@ -160426,7 +161046,7 @@ async function runAllMembers(args) {
|
|
|
160426
161046
|
},
|
|
160427
161047
|
send: async (recipient, memberRequestId) => {
|
|
160428
161048
|
const response = await send2(recipient, memberRequestId);
|
|
160429
|
-
const code =
|
|
161049
|
+
const code = refusalCode2(response);
|
|
160430
161050
|
if (code === "rate_limited" && response.retryAfterSec) return { state: "rate_limited", retryAfterSec: response.retryAfterSec };
|
|
160431
161051
|
if (code) return { state: "failed", code };
|
|
160432
161052
|
return { state: "accepted", deduplicated: response.body?.deduplicated === true };
|
|
@@ -160450,7 +161070,7 @@ function flagRefusal(flags) {
|
|
|
160450
161070
|
return void 0;
|
|
160451
161071
|
}
|
|
160452
161072
|
function report2(http, sent, flags, io2) {
|
|
160453
|
-
const code =
|
|
161073
|
+
const code = refusalCode2(http);
|
|
160454
161074
|
if (code === "send_outcome_unknown") {
|
|
160455
161075
|
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 });
|
|
160456
161076
|
}
|
|
@@ -160462,7 +161082,7 @@ function report2(http, sent, flags, io2) {
|
|
|
160462
161082
|
else io2.log(summary(http.body ?? {}, sent));
|
|
160463
161083
|
return 0;
|
|
160464
161084
|
}
|
|
160465
|
-
function
|
|
161085
|
+
function refusalCode2(http) {
|
|
160466
161086
|
if (http.error) return http.error === "push_send_unreachable" ? "send_outcome_unknown" : http.error;
|
|
160467
161087
|
if (http.ok && (http.body?.state === "accepted" || http.body?.state === "dry_run")) return void 0;
|
|
160468
161088
|
const code = String(http.body?.error ?? "");
|
|
@@ -160521,15 +161141,15 @@ __export(notify_exports, {
|
|
|
160521
161141
|
runNotify: () => runNotify,
|
|
160522
161142
|
saveAdminSession: () => saveAdminSession
|
|
160523
161143
|
});
|
|
160524
|
-
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as
|
|
161144
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as readFileSync91, writeFileSync as writeFileSync31 } from "node:fs";
|
|
160525
161145
|
import { homedir as homedir9 } from "node:os";
|
|
160526
|
-
import { dirname as dirname39, join as
|
|
161146
|
+
import { dirname as dirname39, join as join75 } from "node:path";
|
|
160527
161147
|
function defaultSessionsPath() {
|
|
160528
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
161148
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join75(homedir9(), ".himalaya", "admin-sessions.json");
|
|
160529
161149
|
}
|
|
160530
161150
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
160531
161151
|
try {
|
|
160532
|
-
return JSON.parse(
|
|
161152
|
+
return JSON.parse(readFileSync91(path2, "utf8"));
|
|
160533
161153
|
} catch {
|
|
160534
161154
|
return {};
|
|
160535
161155
|
}
|
|
@@ -160906,20 +161526,20 @@ __export(base44_auth_exports, {
|
|
|
160906
161526
|
usableBase44Auth: () => usableBase44Auth,
|
|
160907
161527
|
writeBase44Session: () => writeBase44Session
|
|
160908
161528
|
});
|
|
160909
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
161529
|
+
import { chmodSync as chmodSync4, existsSync as existsSync75, mkdirSync as mkdirSync36, readFileSync as readFileSync92, rmSync as rmSync19, writeFileSync as writeFileSync32 } from "node:fs";
|
|
160910
161530
|
import { homedir as homedir10 } from "node:os";
|
|
160911
|
-
import { dirname as dirname40, join as
|
|
161531
|
+
import { dirname as dirname40, join as join76 } from "node:path";
|
|
160912
161532
|
function base44ApiBase(env = process.env) {
|
|
160913
161533
|
return (env.BASE44_API_URL?.trim() || "https://app.base44.com").replace(/\/+$/, "");
|
|
160914
161534
|
}
|
|
160915
161535
|
function base44SessionPath(home = homedir10()) {
|
|
160916
|
-
return
|
|
161536
|
+
return join76(home, ".himi", "base44", "session.json");
|
|
160917
161537
|
}
|
|
160918
161538
|
function readBase44Session(home) {
|
|
160919
161539
|
const p2 = base44SessionPath(home);
|
|
160920
|
-
if (!
|
|
161540
|
+
if (!existsSync75(p2)) return void 0;
|
|
160921
161541
|
try {
|
|
160922
|
-
const s2 = JSON.parse(
|
|
161542
|
+
const s2 = JSON.parse(readFileSync92(p2, "utf8"));
|
|
160923
161543
|
return typeof s2.accessToken === "string" && s2.accessToken ? s2 : void 0;
|
|
160924
161544
|
} catch {
|
|
160925
161545
|
return void 0;
|
|
@@ -160935,7 +161555,7 @@ function writeBase44Session(session, home) {
|
|
|
160935
161555
|
}
|
|
160936
161556
|
function deleteBase44Session(home) {
|
|
160937
161557
|
const p2 = base44SessionPath(home);
|
|
160938
|
-
if (!
|
|
161558
|
+
if (!existsSync75(p2)) return false;
|
|
160939
161559
|
rmSync19(p2, { force: true });
|
|
160940
161560
|
return true;
|
|
160941
161561
|
}
|
|
@@ -161030,9 +161650,9 @@ async function base44DeviceLogin(opts) {
|
|
|
161030
161650
|
throw new Error("the Base44 sign-in code expired before it was approved \u2014 run `himi base44 login` again");
|
|
161031
161651
|
}
|
|
161032
161652
|
function importBase44CliSession(home = homedir10(), env = process.env) {
|
|
161033
|
-
const src =
|
|
161034
|
-
if (!
|
|
161035
|
-
const a2 = JSON.parse(
|
|
161653
|
+
const src = join76(home, ".base44", "auth", "auth.json");
|
|
161654
|
+
if (!existsSync75(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
|
|
161655
|
+
const a2 = JSON.parse(readFileSync92(src, "utf8"));
|
|
161036
161656
|
if (typeof a2.accessToken !== "string" || !a2.accessToken) throw new Error(`${src} holds no access token`);
|
|
161037
161657
|
const session = {
|
|
161038
161658
|
accessToken: a2.accessToken,
|
|
@@ -163167,7 +163787,7 @@ var init_brand_font = __esm({
|
|
|
163167
163787
|
|
|
163168
163788
|
// src/site-analyze/write-artifacts.ts
|
|
163169
163789
|
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync33 } from "node:fs";
|
|
163170
|
-
import { join as
|
|
163790
|
+
import { join as join77 } from "node:path";
|
|
163171
163791
|
function attachVeloSources(book, sources, put) {
|
|
163172
163792
|
const byPath = new Map((sources ?? []).map((s2) => [s2.path, s2.text]));
|
|
163173
163793
|
for (const f2 of book.velo.files) {
|
|
@@ -163322,12 +163942,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
163322
163942
|
}
|
|
163323
163943
|
async function writeBusinessBook(result, opts) {
|
|
163324
163944
|
const out2 = opts.outDir;
|
|
163325
|
-
mkdirSync37(
|
|
163326
|
-
mkdirSync37(
|
|
163945
|
+
mkdirSync37(join77(out2, "evidence/pages"), { recursive: true });
|
|
163946
|
+
mkdirSync37(join77(out2, "media/catalog"), { recursive: true });
|
|
163327
163947
|
const files = [];
|
|
163328
163948
|
const put = (rel, body) => {
|
|
163329
|
-
const p2 =
|
|
163330
|
-
mkdirSync37(
|
|
163949
|
+
const p2 = join77(out2, rel);
|
|
163950
|
+
mkdirSync37(join77(p2, ".."), { recursive: true });
|
|
163331
163951
|
writeFileSync33(p2, body);
|
|
163332
163952
|
files.push(rel);
|
|
163333
163953
|
};
|
|
@@ -164231,11 +164851,11 @@ var init_analyze = __esm({
|
|
|
164231
164851
|
});
|
|
164232
164852
|
|
|
164233
164853
|
// src/base44-analyze/write-artifacts.ts
|
|
164234
|
-
import { existsSync as
|
|
164235
|
-
import { dirname as dirname41, join as
|
|
164854
|
+
import { existsSync as existsSync76, mkdirSync as mkdirSync38, readFileSync as readFileSync93, rmSync as rmSync20, writeFileSync as writeFileSync34 } from "node:fs";
|
|
164855
|
+
import { dirname as dirname41, join as join78, resolve as resolve56, sep as sep19 } from "node:path";
|
|
164236
164856
|
function isBookFolder(dir) {
|
|
164237
164857
|
try {
|
|
164238
|
-
return JSON.parse(
|
|
164858
|
+
return JSON.parse(readFileSync93(join78(dir, "book.json"), "utf8")).kind === "base44-app-book";
|
|
164239
164859
|
} catch {
|
|
164240
164860
|
return false;
|
|
164241
164861
|
}
|
|
@@ -164322,24 +164942,24 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
164322
164942
|
const md = renderBookMd(book);
|
|
164323
164943
|
assertNoSecrets(json6);
|
|
164324
164944
|
assertNoSecrets(md);
|
|
164325
|
-
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) =>
|
|
164945
|
+
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync76(join78(out2, n2)));
|
|
164326
164946
|
if (owned.length) {
|
|
164327
164947
|
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`);
|
|
164328
|
-
for (const d2 of ["source", "screenshots"]) rmSync20(
|
|
164948
|
+
for (const d2 of ["source", "screenshots"]) rmSync20(join78(out2, d2), { recursive: true, force: true });
|
|
164329
164949
|
}
|
|
164330
164950
|
mkdirSync38(out2, { recursive: true });
|
|
164331
|
-
writeFileSync34(
|
|
164332
|
-
writeFileSync34(
|
|
164951
|
+
writeFileSync34(join78(out2, "book.json"), json6);
|
|
164952
|
+
writeFileSync34(join78(out2, "BOOK.md"), md);
|
|
164333
164953
|
files.push("book.json", "BOOK.md");
|
|
164334
164954
|
for (const s2 of shots) {
|
|
164335
|
-
mkdirSync38(
|
|
164336
|
-
writeFileSync34(
|
|
164955
|
+
mkdirSync38(join78(out2, "screenshots"), { recursive: true });
|
|
164956
|
+
writeFileSync34(join78(out2, "screenshots", s2.filename), s2.bytes);
|
|
164337
164957
|
files.push(`screenshots/${s2.filename}`);
|
|
164338
164958
|
}
|
|
164339
|
-
const sourceRoot =
|
|
164959
|
+
const sourceRoot = join78(out2, "source");
|
|
164340
164960
|
for (const f2 of result.sourceFiles) {
|
|
164341
164961
|
if (!safeRel(f2.path)) continue;
|
|
164342
|
-
const dest =
|
|
164962
|
+
const dest = join78(sourceRoot, ...f2.path.split("/"));
|
|
164343
164963
|
if (!dest.startsWith(sourceRoot + sep19)) continue;
|
|
164344
164964
|
mkdirSync38(dirname41(dest), { recursive: true });
|
|
164345
164965
|
writeFileSync34(dest, f2.bytes);
|
|
@@ -167884,7 +168504,7 @@ __export(cli_exports, {
|
|
|
167884
168504
|
import { execFile } from "node:child_process";
|
|
167885
168505
|
import { mkdirSync as mkdirSync39, mkdtempSync as mkdtempSync4, rmSync as rmSync21, writeFileSync as writeFileSync35 } from "node:fs";
|
|
167886
168506
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
167887
|
-
import { join as
|
|
168507
|
+
import { join as join79, resolve as resolve57 } from "node:path";
|
|
167888
168508
|
import { promisify } from "node:util";
|
|
167889
168509
|
function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
167890
168510
|
return async (appId2) => {
|
|
@@ -167897,11 +168517,11 @@ function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
|
167897
168517
|
}
|
|
167898
168518
|
const bytes2 = await readCapped(res, MAX_TARBALL_BYTES);
|
|
167899
168519
|
if (!bytes2) throw new Error(`project download is over the ${MAX_TARBALL_BYTES}-byte cap`);
|
|
167900
|
-
const root = mkdtempSync4(
|
|
168520
|
+
const root = mkdtempSync4(join79(tmpdir5(), "himi-base44-"));
|
|
167901
168521
|
const cleanup = () => rmSync21(root, { recursive: true, force: true });
|
|
167902
168522
|
try {
|
|
167903
|
-
const archive =
|
|
167904
|
-
const dir =
|
|
168523
|
+
const archive = join79(root, "project.tar");
|
|
168524
|
+
const dir = join79(root, "project");
|
|
167905
168525
|
writeFileSync35(archive, bytes2);
|
|
167906
168526
|
mkdirSync39(dir);
|
|
167907
168527
|
await extract(archive, dir);
|
|
@@ -169196,8 +169816,8 @@ var init_customer_build = __esm({
|
|
|
169196
169816
|
});
|
|
169197
169817
|
|
|
169198
169818
|
// src/site-analyze/apply.ts
|
|
169199
|
-
import { existsSync as
|
|
169200
|
-
import { dirname as dirname42, isAbsolute as isAbsolute8, join as
|
|
169819
|
+
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";
|
|
169820
|
+
import { dirname as dirname42, isAbsolute as isAbsolute8, join as join80, resolve as resolve58, sep as sep20 } from "node:path";
|
|
169201
169821
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
169202
169822
|
function unpairedRedirectNote(overlay) {
|
|
169203
169823
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
@@ -169212,7 +169832,7 @@ function committedShellProvisioning(path2) {
|
|
|
169212
169832
|
function findRepoRoot(cwd) {
|
|
169213
169833
|
let dir = cwd;
|
|
169214
169834
|
for (let i2 = 0; i2 < 8; i2++) {
|
|
169215
|
-
if (SHELL_NAMES2.some((name) =>
|
|
169835
|
+
if (SHELL_NAMES2.some((name) => existsSync77(join80(dir, shellAppDir(name), "package.json")))) return dir;
|
|
169216
169836
|
const next = dirname42(dir);
|
|
169217
169837
|
if (next === dir) break;
|
|
169218
169838
|
dir = next;
|
|
@@ -169315,11 +169935,11 @@ function sameKnownSite(previous, next) {
|
|
|
169315
169935
|
}
|
|
169316
169936
|
function buildMergedContract(options) {
|
|
169317
169937
|
const { appDir: appDir3, packageDir, overlay } = options;
|
|
169318
|
-
const committedPath =
|
|
169319
|
-
if (!
|
|
169938
|
+
const committedPath = join80(appDir3, "provisioning.json");
|
|
169939
|
+
if (!existsSync77(committedPath)) {
|
|
169320
169940
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
169321
169941
|
}
|
|
169322
|
-
const committed = JSON.parse(
|
|
169942
|
+
const committed = JSON.parse(readFileSync94(committedPath, "utf8"));
|
|
169323
169943
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
169324
169944
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
169325
169945
|
const branding = merged.branding ?? {};
|
|
@@ -169331,13 +169951,13 @@ function buildMergedContract(options) {
|
|
|
169331
169951
|
};
|
|
169332
169952
|
const stage = (fromRel, toRel) => {
|
|
169333
169953
|
const from = contained(packageDir, fromRel);
|
|
169334
|
-
const to2 = contained(
|
|
169335
|
-
if (!from || !to2 || !
|
|
169954
|
+
const to2 = contained(join80(appDir3, STAGED), toRel.slice(STAGED.length + 1));
|
|
169955
|
+
if (!from || !to2 || !existsSync77(from)) return void 0;
|
|
169336
169956
|
let real;
|
|
169337
169957
|
let realRoot;
|
|
169338
169958
|
try {
|
|
169339
|
-
real =
|
|
169340
|
-
realRoot =
|
|
169959
|
+
real = realpathSync14(from);
|
|
169960
|
+
realRoot = realpathSync14(packageDir);
|
|
169341
169961
|
} catch {
|
|
169342
169962
|
return void 0;
|
|
169343
169963
|
}
|
|
@@ -169354,11 +169974,11 @@ function buildMergedContract(options) {
|
|
|
169354
169974
|
};
|
|
169355
169975
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
169356
169976
|
if (icon) branding.appIconPath = icon;
|
|
169357
|
-
const facesPath =
|
|
169358
|
-
if (
|
|
169977
|
+
const facesPath = join80(packageDir, "media/fonts/faces.json");
|
|
169978
|
+
if (existsSync77(facesPath)) {
|
|
169359
169979
|
let faces = [];
|
|
169360
169980
|
try {
|
|
169361
|
-
const parsed = JSON.parse(
|
|
169981
|
+
const parsed = JSON.parse(readFileSync94(facesPath, "utf8"));
|
|
169362
169982
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
169363
169983
|
} catch {
|
|
169364
169984
|
faces = [];
|
|
@@ -169379,9 +169999,9 @@ function buildMergedContract(options) {
|
|
|
169379
169999
|
merged.branding = branding;
|
|
169380
170000
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
169381
170001
|
`;
|
|
169382
|
-
const path2 =
|
|
170002
|
+
const path2 = join80(packageDir, "provisioning.contract.json");
|
|
169383
170003
|
writeFileSync36(path2, body);
|
|
169384
|
-
const localPath2 =
|
|
170004
|
+
const localPath2 = join80(appDir3, LOCAL_CONTRACT_REL);
|
|
169385
170005
|
mkdirSync40(dirname42(localPath2), { recursive: true });
|
|
169386
170006
|
writeFileSync36(localPath2, body);
|
|
169387
170007
|
staged.push(localPath2);
|
|
@@ -169416,10 +170036,10 @@ function catalogTypography(overlay, template) {
|
|
|
169416
170036
|
function staticFaqFor(overlay, overlayPath) {
|
|
169417
170037
|
const own4 = overlay.faq;
|
|
169418
170038
|
if (own4 !== void 0) return deriveStaticFaq(own4);
|
|
169419
|
-
const bookPath =
|
|
169420
|
-
if (!
|
|
170039
|
+
const bookPath = join80(dirname42(resolve58(overlayPath)), "book.json");
|
|
170040
|
+
if (!existsSync77(bookPath)) return void 0;
|
|
169421
170041
|
try {
|
|
169422
|
-
const book = JSON.parse(
|
|
170042
|
+
const book = JSON.parse(readFileSync94(bookPath, "utf8"));
|
|
169423
170043
|
const copy = book?.copy;
|
|
169424
170044
|
if (!copy || typeof copy !== "object" || copy.unavailable) return void 0;
|
|
169425
170045
|
const pairs = deriveStaticFaq(copy.faq);
|
|
@@ -169433,10 +170053,10 @@ function staticGalleriesFor(overlay, overlayPath) {
|
|
|
169433
170053
|
if (overlay.galleries !== void 0) return deriveStaticGalleries(
|
|
169434
170054
|
overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
|
|
169435
170055
|
);
|
|
169436
|
-
const bookPath =
|
|
169437
|
-
if (!
|
|
170056
|
+
const bookPath = join80(dirname42(resolve58(overlayPath)), "book.json");
|
|
170057
|
+
if (!existsSync77(bookPath)) return void 0;
|
|
169438
170058
|
try {
|
|
169439
|
-
const book = JSON.parse(
|
|
170059
|
+
const book = JSON.parse(readFileSync94(bookPath, "utf8"));
|
|
169440
170060
|
if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
|
|
169441
170061
|
const galleries = deriveStaticGalleries(book.look.pages);
|
|
169442
170062
|
return galleries.length || book.look.complete === true ? galleries : void 0;
|
|
@@ -169448,8 +170068,8 @@ async function applyOverlays(input) {
|
|
|
169448
170068
|
const cwd = resolve58(input.cwd);
|
|
169449
170069
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
169450
170070
|
assertKnownShell(shell);
|
|
169451
|
-
const overlay = JSON.parse(
|
|
169452
|
-
const tokens2 = JSON.parse(
|
|
170071
|
+
const overlay = JSON.parse(readFileSync94(input.overlayPath, "utf8"));
|
|
170072
|
+
const tokens2 = JSON.parse(readFileSync94(input.tokensPath, "utf8"));
|
|
169453
170073
|
const faq = staticFaqFor(overlay, input.overlayPath);
|
|
169454
170074
|
if (faq !== void 0) overlay.faq = faq;
|
|
169455
170075
|
const galleries = staticGalleriesFor(overlay, input.overlayPath);
|
|
@@ -169466,9 +170086,9 @@ async function applyOverlays(input) {
|
|
|
169466
170086
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
169467
170087
|
);
|
|
169468
170088
|
}
|
|
169469
|
-
const appDir3 =
|
|
169470
|
-
const committedPath =
|
|
169471
|
-
const committedSite =
|
|
170089
|
+
const appDir3 = join80(repoRoot2, shellAppDir(shell));
|
|
170090
|
+
const committedPath = join80(appDir3, "provisioning.json");
|
|
170091
|
+
const committedSite = existsSync77(committedPath) ? JSON.parse(readFileSync94(committedPath, "utf8")).site : void 0;
|
|
169472
170092
|
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
169473
170093
|
throw new Error(
|
|
169474
170094
|
`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.`
|
|
@@ -169495,9 +170115,9 @@ async function applyOverlays(input) {
|
|
|
169495
170115
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
169496
170116
|
};
|
|
169497
170117
|
}
|
|
169498
|
-
const pkgProv =
|
|
170118
|
+
const pkgProv = join80(cwd, "provisioning.json");
|
|
169499
170119
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
169500
|
-
const contentPath =
|
|
170120
|
+
const contentPath = join80(cwd, "himalaya.content.json");
|
|
169501
170121
|
const syncViewNames = (before, after) => {
|
|
169502
170122
|
const content = readContentManifest(cwd);
|
|
169503
170123
|
if (!content) return;
|
|
@@ -169509,8 +170129,8 @@ async function applyOverlays(input) {
|
|
|
169509
170129
|
};
|
|
169510
170130
|
let packageFaq = faq;
|
|
169511
170131
|
let packageGalleries = galleries;
|
|
169512
|
-
if (
|
|
169513
|
-
const cur = JSON.parse(
|
|
170132
|
+
if (existsSync77(pkgProv)) {
|
|
170133
|
+
const cur = JSON.parse(readFileSync94(pkgProv, "utf8"));
|
|
169514
170134
|
if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
|
|
169515
170135
|
const merged = deepMerge4(cur, overlay);
|
|
169516
170136
|
packageFaq = merged.faq;
|
|
@@ -169526,9 +170146,9 @@ async function applyOverlays(input) {
|
|
|
169526
170146
|
if (Array.isArray(packageGalleries) && packageGalleries.length && !overlay.installedVerticals.includes("galleries")) {
|
|
169527
170147
|
overlay.installedVerticals.push("galleries");
|
|
169528
170148
|
}
|
|
169529
|
-
const pkgTokens =
|
|
169530
|
-
if (
|
|
169531
|
-
const cur = JSON.parse(
|
|
170149
|
+
const pkgTokens = join80(cwd, "tokens.json");
|
|
170150
|
+
if (existsSync77(pkgTokens) && (tokens2.colors || tokens2.typography)) {
|
|
170151
|
+
const cur = JSON.parse(readFileSync94(pkgTokens, "utf8"));
|
|
169532
170152
|
let tokensIn = tokens2;
|
|
169533
170153
|
if (tokens2.typography) {
|
|
169534
170154
|
const fonts = catalogTypography(tokens2.typography, cur.typography);
|
|
@@ -169553,9 +170173,9 @@ async function applyOverlays(input) {
|
|
|
169553
170173
|
wrote.push(pkgTokens);
|
|
169554
170174
|
}
|
|
169555
170175
|
const homeAction = homeRefreshActionId(shell);
|
|
169556
|
-
const homeSrc =
|
|
169557
|
-
if (homeAction &&
|
|
169558
|
-
const prev =
|
|
170176
|
+
const homeSrc = join80(cwd, "dev/index.ts");
|
|
170177
|
+
if (homeAction && existsSync77(homeSrc)) {
|
|
170178
|
+
const prev = readFileSync94(homeSrc, "utf8");
|
|
169559
170179
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
169560
170180
|
let next = patched.src;
|
|
169561
170181
|
if (!patched.foreign && faq?.length && prev.includes('"tier5.himiBrandedFaq.load"') && !prev.includes('"staticFaq"')) {
|
|
@@ -169590,13 +170210,13 @@ async function applyOverlays(input) {
|
|
|
169590
170210
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
169591
170211
|
}
|
|
169592
170212
|
}
|
|
169593
|
-
if (!input.iconPath || !
|
|
170213
|
+
if (!input.iconPath || !existsSync77(input.iconPath)) {
|
|
169594
170214
|
const book = input.iconPath ? dirname42(dirname42(resolve58(input.iconPath))) : void 0;
|
|
169595
170215
|
notes.push(
|
|
169596
170216
|
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"
|
|
169597
170217
|
);
|
|
169598
170218
|
}
|
|
169599
|
-
if (input.iconPath &&
|
|
170219
|
+
if (input.iconPath && existsSync77(input.iconPath)) {
|
|
169600
170220
|
try {
|
|
169601
170221
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
169602
170222
|
wrote.push(...installed.wrote);
|
|
@@ -170553,7 +171173,7 @@ __export(cli_exports2, {
|
|
|
170553
171173
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
170554
171174
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
170555
171175
|
});
|
|
170556
|
-
import { existsSync as
|
|
171176
|
+
import { existsSync as existsSync78, readFileSync as readFileSync95 } from "node:fs";
|
|
170557
171177
|
import { resolve as resolve59 } from "node:path";
|
|
170558
171178
|
function applyNeedsClient(shell) {
|
|
170559
171179
|
if (shell === void 0 || !SHELL_NAMES2.includes(shell)) return true;
|
|
@@ -170610,9 +171230,9 @@ async function runSiteAnalyze(opts) {
|
|
|
170610
171230
|
if (book?.skipped) result.warnings = [...result.warnings ?? [], book.skipped];
|
|
170611
171231
|
const derived = deriveSiteShell({ siteUrl: result.book.input.siteUrl, look: result.book.look, kind, routes });
|
|
170612
171232
|
const prevOverlayPath = resolve59(outDir, "provisioning.overlay.json");
|
|
170613
|
-
const prevSite =
|
|
171233
|
+
const prevSite = existsSync78(prevOverlayPath) ? (() => {
|
|
170614
171234
|
try {
|
|
170615
|
-
return JSON.parse(
|
|
171235
|
+
return JSON.parse(readFileSync95(prevOverlayPath, "utf8")).site;
|
|
170616
171236
|
} catch {
|
|
170617
171237
|
return void 0;
|
|
170618
171238
|
}
|
|
@@ -170631,7 +171251,7 @@ async function runSiteAnalyze(opts) {
|
|
|
170631
171251
|
}
|
|
170632
171252
|
const previousOverlay = resolve59(outDir, "provisioning.overlay.json");
|
|
170633
171253
|
carryOverGoals(
|
|
170634
|
-
|
|
171254
|
+
existsSync78(previousOverlay) ? readFileSync95(previousOverlay, "utf8") : void 0,
|
|
170635
171255
|
result.provisioningOverlay
|
|
170636
171256
|
);
|
|
170637
171257
|
const ownerCall = ownerAuth ? ownerTransportFrom(fetchImpl, ownerAuth) : void 0;
|
|
@@ -170689,7 +171309,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
170689
171309
|
let source;
|
|
170690
171310
|
if (opts.sourcePath) {
|
|
170691
171311
|
const p2 = resolve59(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
170692
|
-
source =
|
|
171312
|
+
source = readFileSync95(p2, "utf8");
|
|
170693
171313
|
}
|
|
170694
171314
|
let body;
|
|
170695
171315
|
if (opts.bodyRaw != null) {
|
|
@@ -170717,9 +171337,9 @@ async function runSiteFunctionCli(opts) {
|
|
|
170717
171337
|
});
|
|
170718
171338
|
}
|
|
170719
171339
|
function base44BookRoutes(bookPath, siteUrl) {
|
|
170720
|
-
if (!
|
|
171340
|
+
if (!existsSync78(bookPath)) return void 0;
|
|
170721
171341
|
try {
|
|
170722
|
-
const book = JSON.parse(
|
|
171342
|
+
const book = JSON.parse(readFileSync95(bookPath, "utf8"));
|
|
170723
171343
|
if (book.kind !== "base44-app-book" || !Array.isArray(book.routes)) return void 0;
|
|
170724
171344
|
const host = (u2) => {
|
|
170725
171345
|
try {
|
|
@@ -170974,7 +171594,7 @@ __export(site_create_exports, {
|
|
|
170974
171594
|
runSiteList: () => runSiteList,
|
|
170975
171595
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
170976
171596
|
});
|
|
170977
|
-
import { existsSync as
|
|
171597
|
+
import { existsSync as existsSync79, readFileSync as readFileSync96, writeFileSync as writeFileSync37 } from "node:fs";
|
|
170978
171598
|
import { resolve as resolvePath2 } from "node:path";
|
|
170979
171599
|
function oauthClientName(projectName) {
|
|
170980
171600
|
return `${projectName} client`;
|
|
@@ -171123,7 +171743,7 @@ async function runSiteCreate(opts) {
|
|
|
171123
171743
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
171124
171744
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
171125
171745
|
}
|
|
171126
|
-
function writeProvisioningBinding(target, binding2, fs2 = { existsSync:
|
|
171746
|
+
function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync79, readFileSync: readFileSync96, writeFileSync: writeFileSync37 }) {
|
|
171127
171747
|
const msid = binding2.siteId;
|
|
171128
171748
|
const path2 = resolvePath2(target);
|
|
171129
171749
|
const committed = committedShellProvisioning(path2);
|
|
@@ -171459,7 +172079,7 @@ var init_site_oauth_client = __esm({
|
|
|
171459
172079
|
|
|
171460
172080
|
// src/site-analyze/velo-source.ts
|
|
171461
172081
|
import path from "node:path";
|
|
171462
|
-
import
|
|
172082
|
+
import ts9 from "typescript";
|
|
171463
172083
|
function applySourceEdits(source, edits) {
|
|
171464
172084
|
const chunks = [];
|
|
171465
172085
|
let cursor = 0;
|
|
@@ -171477,13 +172097,13 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171477
172097
|
/\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,
|
|
171478
172098
|
REDACTED2
|
|
171479
172099
|
).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]");
|
|
171480
|
-
const parsed =
|
|
172100
|
+
const parsed = ts9.createSourceFile("backend.ts", source, ts9.ScriptTarget.Latest, true);
|
|
171481
172101
|
const comments = /* @__PURE__ */ new Map();
|
|
171482
172102
|
const visitComments = (node) => {
|
|
171483
172103
|
for (const range of [
|
|
171484
|
-
...
|
|
171485
|
-
...
|
|
171486
|
-
...
|
|
172104
|
+
...ts9.getLeadingCommentRanges(source, node.pos) ?? [],
|
|
172105
|
+
...ts9.getTrailingCommentRanges(source, node.pos) ?? [],
|
|
172106
|
+
...ts9.getTrailingCommentRanges(source, node.end) ?? []
|
|
171487
172107
|
]) comments.set(range.pos, range.end);
|
|
171488
172108
|
for (const child of node.getChildren(parsed)) visitComments(child);
|
|
171489
172109
|
};
|
|
@@ -171502,22 +172122,22 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171502
172122
|
if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
|
|
171503
172123
|
return token;
|
|
171504
172124
|
};
|
|
171505
|
-
const clean2 =
|
|
172125
|
+
const clean2 = ts9.createSourceFile("backend.ts", source, ts9.ScriptTarget.Latest, true);
|
|
171506
172126
|
const masks = [];
|
|
171507
172127
|
const collectMasks = (node) => {
|
|
171508
172128
|
const start = node.getStart(clean2);
|
|
171509
|
-
if (
|
|
172129
|
+
if (ts9.isRegularExpressionLiteral(node)) {
|
|
171510
172130
|
masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
|
|
171511
|
-
} else if (
|
|
172131
|
+
} else if (ts9.isStringLiteral(node) || ts9.isTemplateLiteralToken(node)) {
|
|
171512
172132
|
masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
|
|
171513
172133
|
}
|
|
171514
|
-
|
|
172134
|
+
ts9.forEachChild(node, collectMasks);
|
|
171515
172135
|
};
|
|
171516
172136
|
collectMasks(clean2);
|
|
171517
172137
|
const assignmentContext = applySourceEdits(source, masks);
|
|
171518
172138
|
const edits = [];
|
|
171519
172139
|
const visitLiterals = (node) => {
|
|
171520
|
-
if (
|
|
172140
|
+
if (ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node) || ts9.isTemplateExpression(node)) {
|
|
171521
172141
|
const start = node.getStart(clean2);
|
|
171522
172142
|
const text9 = source.slice(start, node.end);
|
|
171523
172143
|
const redacted = redactLiteral(text9, start);
|
|
@@ -171526,7 +172146,7 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
171526
172146
|
return;
|
|
171527
172147
|
}
|
|
171528
172148
|
}
|
|
171529
|
-
|
|
172149
|
+
ts9.forEachChild(node, visitLiterals);
|
|
171530
172150
|
};
|
|
171531
172151
|
visitLiterals(clean2);
|
|
171532
172152
|
return applySourceEdits(source, edits);
|
|
@@ -171565,19 +172185,19 @@ function selectVeloSource(files, request, knownSecrets = []) {
|
|
|
171565
172185
|
selected.set(file2.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
|
|
171566
172186
|
remaining -= excerpt.length;
|
|
171567
172187
|
const dependencies = [];
|
|
171568
|
-
const parsed =
|
|
172188
|
+
const parsed = ts9.createSourceFile(file2.path, file2.content, ts9.ScriptTarget.Latest, true);
|
|
171569
172189
|
const specifiers = [];
|
|
171570
172190
|
const collectImports = (node) => {
|
|
171571
172191
|
let specifier;
|
|
171572
|
-
if (
|
|
172192
|
+
if (ts9.isImportDeclaration(node) || ts9.isExportDeclaration(node)) {
|
|
171573
172193
|
specifier = node.moduleSpecifier;
|
|
171574
|
-
} else if (
|
|
172194
|
+
} else if (ts9.isImportEqualsDeclaration(node) && ts9.isExternalModuleReference(node.moduleReference)) {
|
|
171575
172195
|
specifier = node.moduleReference.expression;
|
|
171576
|
-
} else if (
|
|
172196
|
+
} else if (ts9.isCallExpression(node) && (node.expression.kind === ts9.SyntaxKind.ImportKeyword || ts9.isIdentifier(node.expression) && node.expression.text === "require")) {
|
|
171577
172197
|
specifier = node.arguments[0];
|
|
171578
172198
|
}
|
|
171579
|
-
if (specifier &&
|
|
171580
|
-
|
|
172199
|
+
if (specifier && ts9.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
|
|
172200
|
+
ts9.forEachChild(node, collectImports);
|
|
171581
172201
|
};
|
|
171582
172202
|
collectImports(parsed);
|
|
171583
172203
|
for (const specifier of specifiers) {
|
|
@@ -171651,7 +172271,7 @@ async function collectSiteContext(opts) {
|
|
|
171651
172271
|
visitorToken = await mintVisitorToken(fetcher, opts.clientId);
|
|
171652
172272
|
visitorAuth = { status: "ok" };
|
|
171653
172273
|
} catch (e2) {
|
|
171654
|
-
visitorAuth =
|
|
172274
|
+
visitorAuth = failed2(e2);
|
|
171655
172275
|
}
|
|
171656
172276
|
}
|
|
171657
172277
|
const visitor = visitorToken ? makeTransport(fetcher, { token: visitorToken, msid: opts.siteId }) : void 0;
|
|
@@ -171668,7 +172288,7 @@ async function collectSiteContext(opts) {
|
|
|
171668
172288
|
currency: identity2.locale.currency
|
|
171669
172289
|
} };
|
|
171670
172290
|
} catch (e2) {
|
|
171671
|
-
return
|
|
172291
|
+
return failed2(e2);
|
|
171672
172292
|
}
|
|
171673
172293
|
};
|
|
171674
172294
|
const cmsRead = async () => {
|
|
@@ -171681,7 +172301,7 @@ async function collectSiteContext(opts) {
|
|
|
171681
172301
|
return data;
|
|
171682
172302
|
} catch (e2) {
|
|
171683
172303
|
const code = e2 instanceof WixApiError2 ? e2.body?.details?.applicationError?.code : void 0;
|
|
171684
|
-
failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } :
|
|
172304
|
+
failure = code === "WDE0110" ? { status: "unavailable", httpStatus: 400 } : failed2(e2);
|
|
171685
172305
|
throw e2;
|
|
171686
172306
|
}
|
|
171687
172307
|
} : void 0;
|
|
@@ -171703,7 +172323,7 @@ async function collectSiteContext(opts) {
|
|
|
171703
172323
|
try {
|
|
171704
172324
|
return await owner(method, path2, body);
|
|
171705
172325
|
} catch (e2) {
|
|
171706
|
-
readFailure =
|
|
172326
|
+
readFailure = failed2(e2);
|
|
171707
172327
|
throw e2;
|
|
171708
172328
|
}
|
|
171709
172329
|
};
|
|
@@ -171730,7 +172350,7 @@ async function collectSiteContext(opts) {
|
|
|
171730
172350
|
truncated: files.length > selected.size || [...selected.values()].some((f2) => f2.sourceTruncated)
|
|
171731
172351
|
};
|
|
171732
172352
|
} catch (e2) {
|
|
171733
|
-
return { ...
|
|
172353
|
+
return { ...failed2(e2), files: [], sourceIncluded: false };
|
|
171734
172354
|
}
|
|
171735
172355
|
};
|
|
171736
172356
|
const [identity, cms, velo, probes] = await Promise.all([
|
|
@@ -171741,7 +172361,7 @@ async function collectSiteContext(opts) {
|
|
|
171741
172361
|
]);
|
|
171742
172362
|
const probeRead = (p2, available, auth) => {
|
|
171743
172363
|
if (!available) return auth;
|
|
171744
|
-
if (p2.httpStatus) return { ...
|
|
172364
|
+
if (p2.httpStatus) return { ...failed2(new WixApiError2(p2.httpStatus, "", "", null)), count: p2.count };
|
|
171745
172365
|
return { status: p2.status === "ok" || p2.status === "empty" ? p2.status : "error", count: p2.count };
|
|
171746
172366
|
};
|
|
171747
172367
|
return {
|
|
@@ -171757,7 +172377,7 @@ async function collectSiteContext(opts) {
|
|
|
171757
172377
|
}))
|
|
171758
172378
|
};
|
|
171759
172379
|
}
|
|
171760
|
-
var responseKeys, definitions, reads,
|
|
172380
|
+
var responseKeys, definitions, reads, failed2;
|
|
171761
172381
|
var init_context = __esm({
|
|
171762
172382
|
"src/site-analyze/context.ts"() {
|
|
171763
172383
|
init_probes();
|
|
@@ -171791,7 +172411,7 @@ var init_context = __esm({
|
|
|
171791
172411
|
...OWNER_VELO_PROBES.map((p2) => `${p2.method} ${p2.path}`),
|
|
171792
172412
|
...definitions.flatMap((p2) => [p2, ...p2.fallbacks ?? []].map((a2) => `${a2.method} ${a2.path}`))
|
|
171793
172413
|
]);
|
|
171794
|
-
|
|
172414
|
+
failed2 = (e2) => {
|
|
171795
172415
|
const httpStatus = e2 instanceof WixApiError2 ? e2.status : void 0;
|
|
171796
172416
|
return { status: httpStatus === 401 ? "unauthorized" : httpStatus === 403 ? "forbidden" : httpStatus === 404 || httpStatus === 428 ? "unavailable" : "error", ...httpStatus ? { httpStatus } : {} };
|
|
171797
172417
|
};
|
|
@@ -171799,12 +172419,12 @@ var init_context = __esm({
|
|
|
171799
172419
|
});
|
|
171800
172420
|
|
|
171801
172421
|
// src/cli.ts
|
|
171802
|
-
import { mkdtempSync as mkdtempSync5, readFileSync as
|
|
172422
|
+
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";
|
|
171803
172423
|
import { execFile as execFile2, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
171804
172424
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
171805
172425
|
import { createHash as createHash41, randomUUID as randomUUID11 } from "node:crypto";
|
|
171806
172426
|
import { tmpdir as tmpdir6, homedir as homedir11, hostname as hostname2 } from "node:os";
|
|
171807
|
-
import { join as
|
|
172427
|
+
import { join as join81, resolve as resolve60, relative as relative15, basename as basename19, dirname as dirname43 } from "node:path";
|
|
171808
172428
|
import { fileURLToPath as fileURLToPath27 } from "node:url";
|
|
171809
172429
|
|
|
171810
172430
|
// ../serve-cli/src/client.ts
|
|
@@ -173958,8 +174578,8 @@ var str9 = (v2) => typeof v2 === "string" ? v2 : void 0;
|
|
|
173958
174578
|
var num3 = (v2) => typeof v2 === "string" && v2 !== "" && Number.isFinite(Number(v2)) ? Number(v2) : void 0;
|
|
173959
174579
|
function embeddedTemplateCatalog() {
|
|
173960
174580
|
return availableTemplates().map((name) => {
|
|
173961
|
-
const path2 =
|
|
173962
|
-
const meta = JSON.parse(
|
|
174581
|
+
const path2 = join81(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
174582
|
+
const meta = JSON.parse(readFileSync97(path2, "utf8"));
|
|
173963
174583
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
173964
174584
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
173965
174585
|
}
|
|
@@ -174496,11 +175116,20 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
174496
175116
|
exact price and explicit territories. Re-reads Apple
|
|
174497
175117
|
first, never edits a live product, never duplicates on
|
|
174498
175118
|
a rerun; prompts unless --yes. Writes the Wix\u2192Apple
|
|
174499
|
-
mapping
|
|
175119
|
+
mapping locally; \`connect\` registers it with Wix.
|
|
174500
175120
|
--limit <n> creates at most n new products per run (big
|
|
174501
175121
|
catalogs go in batches; a rerun continues).
|
|
174502
175122
|
himi store iap status --manifest <file> --profile <name> [--out <file>] [--json]
|
|
174503
175123
|
READ-ONLY: what App Store Connect has for each product.
|
|
175124
|
+
himi store iap connect --manifest <file> --profile <name> [--iap-key <AuthKey.p8> --iap-key-id <id>]
|
|
175125
|
+
[--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <report.json>] [--json]
|
|
175126
|
+
connect the manifest's Wix site to sell those products:
|
|
175127
|
+
register the bundle's purchases app on that site, store its
|
|
175128
|
+
In-App Purchase key, connect the appleIAP provider, and map
|
|
175129
|
+
each Wix item to its Apple product. Reads first and reuses
|
|
175130
|
+
what exists; a bundle, mapping or SKU held elsewhere is a
|
|
175131
|
+
conflict, never overwritten. --content records the
|
|
175132
|
+
purchases app as wixIap in the app's config.ts.
|
|
174504
175133
|
No build, signing or repo checkout. Guide: himi docs iap-products
|
|
174505
175134
|
himi logout [--target <t>] clear the stored control token for a target
|
|
174506
175135
|
himi notify setup --content <dir> [--target wix] [--yes] [--no-push-setup]
|
|
@@ -174804,7 +175433,7 @@ var COMMANDS2 = [
|
|
|
174804
175433
|
{ 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)" },
|
|
174805
175434
|
{ 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>]" },
|
|
174806
175435
|
{ 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]" },
|
|
174807
|
-
{ 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]" },
|
|
175436
|
+
{ 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]" },
|
|
174808
175437
|
{ name: "guide", summary: "print the Himalaya overview + headless dev loop + available topics (offline)", required: "[--json]" },
|
|
174809
175438
|
{ 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]" },
|
|
174810
175439
|
{ name: "components", summary: "print the SDUI component vocabulary + props; a name = that component (offline)", required: "[<Name>] [--json]" },
|
|
@@ -174821,7 +175450,7 @@ var COMMANDS2 = [
|
|
|
174821
175450
|
];
|
|
174822
175451
|
function cliVersion() {
|
|
174823
175452
|
try {
|
|
174824
|
-
return JSON.parse(
|
|
175453
|
+
return JSON.parse(readFileSync97(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
174825
175454
|
} catch {
|
|
174826
175455
|
return "unknown";
|
|
174827
175456
|
}
|
|
@@ -174946,7 +175575,7 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
174946
175575
|
}
|
|
174947
175576
|
function packageVersion(path2) {
|
|
174948
175577
|
try {
|
|
174949
|
-
const version4 = JSON.parse(
|
|
175578
|
+
const version4 = JSON.parse(readFileSync97(path2, "utf8")).version;
|
|
174950
175579
|
return typeof version4 === "string" && version4 ? version4 : void 0;
|
|
174951
175580
|
} catch {
|
|
174952
175581
|
return void 0;
|
|
@@ -174955,7 +175584,7 @@ function packageVersion(path2) {
|
|
|
174955
175584
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
174956
175585
|
let dir = resolve60(fromDir);
|
|
174957
175586
|
for (; ; ) {
|
|
174958
|
-
const version4 = packageVersion(
|
|
175587
|
+
const version4 = packageVersion(join81(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
174959
175588
|
if (version4) return { version: version4, source: "local" };
|
|
174960
175589
|
const parent = dirname43(dir);
|
|
174961
175590
|
if (parent === dir) break;
|
|
@@ -174965,7 +175594,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
174965
175594
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
174966
175595
|
try {
|
|
174967
175596
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
174968
|
-
const version4 = root ? packageVersion(
|
|
175597
|
+
const version4 = root ? packageVersion(join81(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
174969
175598
|
return version4 ? { version: version4, source: "global" } : {};
|
|
174970
175599
|
} catch {
|
|
174971
175600
|
return {};
|
|
@@ -175012,11 +175641,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
175012
175641
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
175013
175642
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
175014
175643
|
function updateCachePath(env = process.env) {
|
|
175015
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
175644
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join81(homedir11(), ".himalaya", "update-check.json");
|
|
175016
175645
|
}
|
|
175017
175646
|
function readUpdateCache(path2) {
|
|
175018
175647
|
try {
|
|
175019
|
-
const parsed = JSON.parse(
|
|
175648
|
+
const parsed = JSON.parse(readFileSync97(path2, "utf8"));
|
|
175020
175649
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
175021
175650
|
} catch {
|
|
175022
175651
|
return {};
|
|
@@ -175085,12 +175714,12 @@ function createUpdateRunner(spawn8 = spawnSync5) {
|
|
|
175085
175714
|
},
|
|
175086
175715
|
installedVersion: () => {
|
|
175087
175716
|
const root = globalNodeModulesRoot();
|
|
175088
|
-
return root ? packageVersion(
|
|
175717
|
+
return root ? packageVersion(join81(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
175089
175718
|
},
|
|
175090
175719
|
reexec: (argv) => {
|
|
175091
175720
|
const root = globalNodeModulesRoot();
|
|
175092
|
-
const entry = root ?
|
|
175093
|
-
if (!entry || !
|
|
175721
|
+
const entry = root ? join81(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
175722
|
+
if (!entry || !existsSync80(entry)) return void 0;
|
|
175094
175723
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
175095
175724
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
175096
175725
|
stdio: "inherit",
|
|
@@ -175137,7 +175766,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
175137
175766
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
175138
175767
|
let content;
|
|
175139
175768
|
try {
|
|
175140
|
-
content =
|
|
175769
|
+
content = readFileSync97(path2, "utf8");
|
|
175141
175770
|
} catch {
|
|
175142
175771
|
continue;
|
|
175143
175772
|
}
|
|
@@ -175160,7 +175789,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
175160
175789
|
const mine = lockStamp(now);
|
|
175161
175790
|
const readLock = (path2) => {
|
|
175162
175791
|
try {
|
|
175163
|
-
return
|
|
175792
|
+
return readFileSync97(path2, "utf8");
|
|
175164
175793
|
} catch {
|
|
175165
175794
|
return void 0;
|
|
175166
175795
|
}
|
|
@@ -175752,7 +176381,7 @@ function executableOnPath(name, env = process.env) {
|
|
|
175752
176381
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
175753
176382
|
for (const dir of entries) {
|
|
175754
176383
|
for (const suffix of suffixes) {
|
|
175755
|
-
const candidate =
|
|
176384
|
+
const candidate = join81(dir, `${name}${suffix}`);
|
|
175756
176385
|
try {
|
|
175757
176386
|
if (!statSync21(candidate).isFile()) continue;
|
|
175758
176387
|
if (process.platform !== "win32") accessSync(candidate, constants4.X_OK);
|
|
@@ -175861,7 +176490,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
175861
176490
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths2(), paths_exports));
|
|
175862
176491
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
175863
176492
|
const iosYmlPath = iosProjectYml2(app);
|
|
175864
|
-
const iosYml =
|
|
176493
|
+
const iosYml = existsSync80(iosYmlPath) ? readFileSync97(iosYmlPath, "utf8") : "";
|
|
175865
176494
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
175866
176495
|
if (!optedIn) {
|
|
175867
176496
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -175875,7 +176504,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
175875
176504
|
}
|
|
175876
176505
|
function readConfigSource(dir) {
|
|
175877
176506
|
try {
|
|
175878
|
-
return
|
|
176507
|
+
return readFileSync97(join81(dir, "config.ts"), "utf8");
|
|
175879
176508
|
} catch {
|
|
175880
176509
|
return null;
|
|
175881
176510
|
}
|
|
@@ -175929,7 +176558,7 @@ var NoBase44SlotError = class extends Error {
|
|
|
175929
176558
|
};
|
|
175930
176559
|
async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {}) {
|
|
175931
176560
|
const dir = resolve60(parentDir, name);
|
|
175932
|
-
if (
|
|
176561
|
+
if (existsSync80(join81(dir, "himalaya.content.json"))) {
|
|
175933
176562
|
throw new Error(`content package already exists at ${dir}`);
|
|
175934
176563
|
}
|
|
175935
176564
|
const r2 = await c2.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -175975,7 +176604,7 @@ function symlinkDestinationIssue(dest) {
|
|
|
175975
176604
|
function restoreDestinationIssue(dest, force) {
|
|
175976
176605
|
const link = symlinkDestinationIssue(dest);
|
|
175977
176606
|
if (link) return link;
|
|
175978
|
-
if (!
|
|
176607
|
+
if (!existsSync80(dest)) return null;
|
|
175979
176608
|
if (!statSync21(dest).isDirectory()) {
|
|
175980
176609
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
175981
176610
|
}
|
|
@@ -175990,7 +176619,7 @@ function restoreDestinationIssue(dest, force) {
|
|
|
175990
176619
|
function isHimalayaMonorepoCheckout(start) {
|
|
175991
176620
|
let dir = resolve60(start);
|
|
175992
176621
|
for (; ; ) {
|
|
175993
|
-
if (
|
|
176622
|
+
if (existsSync80(join81(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync80(join81(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
175994
176623
|
const parent = dirname43(dir);
|
|
175995
176624
|
if (parent === dir) return false;
|
|
175996
176625
|
dir = parent;
|
|
@@ -176028,7 +176657,7 @@ function shellShaDivergenceWarnings(jobs) {
|
|
|
176028
176657
|
}
|
|
176029
176658
|
async function templatePublishName(sourceDir) {
|
|
176030
176659
|
const id = await appId(sourceDir);
|
|
176031
|
-
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ?
|
|
176660
|
+
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ? basename19(sourceDir) : id;
|
|
176032
176661
|
}
|
|
176033
176662
|
function templateNameError(name, from) {
|
|
176034
176663
|
if (name.startsWith(TEMPLATE_APP_PREFIX)) {
|
|
@@ -176051,7 +176680,7 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176051
176680
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
176052
176681
|
);
|
|
176053
176682
|
const repoRoot2 = resolve60(fileURLToPath27(new URL("../../..", import.meta.url)));
|
|
176054
|
-
const root =
|
|
176683
|
+
const root = join81(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
176055
176684
|
const stillRunning = (pid) => {
|
|
176056
176685
|
try {
|
|
176057
176686
|
process.kill(pid, 0);
|
|
@@ -176065,12 +176694,12 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176065
176694
|
if (!entry.isDirectory()) continue;
|
|
176066
176695
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
176067
176696
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
176068
|
-
rmSync22(
|
|
176697
|
+
rmSync22(join81(root, entry.name), { recursive: true, force: true });
|
|
176069
176698
|
}
|
|
176070
176699
|
}
|
|
176071
176700
|
} catch {
|
|
176072
176701
|
}
|
|
176073
|
-
const dest =
|
|
176702
|
+
const dest = join81(root, `${slug}-${process.pid}`);
|
|
176074
176703
|
rmSync22(dest, { recursive: true, force: true });
|
|
176075
176704
|
mkdirSync41(dest, { recursive: true });
|
|
176076
176705
|
try {
|
|
@@ -176083,17 +176712,17 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
176083
176712
|
}
|
|
176084
176713
|
async function appId(dir) {
|
|
176085
176714
|
try {
|
|
176086
|
-
const { readFileSync:
|
|
176087
|
-
const m2 = JSON.parse(
|
|
176715
|
+
const { readFileSync: readFileSync98 } = await import("node:fs");
|
|
176716
|
+
const m2 = JSON.parse(readFileSync98(join81(dir, "himalaya.content.json"), "utf8"));
|
|
176088
176717
|
if (m2.name) return m2.name;
|
|
176089
176718
|
} catch {
|
|
176090
176719
|
}
|
|
176091
|
-
return
|
|
176720
|
+
return basename19(dir);
|
|
176092
176721
|
}
|
|
176093
176722
|
async function contentVisibility(dir) {
|
|
176094
176723
|
try {
|
|
176095
|
-
const { readFileSync:
|
|
176096
|
-
const m2 = JSON.parse(
|
|
176724
|
+
const { readFileSync: readFileSync98 } = await import("node:fs");
|
|
176725
|
+
const m2 = JSON.parse(readFileSync98(join81(dir, "himalaya.content.json"), "utf8"));
|
|
176097
176726
|
if (m2.visibility === "public" || m2.visibility === "unlisted") return m2.visibility;
|
|
176098
176727
|
} catch {
|
|
176099
176728
|
}
|
|
@@ -176382,7 +177011,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
176382
177011
|
...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/" } : {},
|
|
176383
177012
|
// In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
|
|
176384
177013
|
// hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
|
|
176385
|
-
...
|
|
177014
|
+
...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" } : {},
|
|
176386
177015
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
176387
177016
|
portalUrl: idx.portalUrl
|
|
176388
177017
|
});
|
|
@@ -176405,7 +177034,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
176405
177034
|
try {
|
|
176406
177035
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
176407
177036
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
176408
|
-
out2 = mkdtempSync5(
|
|
177037
|
+
out2 = mkdtempSync5(join81(tmpdir6(), "himi-ux-record-"));
|
|
176409
177038
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
176410
177039
|
const outcome = await buildReleaseFromContent2(dir, out2, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
176411
177040
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -176584,7 +177213,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
176584
177213
|
let js2;
|
|
176585
177214
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
176586
177215
|
try {
|
|
176587
|
-
js2 =
|
|
177216
|
+
js2 = readFileSync97(join81(outDir, candidate), "utf8");
|
|
176588
177217
|
break;
|
|
176589
177218
|
} catch {
|
|
176590
177219
|
}
|
|
@@ -176615,7 +177244,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
176615
177244
|
}
|
|
176616
177245
|
return { families, source: "dist/bundles" };
|
|
176617
177246
|
}
|
|
176618
|
-
var boardOpen = (dir) =>
|
|
177247
|
+
var boardOpen = (dir) => existsSync80(join81(dir, ".himi", "studio", "index.html"));
|
|
176619
177248
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
176620
177249
|
async function leaveForBoard(dir, record2, value) {
|
|
176621
177250
|
if (!boardOpen(dir)) return;
|
|
@@ -176639,7 +177268,7 @@ async function liveMapFor(dir) {
|
|
|
176639
177268
|
}
|
|
176640
177269
|
var commandScratch = new AsyncLocalStorage2();
|
|
176641
177270
|
function commandScratchDir(prefix) {
|
|
176642
|
-
const dir = mkdtempSync5(
|
|
177271
|
+
const dir = mkdtempSync5(join81(tmpdir6(), prefix));
|
|
176643
177272
|
commandScratch.getStore()?.push(dir);
|
|
176644
177273
|
return dir;
|
|
176645
177274
|
}
|
|
@@ -176993,7 +177622,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
176993
177622
|
const owed = openApprovals2(readApprovals2(dir).events).length;
|
|
176994
177623
|
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`);
|
|
176995
177624
|
}
|
|
176996
|
-
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) =>
|
|
177625
|
+
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync80(join81(parentDir, f2)));
|
|
176997
177626
|
if (planInParent.length) {
|
|
176998
177627
|
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}`);
|
|
176999
177628
|
}
|
|
@@ -177154,13 +177783,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177154
177783
|
if (adding) {
|
|
177155
177784
|
const from = str9(flags.from);
|
|
177156
177785
|
if (!from) throw new TrimRefusal2('--add <id> needs --from <file> holding the whole new SCREENS entry (` "<id>": { "screenId": "<id>", \u2026 },`)');
|
|
177157
|
-
print(adopt.addScreen(dir, adding,
|
|
177786
|
+
print(adopt.addScreen(dir, adding, readFileSync97(from, "utf8"), { parent: str9(flags.parent), tab: str9(flags.tab), displayName: str9(flags["display-name"]) }));
|
|
177158
177787
|
return 0;
|
|
177159
177788
|
}
|
|
177160
177789
|
if (target) {
|
|
177161
177790
|
const from = str9(flags.from);
|
|
177162
177791
|
if (!from) throw new TrimRefusal2("--write <id> needs --from <file> holding the whole entry, as --show prints it");
|
|
177163
|
-
print(adopt.replaceScreen(dir, target,
|
|
177792
|
+
print(adopt.replaceScreen(dir, target, readFileSync97(from, "utf8")));
|
|
177164
177793
|
return 0;
|
|
177165
177794
|
}
|
|
177166
177795
|
if (show) {
|
|
@@ -177242,7 +177871,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177242
177871
|
const { keepFromSpec: keepFromSpec2 } = await Promise.resolve().then(() => (init_template_adopt(), template_adopt_exports));
|
|
177243
177872
|
const dir = contentDir(flags);
|
|
177244
177873
|
try {
|
|
177245
|
-
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ??
|
|
177874
|
+
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ?? join81(dir, "SPEC.md"));
|
|
177246
177875
|
const own4 = typeof keep === "string" ? keep.split(",").map((k2) => k2.trim()).filter(Boolean) : [];
|
|
177247
177876
|
keep = [.../* @__PURE__ */ new Set([...spec.keep, ...own4])].join(",");
|
|
177248
177877
|
fromSpec = { fromSpec: {
|
|
@@ -177283,7 +177912,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177283
177912
|
const result = { ...outcome.result, ...fromSpec };
|
|
177284
177913
|
const adoptDir = contentDir(flags);
|
|
177285
177914
|
const kept = flags["dry-run"] !== true && (outcome.code === 0 || outcome.result.forcedKeep === true);
|
|
177286
|
-
if (kept &&
|
|
177915
|
+
if (kept && existsSync80(join81(adoptDir, adoptBits.ADOPT_FILE))) {
|
|
177287
177916
|
try {
|
|
177288
177917
|
const inv = adoptBits.inspectApp(adoptDir);
|
|
177289
177918
|
adoptBits.writeInventory(adoptDir, inv, { companions: "if-missing" });
|
|
@@ -177312,7 +177941,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177312
177941
|
const sourceDir = resolve60(str9(flags["source-dir"]) ?? appDir3);
|
|
177313
177942
|
let meta;
|
|
177314
177943
|
try {
|
|
177315
|
-
meta = JSON.parse(
|
|
177944
|
+
meta = JSON.parse(readFileSync97(join81(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
177316
177945
|
} catch {
|
|
177317
177946
|
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>)` }));
|
|
177318
177947
|
return 2;
|
|
@@ -177322,7 +177951,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177322
177951
|
return 2;
|
|
177323
177952
|
}
|
|
177324
177953
|
try {
|
|
177325
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
177954
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync97(join81(sourceDir, "tokens.json"), "utf8")));
|
|
177326
177955
|
meta = { ...appearance, ...meta };
|
|
177327
177956
|
} catch {
|
|
177328
177957
|
}
|
|
@@ -177344,7 +177973,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177344
177973
|
const force = flags.force === true;
|
|
177345
177974
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
177346
177975
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
177347
|
-
const out2 = mkdtempSync5(
|
|
177976
|
+
const out2 = mkdtempSync5(join81(tmpdir6(), "himi-template-"));
|
|
177348
177977
|
publishScratch.push(out2);
|
|
177349
177978
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
177350
177979
|
const outcome = await buildReleaseFromContent2(buildDir, out2, {
|
|
@@ -177401,7 +178030,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177401
178030
|
let iconHash;
|
|
177402
178031
|
if (iconPath) {
|
|
177403
178032
|
try {
|
|
177404
|
-
const bytes2 =
|
|
178033
|
+
const bytes2 = readFileSync97(iconPath);
|
|
177405
178034
|
payload.icon = bytes2.toString("base64");
|
|
177406
178035
|
iconHash = createHash41("sha256").update(bytes2).digest("hex");
|
|
177407
178036
|
} catch {
|
|
@@ -177588,17 +178217,17 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177588
178217
|
const dir = contentDir(flags);
|
|
177589
178218
|
const { buildContentBundles: buildContentBundles2 } = await loadAuthoring();
|
|
177590
178219
|
const res = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
177591
|
-
const
|
|
178220
|
+
const failed3 = res.compileErrors;
|
|
177592
178221
|
print({
|
|
177593
|
-
ok:
|
|
178222
|
+
ok: failed3.length === 0,
|
|
177594
178223
|
outDir: res.outDir,
|
|
177595
178224
|
built: res.built,
|
|
177596
|
-
...
|
|
178225
|
+
...failed3.length ? { compileErrors: failed3 } : {},
|
|
177597
178226
|
// #642.1b — a stale @wix/himalaya is advisory on `build` (the bundles may
|
|
177598
178227
|
// still compile); `validate --strict` is where it hard-fails.
|
|
177599
178228
|
...res.sdkVersionIssue ? { warnings: [res.sdkVersionIssue] } : {}
|
|
177600
178229
|
});
|
|
177601
|
-
return
|
|
178230
|
+
return failed3.length ? 1 : 0;
|
|
177602
178231
|
}
|
|
177603
178232
|
case "eject": {
|
|
177604
178233
|
const mod = String(pos[1] ?? "");
|
|
@@ -177700,7 +178329,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177700
178329
|
const path2 = dpxSessionTokenPath();
|
|
177701
178330
|
let raw;
|
|
177702
178331
|
try {
|
|
177703
|
-
raw =
|
|
178332
|
+
raw = readFileSync97(path2, "utf8");
|
|
177704
178333
|
} catch {
|
|
177705
178334
|
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`);
|
|
177706
178335
|
}
|
|
@@ -177834,8 +178463,8 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177834
178463
|
const dir = resolve60(out2);
|
|
177835
178464
|
const files = himiPluginFiles2(skills.skillMd);
|
|
177836
178465
|
for (const f2 of files) {
|
|
177837
|
-
mkdirSync41(dirname43(
|
|
177838
|
-
writeFileSync38(
|
|
178466
|
+
mkdirSync41(dirname43(join81(dir, f2.path)), { recursive: true });
|
|
178467
|
+
writeFileSync38(join81(dir, f2.path), f2.text);
|
|
177839
178468
|
}
|
|
177840
178469
|
print({ ok: true, dir, files: files.map((f2) => f2.path), next: [`claude plugin validate ${dir}`, `claude --plugin-dir ${dir}`] });
|
|
177841
178470
|
return 0;
|
|
@@ -177852,13 +178481,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177852
178481
|
case "studio": {
|
|
177853
178482
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
177854
178483
|
const dir = contentDir(flags);
|
|
177855
|
-
if (!
|
|
178484
|
+
if (!existsSync80(join81(dir, "himalaya.content.json"))) {
|
|
177856
178485
|
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/" }));
|
|
177857
178486
|
return 2;
|
|
177858
178487
|
}
|
|
177859
178488
|
if (pos[1] === "reel") {
|
|
177860
178489
|
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
177861
|
-
const out2 = resolve60(str9(flags.out) ??
|
|
178490
|
+
const out2 = resolve60(str9(flags.out) ?? join81(dir, ".himi", "making-of.html"));
|
|
177862
178491
|
const { html, plan } = buildReel2(dir);
|
|
177863
178492
|
mkdirSync41(dirname43(out2), { recursive: true });
|
|
177864
178493
|
writeFileSync38(out2, html);
|
|
@@ -177869,7 +178498,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
177869
178498
|
const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
|
|
177870
178499
|
openUrl2(url2);
|
|
177871
178500
|
}
|
|
177872
|
-
const handover = { file: out2, hint: `hand ${
|
|
178501
|
+
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` };
|
|
177873
178502
|
const report3 = {
|
|
177874
178503
|
ok: true,
|
|
177875
178504
|
file: out2,
|
|
@@ -177930,7 +178559,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
177930
178559
|
} = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
177931
178560
|
const dir = contentDir(flags);
|
|
177932
178561
|
const journal2 = journalPath2(dir);
|
|
177933
|
-
const isContentPackage =
|
|
178562
|
+
const isContentPackage = existsSync80(join81(dir, "himalaya.content.json"));
|
|
177934
178563
|
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" };
|
|
177935
178564
|
const message = pos.slice(1).join(" ").trim();
|
|
177936
178565
|
const approvalFlags = ["approve", "done", "drop"].filter((f2) => flags[f2] !== void 0);
|
|
@@ -178082,7 +178711,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178082
178711
|
case "test": {
|
|
178083
178712
|
const dir = contentDir(flags);
|
|
178084
178713
|
const structuredOutput = flags.json === true || io2.isTTY !== true;
|
|
178085
|
-
if (
|
|
178714
|
+
if (existsSync80(join81(dir, "functions"))) {
|
|
178086
178715
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
178087
178716
|
const loaded = await loadFunctionsApp2(dir);
|
|
178088
178717
|
const results = [];
|
|
@@ -178214,7 +178843,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178214
178843
|
io2.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
178215
178844
|
return 2;
|
|
178216
178845
|
}
|
|
178217
|
-
const sources = collectWorkerSources2(
|
|
178846
|
+
const sources = collectWorkerSources2(join81(dir, "tier5-src"), screen.bundleName);
|
|
178218
178847
|
if (!sources) {
|
|
178219
178848
|
io2.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
178220
178849
|
return 2;
|
|
@@ -178392,7 +179021,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178392
179021
|
const sp = await runShotsPass2({
|
|
178393
179022
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
178394
179023
|
tokens: outcome.tokens,
|
|
178395
|
-
outDir:
|
|
179024
|
+
outDir: join81(dir, ".himi", "shots"),
|
|
178396
179025
|
width: 390,
|
|
178397
179026
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
178398
179027
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -178432,7 +179061,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
178432
179061
|
releaseId: result.releaseId,
|
|
178433
179062
|
releasePayload: release2,
|
|
178434
179063
|
descriptors: attestedDescriptors,
|
|
178435
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
179064
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join81(dir, ".himi", "shots", name)])),
|
|
178436
179065
|
coverage: {
|
|
178437
179066
|
screens: crawledScreens.size,
|
|
178438
179067
|
actionsDispatched: result.actions.exercised,
|
|
@@ -178557,7 +179186,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178557
179186
|
return 2;
|
|
178558
179187
|
}
|
|
178559
179188
|
try {
|
|
178560
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
179189
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync97(stateArg.replace(/^@/, ""), "utf8");
|
|
178561
179190
|
injectedState = JSON.parse(raw);
|
|
178562
179191
|
} catch (e2) {
|
|
178563
179192
|
io2.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e2.message}` }));
|
|
@@ -178572,7 +179201,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178572
179201
|
return 2;
|
|
178573
179202
|
}
|
|
178574
179203
|
try {
|
|
178575
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
179204
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync97(inputArg.replace(/^@/, ""), "utf8");
|
|
178576
179205
|
const parsed = JSON.parse(raw);
|
|
178577
179206
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
178578
179207
|
injectedInput = parsed;
|
|
@@ -178654,7 +179283,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
178654
179283
|
const diagnostics = (outcome.lint ?? []).find((s2) => s2.screenId === screenId)?.issues ?? [];
|
|
178655
179284
|
let pngFile;
|
|
178656
179285
|
let attestationPngFile;
|
|
178657
|
-
const shotPath =
|
|
179286
|
+
const shotPath = join81(dir, ".himi", "shots", `${screenId}.png`);
|
|
178658
179287
|
const pngTarget = typeof flags.png === "string" ? str9(flags.png) : flags.png === true ? shotPath : void 0;
|
|
178659
179288
|
if (pngTarget && r2.pngBase64) {
|
|
178660
179289
|
pngFile = writePngFile(pngTarget, r2.pngBase64);
|
|
@@ -179013,7 +179642,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179013
179642
|
io2.error(JSON.stringify(linked));
|
|
179014
179643
|
return 1;
|
|
179015
179644
|
}
|
|
179016
|
-
if (
|
|
179645
|
+
if (existsSync80(dest)) {
|
|
179017
179646
|
if (!statSync21(dest).isDirectory()) {
|
|
179018
179647
|
io2.error(JSON.stringify({
|
|
179019
179648
|
error: `${dest} exists and is not a directory`,
|
|
@@ -179026,7 +179655,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179026
179655
|
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" }));
|
|
179027
179656
|
return 1;
|
|
179028
179657
|
}
|
|
179029
|
-
if (replace && occupied && !
|
|
179658
|
+
if (replace && occupied && !existsSync80(join81(dest, "himalaya.content.json"))) {
|
|
179030
179659
|
io2.error(JSON.stringify({
|
|
179031
179660
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
179032
179661
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -179224,9 +179853,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179224
179853
|
})));
|
|
179225
179854
|
return 1;
|
|
179226
179855
|
}
|
|
179227
|
-
const
|
|
179228
|
-
if (!
|
|
179229
|
-
io2.error(JSON.stringify(pushFailure2("invalid_patch",
|
|
179856
|
+
const planned2 = planFromPayload2(payload, baseForPlan.manifest, parsed.selectors);
|
|
179857
|
+
if (!planned2.ok) {
|
|
179858
|
+
io2.error(JSON.stringify(pushFailure2("invalid_patch", planned2.error), null, 2));
|
|
179230
179859
|
return 1;
|
|
179231
179860
|
}
|
|
179232
179861
|
const patchUxEvidence = handoverUxEvidence(dir, {
|
|
@@ -179263,7 +179892,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179263
179892
|
return runReleasePatch({
|
|
179264
179893
|
door: "push --only",
|
|
179265
179894
|
app,
|
|
179266
|
-
plan:
|
|
179895
|
+
plan: planned2.plan,
|
|
179267
179896
|
draft: onlyDraft,
|
|
179268
179897
|
// PIN the base that was actually validated. Passing `fromRelease` only when the user
|
|
179269
179898
|
// named one would let `runReleasePatch` resolve "current" a SECOND time, so a publish
|
|
@@ -179734,7 +180363,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179734
180363
|
}
|
|
179735
180364
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
179736
180365
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
179737
|
-
const built = mkdtempSync5(
|
|
180366
|
+
const built = mkdtempSync5(join81(tmpdir6(), "himi-pack-"));
|
|
179738
180367
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
179739
180368
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
179740
180369
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -179941,7 +180570,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
179941
180570
|
}));
|
|
179942
180571
|
return 1;
|
|
179943
180572
|
}
|
|
179944
|
-
const archive =
|
|
180573
|
+
const archive = readFileSync97(resolve60(file2));
|
|
179945
180574
|
const result = await client2().createPackageShare({
|
|
179946
180575
|
app: opened.header.app,
|
|
179947
180576
|
releaseId: opened.header.releaseId,
|
|
@@ -180038,11 +180667,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180038
180667
|
const app = await appId(dir2);
|
|
180039
180668
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
180040
180669
|
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
180041
|
-
temp = mkdtempSync5(
|
|
180670
|
+
temp = mkdtempSync5(join81(tmpdir6(), "himi-run-build-"));
|
|
180042
180671
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
180043
180672
|
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
180044
180673
|
servedMissing = initial.missingBundles;
|
|
180045
|
-
source =
|
|
180674
|
+
source = join81(temp, app);
|
|
180046
180675
|
}
|
|
180047
180676
|
const chromeArg = str9(flags.chrome) ?? "preview";
|
|
180048
180677
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -180081,7 +180710,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180081
180710
|
if (!recordKit) return;
|
|
180082
180711
|
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
180083
180712
|
const failure = record2(served2, { ok: true, at: startedAt });
|
|
180084
|
-
if (!recorded) io2.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${
|
|
180713
|
+
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.` }));
|
|
180085
180714
|
await refreshBoard();
|
|
180086
180715
|
};
|
|
180087
180716
|
const retract = async () => {
|
|
@@ -180117,7 +180746,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180117
180746
|
const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
180118
180747
|
const hhpPreviewRoute = watch2 ? (await Promise.resolve().then(() => (init_hhp_preview(), hhp_preview_exports))).hhpPreviewResponse : null;
|
|
180119
180748
|
const bus = watchKit ? new watchKit.ReloadBus() : void 0;
|
|
180120
|
-
if (watch2) served = mkdtempSync5(
|
|
180749
|
+
if (watch2) served = mkdtempSync5(join81(tmpdir6(), "himi-run-served-"));
|
|
180121
180750
|
const running = await runPackage2(source, {
|
|
180122
180751
|
port,
|
|
180123
180752
|
chrome: chromeArg,
|
|
@@ -180146,10 +180775,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180146
180775
|
await announce(running);
|
|
180147
180776
|
if (watchKit && bus) {
|
|
180148
180777
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
180149
|
-
const live3 =
|
|
180150
|
-
const manifestOf = (tree) => JSON.parse(
|
|
180778
|
+
const live3 = join81(running.releaseRoot, running.app);
|
|
180779
|
+
const manifestOf = (tree) => JSON.parse(readFileSync97(join81(tree, "release-manifest.json"), "utf8"));
|
|
180151
180780
|
let current = manifestOf(live3);
|
|
180152
|
-
const
|
|
180781
|
+
const failed3 = async (message) => {
|
|
180153
180782
|
if (stopping) return;
|
|
180154
180783
|
bus.publish("build.failed", { message });
|
|
180155
180784
|
record2(running, { ok: false, at: (/* @__PURE__ */ new Date()).toISOString(), error: message });
|
|
@@ -180158,33 +180787,33 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180158
180787
|
};
|
|
180159
180788
|
rebuild = watchKit.serialize(async () => {
|
|
180160
180789
|
const t0 = Date.now();
|
|
180161
|
-
const next = mkdtempSync5(
|
|
180790
|
+
const next = mkdtempSync5(join81(tmpdir6(), "himi-run-build-"));
|
|
180162
180791
|
try {
|
|
180163
180792
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
180164
180793
|
if (bres.compileErrors.length) {
|
|
180165
180794
|
const first = bres.compileErrors[0];
|
|
180166
180795
|
const diag = first.errors[0];
|
|
180167
|
-
await
|
|
180796
|
+
await failed3(`${first.bundle}: ${diag ? `${diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ""} ` : ""}${diag.text}` : "did not compile"}`);
|
|
180168
180797
|
return;
|
|
180169
180798
|
}
|
|
180170
180799
|
const hasWorkers = bres.built.length > 0;
|
|
180171
180800
|
const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, freshModule: true });
|
|
180172
180801
|
const blocker = watchKit.rebuildBlocker(outcome, servedMissing);
|
|
180173
180802
|
if (blocker) {
|
|
180174
|
-
await
|
|
180803
|
+
await failed3(blocker);
|
|
180175
180804
|
return;
|
|
180176
180805
|
}
|
|
180177
180806
|
if (stopping) return;
|
|
180178
|
-
const fresh = manifestOf(
|
|
180807
|
+
const fresh = manifestOf(join81(next, running.app));
|
|
180179
180808
|
const diff = watchKit.diffReleases(current, fresh);
|
|
180180
180809
|
const { describeChanges: describeChanges2, headline: headline2 } = await Promise.resolve().then(() => (init_build_changes(), build_changes_exports));
|
|
180181
|
-
const changes = describeChanges2(live3,
|
|
180810
|
+
const changes = describeChanges2(live3, join81(next, running.app), diff);
|
|
180182
180811
|
const retired = `${live3}.retired-${Date.now()}`;
|
|
180183
180812
|
renameSync12(live3, retired);
|
|
180184
180813
|
try {
|
|
180185
|
-
renameSync12(
|
|
180814
|
+
renameSync12(join81(next, running.app), live3);
|
|
180186
180815
|
} catch {
|
|
180187
|
-
cpSync3(
|
|
180816
|
+
cpSync3(join81(next, running.app), live3, { recursive: true });
|
|
180188
180817
|
}
|
|
180189
180818
|
rmSync22(retired, { recursive: true, force: true });
|
|
180190
180819
|
current = fresh;
|
|
@@ -180194,7 +180823,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180194
180823
|
await refreshBoard();
|
|
180195
180824
|
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 }));
|
|
180196
180825
|
} catch (e2) {
|
|
180197
|
-
await
|
|
180826
|
+
await failed3(e2.message.split("\n")[0]);
|
|
180198
180827
|
} finally {
|
|
180199
180828
|
rmSync22(next, { recursive: true, force: true });
|
|
180200
180829
|
}
|
|
@@ -180811,7 +181440,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180811
181440
|
io2.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
180812
181441
|
return 2;
|
|
180813
181442
|
}
|
|
180814
|
-
if (!
|
|
181443
|
+
if (!existsSync80(file2)) {
|
|
180815
181444
|
io2.error(JSON.stringify({ error: `no such file: ${file2}` }));
|
|
180816
181445
|
return 2;
|
|
180817
181446
|
}
|
|
@@ -180867,7 +181496,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180867
181496
|
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."
|
|
180868
181497
|
};
|
|
180869
181498
|
if (kind === "tokens" || kind === "app-config") {
|
|
180870
|
-
const body =
|
|
181499
|
+
const body = readFileSync97(file2, "utf8");
|
|
180871
181500
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
180872
181501
|
return runReleasePatch({
|
|
180873
181502
|
...common,
|
|
@@ -180882,7 +181511,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180882
181511
|
io2.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
180883
181512
|
return 2;
|
|
180884
181513
|
}
|
|
180885
|
-
const descriptor =
|
|
181514
|
+
const descriptor = readFileSync97(file2, "utf8");
|
|
180886
181515
|
try {
|
|
180887
181516
|
JSON.parse(descriptor);
|
|
180888
181517
|
} catch (e2) {
|
|
@@ -180922,7 +181551,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
180922
181551
|
extra: { kind, screen: id, file: { path: file2, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
180923
181552
|
});
|
|
180924
181553
|
}
|
|
180925
|
-
const bytes2 =
|
|
181554
|
+
const bytes2 = readFileSync97(file2);
|
|
180926
181555
|
const sha2 = createHash41("sha256").update(bytes2).digest("hex");
|
|
180927
181556
|
const forScreens = (str9(flags["for-screen"]) ?? "").split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
180928
181557
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
@@ -181066,7 +181695,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181066
181695
|
}
|
|
181067
181696
|
let def;
|
|
181068
181697
|
try {
|
|
181069
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
181698
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync97(arg.slice(1), "utf8") : arg);
|
|
181070
181699
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
181071
181700
|
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}`] }));
|
|
181072
181701
|
return 2;
|
|
@@ -181213,7 +181842,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181213
181842
|
case "testflight": {
|
|
181214
181843
|
if (command === "store" && pos[1] === "iap") {
|
|
181215
181844
|
const { runStoreIap: runStoreIap2, defaultStoreIapDeps: defaultStoreIapDeps2 } = await Promise.resolve().then(() => (init_store_iap(), store_iap_exports));
|
|
181216
|
-
return runStoreIap2(pos, flags, io2, defaultStoreIapDeps2());
|
|
181845
|
+
return runStoreIap2(pos, flags, io2, { ...defaultStoreIapDeps2(), validateConfig: createTrimValidator(deps) });
|
|
181217
181846
|
}
|
|
181218
181847
|
if (str9(flags.provider) === "wix-mobile-release") {
|
|
181219
181848
|
const playerTarget = wixPlayerTestflightTarget(str9(flags.target));
|
|
@@ -181348,7 +181977,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
181348
181977
|
const rememberLastDist = async (jobs2) => {
|
|
181349
181978
|
try {
|
|
181350
181979
|
const dir = contentDir(flags);
|
|
181351
|
-
if (!
|
|
181980
|
+
if (!existsSync80(join81(dir, "himalaya.content.json"))) return;
|
|
181352
181981
|
const { lastDistFromJob: lastDistFromJob2, writeLastDist: writeLastDist2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
|
|
181353
181982
|
const own4 = await appId(dir);
|
|
181354
181983
|
for (const job of jobs2) {
|
|
@@ -181586,7 +182215,7 @@ ${label2}`);
|
|
|
181586
182215
|
const platform = str9(flags.platform)?.split(",").map((p2) => p2.trim()).filter(Boolean);
|
|
181587
182216
|
{
|
|
181588
182217
|
const distDir = contentDir(flags);
|
|
181589
|
-
if (
|
|
182218
|
+
if (existsSync80(join81(distDir, "himalaya.content.json"))) {
|
|
181590
182219
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
181591
182220
|
const errors = issues.filter((i2) => i2.severity === "error");
|
|
181592
182221
|
for (const i2 of issues.filter((i3) => i3.severity === "warning")) {
|
|
@@ -181925,7 +182554,7 @@ ${label2}`);
|
|
|
181925
182554
|
const dpxPath = dpxSessionTokenPath();
|
|
181926
182555
|
let dpx;
|
|
181927
182556
|
try {
|
|
181928
|
-
dpx =
|
|
182557
|
+
dpx = readFileSync97(dpxPath, "utf8").trim();
|
|
181929
182558
|
} catch {
|
|
181930
182559
|
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` }));
|
|
181931
182560
|
return 1;
|
|
@@ -182346,7 +182975,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
|
|
|
182346
182975
|
const path2 = dpxSessionTokenPath();
|
|
182347
182976
|
let raw;
|
|
182348
182977
|
try {
|
|
182349
|
-
raw =
|
|
182978
|
+
raw = readFileSync97(path2, "utf8");
|
|
182350
182979
|
} catch {
|
|
182351
182980
|
io2.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
182352
182981
|
return 1;
|