@wix/himalaya-cli 0.944.0 → 0.946.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +4 -3
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/community-club/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
- package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +68 -24
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +7 -3
package/dist/cli.mjs
CHANGED
|
@@ -18546,7 +18546,6 @@ function shouldRevealError(args) {
|
|
|
18546
18546
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
18547
18547
|
var init_validation = __esm({
|
|
18548
18548
|
"../../core/ts/src/validation.ts"() {
|
|
18549
|
-
"use strict";
|
|
18550
18549
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
18551
18550
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
18552
18551
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -21970,7 +21969,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
21970
21969
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
21971
21970
|
var init_worker_subtree = __esm({
|
|
21972
21971
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
21973
|
-
"use strict";
|
|
21974
21972
|
init_worker_subtree_safe_types_generated();
|
|
21975
21973
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
21976
21974
|
maxEncodedBytes: 65536,
|
|
@@ -55209,7 +55207,10 @@ function ownerPlaneHint(status, error, target) {
|
|
|
55209
55207
|
return { hint: "this environment has no token signing secret configured \u2014 an operator must set SERVE_CONTROL_SIGNING_SECRET" };
|
|
55210
55208
|
}
|
|
55211
55209
|
if (error === "owner_requires_selfserve_token") {
|
|
55212
|
-
|
|
55210
|
+
const base = `that credential is an operator token, not a self-serve one \u2014 run \`himi login --browser --target ${target}\` to get an owner identity`;
|
|
55211
|
+
return {
|
|
55212
|
+
hint: isPublicTarget(target) ? base : `${base}. On ${target} that REPLACES the employee token stored for this target, and \`himi dist\` then charges the self-serve tier instead of the employee one \u2014 deliberately the tightest of the three, so far fewer concurrent builds and far fewer per day. \`himi login --dpx --target ${target}\` switches back.`
|
|
55213
|
+
};
|
|
55213
55214
|
}
|
|
55214
55215
|
if (error === "token_revoked") {
|
|
55215
55216
|
return { hint: `this token was revoked \u2014 run \`himi login --browser --target ${target}\` to get a new one` };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.946.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"artifactId": "himalaya-cli"
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"falconPackageHash": "
|
|
67
|
+
"falconPackageHash": "3f6060102b6c94b2c8e6ed84fd14f6c0e0091b8c611331ef95f97e2a"
|
|
68
68
|
}
|
|
@@ -53,6 +53,17 @@ const HTML_BODY = /<!DOCTYPE html|<html[\s>]|<head[\s>]/i;
|
|
|
53
53
|
* "app":"…"}` — and it is short enough to slip under MAX_RAW, so truncation
|
|
54
54
|
* never caught it and the owner read the machine's word for it. */
|
|
55
55
|
const JSON_BODY = /HTTP \d{3}:\s*[[{]/;
|
|
56
|
+
/** `HTTP <status> [SERVICE_CODE]: message` — the shape a Wix service uses when
|
|
57
|
+
* it refuses with a named reason. */
|
|
58
|
+
const CODED = /HTTP (\d{3}) \[([A-Z0-9_]+)\]/;
|
|
59
|
+
/**
|
|
60
|
+
* The codes that all mean one thing to an owner: the session cannot address this
|
|
61
|
+
* business. Found on a real session whose account did not own the business the app
|
|
62
|
+
* had persisted — Home rendered
|
|
63
|
+
* `HTTP 428 [MISSING_METASITE_ID]: Couldn't extract metasiteId from the request
|
|
64
|
+
* context` where "6 orders" belongs.
|
|
65
|
+
*/
|
|
66
|
+
const SITE_CONTEXT_CODES = ["MISSING_METASITE_ID", "MISSING_REQUEST_SITE_CONTEXT", "MISSING_SITE_CONTEXT"];
|
|
56
67
|
/** Longest raw upstream text worth showing. Beyond this it stops being a
|
|
57
68
|
* message and starts being a payload dump. */
|
|
58
69
|
const MAX_RAW = 200;
|
|
@@ -69,6 +80,29 @@ const MAX_RAW = 200;
|
|
|
69
80
|
*/
|
|
70
81
|
function humanWireError(msg: string): string {
|
|
71
82
|
const status = STATUS.exec(msg)?.[1];
|
|
83
|
+
// A JSON ENVELOPE or a NAMED REASON CODE is the machine's word for it, and the
|
|
84
|
+
// owner gets neither. Both reductions used to live in `ownerDisplayError` only,
|
|
85
|
+
// on the belief that this function's output was parsed downstream — see the note
|
|
86
|
+
// on `ownerLoadError`, which records why that was wrong and how it was checked.
|
|
87
|
+
if (JSON_BODY.test(msg) && status) {
|
|
88
|
+
return copyParam(
|
|
89
|
+
"ownerCommon.upstreamStatus",
|
|
90
|
+
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const coded = CODED.exec(msg);
|
|
94
|
+
if (coded) {
|
|
95
|
+
if (SITE_CONTEXT_CODES.includes(coded[2])) {
|
|
96
|
+
return copyParam(
|
|
97
|
+
"ownerCommon.noSiteContext",
|
|
98
|
+
"This business isn’t available to your Wix account right now. Switch business, or sign in again as its owner.",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return copyParam(
|
|
102
|
+
"ownerCommon.upstreamStatus",
|
|
103
|
+
`Wix returned an error (HTTP ${coded[1]}). Try again in a moment.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
72
106
|
if (HTML_BODY.test(msg)) {
|
|
73
107
|
if (status === "403") {
|
|
74
108
|
return copyParam(
|
|
@@ -101,36 +135,46 @@ export function ownerPreviewUnavailable(): string {
|
|
|
101
135
|
/**
|
|
102
136
|
* `ownerLoadError` for a screen that does nothing but RENDER the string.
|
|
103
137
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* native write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
138
|
+
* One difference left, and it is about WHERE the app is rather than what the
|
|
139
|
+
* error says: this names the web preview when there IS one. `isBridgeUnavailable`
|
|
140
|
+
* reads "not live" as "preview", and native injects no mode at all, so the
|
|
141
|
+
* default would answer a device-side `HTTP 503` with "open this app on a device"
|
|
142
|
+
* — on the device. That predicate is deliberately left alone: native
|
|
143
|
+
* write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
111
144
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* `CATALOG_V3_CALLING_CATALOG_V1_API` in it to choose its v1 fallback, and
|
|
115
|
-
* `owner-load-error.test.ts` pins that verbatim. A display-only caller has
|
|
116
|
-
* no such reader, and the bridge's typed refusals are JSON and short enough
|
|
117
|
-
* (68 chars) to slip under MAX_RAW, so nothing else was catching them.
|
|
118
|
-
*
|
|
119
|
-
* So: use this ONLY where the value is rendered and never matched on.
|
|
145
|
+
* The reductions this used to add are now in `humanWireError`, so every owner
|
|
146
|
+
* screen gets them rather than the two that happened to call this.
|
|
120
147
|
*/
|
|
121
148
|
export function ownerDisplayError(e: unknown): string {
|
|
122
149
|
if (isOwnerPreviewHost() && isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
123
|
-
|
|
124
|
-
const status = STATUS.exec(msg)?.[1];
|
|
125
|
-
if (JSON_BODY.test(msg) && status) {
|
|
126
|
-
return copyParam(
|
|
127
|
-
"ownerCommon.upstreamStatus",
|
|
128
|
-
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
return humanWireError(msg);
|
|
150
|
+
return humanWireError(String((e as Error)?.message ?? e));
|
|
132
151
|
}
|
|
133
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The default. Reduces the same shapes as `ownerDisplayError`.
|
|
155
|
+
*
|
|
156
|
+
* It used to reduce LESS, on the stated grounds that its output is parsed
|
|
157
|
+
* downstream — "the products worker matches `CATALOG_V3_CALLING_CATALOG_V1_API`
|
|
158
|
+
* in it to choose its v1 fallback". **That was not true**, and it cost 17 owner
|
|
159
|
+
* screens their error copy: they printed `HTTP 428 [MISSING_METASITE_ID]: …`
|
|
160
|
+
* verbatim for a contract that does not exist.
|
|
161
|
+
*
|
|
162
|
+
* Checked before changing it, and worth recording so nobody restores the belief:
|
|
163
|
+
*
|
|
164
|
+
* • the catalog v1/v3 decision is made INSIDE the Wix stores SDK, on the RAW
|
|
165
|
+
* thrown error — its `catalogVersionFromMismatch` reads the error's own
|
|
166
|
+
* `message`, and only that module calls it. It never sees this function's
|
|
167
|
+
* output.
|
|
168
|
+
* • `CATALOG_V3_CALLING_CATALOG_V1_API` appears nowhere else in the codebase
|
|
169
|
+
* outside comments, tests and that one SDK module.
|
|
170
|
+
* • the collection framework's `clearOnError` is handed the RAW error
|
|
171
|
+
* (`error => /401|403|forbidden/i.test(String(error))`), separately from
|
|
172
|
+
* `errorMessage: ownerLoadError` — so the one place that does match on a
|
|
173
|
+
* failure is unaffected by what this returns.
|
|
174
|
+
*
|
|
175
|
+
* So: the raw error remains available to logic everywhere it was; this function's
|
|
176
|
+
* result is display copy, and now reads like it.
|
|
177
|
+
*/
|
|
134
178
|
export function ownerLoadError(e: unknown): string {
|
|
135
179
|
const msg = String((e as Error)?.message ?? e);
|
|
136
180
|
if (isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
@@ -53,6 +53,17 @@ const HTML_BODY = /<!DOCTYPE html|<html[\s>]|<head[\s>]/i;
|
|
|
53
53
|
* "app":"…"}` — and it is short enough to slip under MAX_RAW, so truncation
|
|
54
54
|
* never caught it and the owner read the machine's word for it. */
|
|
55
55
|
const JSON_BODY = /HTTP \d{3}:\s*[[{]/;
|
|
56
|
+
/** `HTTP <status> [SERVICE_CODE]: message` — the shape a Wix service uses when
|
|
57
|
+
* it refuses with a named reason. */
|
|
58
|
+
const CODED = /HTTP (\d{3}) \[([A-Z0-9_]+)\]/;
|
|
59
|
+
/**
|
|
60
|
+
* The codes that all mean one thing to an owner: the session cannot address this
|
|
61
|
+
* business. Found on a real session whose account did not own the business the app
|
|
62
|
+
* had persisted — Home rendered
|
|
63
|
+
* `HTTP 428 [MISSING_METASITE_ID]: Couldn't extract metasiteId from the request
|
|
64
|
+
* context` where "6 orders" belongs.
|
|
65
|
+
*/
|
|
66
|
+
const SITE_CONTEXT_CODES = ["MISSING_METASITE_ID", "MISSING_REQUEST_SITE_CONTEXT", "MISSING_SITE_CONTEXT"];
|
|
56
67
|
/** Longest raw upstream text worth showing. Beyond this it stops being a
|
|
57
68
|
* message and starts being a payload dump. */
|
|
58
69
|
const MAX_RAW = 200;
|
|
@@ -69,6 +80,29 @@ const MAX_RAW = 200;
|
|
|
69
80
|
*/
|
|
70
81
|
function humanWireError(msg: string): string {
|
|
71
82
|
const status = STATUS.exec(msg)?.[1];
|
|
83
|
+
// A JSON ENVELOPE or a NAMED REASON CODE is the machine's word for it, and the
|
|
84
|
+
// owner gets neither. Both reductions used to live in `ownerDisplayError` only,
|
|
85
|
+
// on the belief that this function's output was parsed downstream — see the note
|
|
86
|
+
// on `ownerLoadError`, which records why that was wrong and how it was checked.
|
|
87
|
+
if (JSON_BODY.test(msg) && status) {
|
|
88
|
+
return copyParam(
|
|
89
|
+
"ownerCommon.upstreamStatus",
|
|
90
|
+
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const coded = CODED.exec(msg);
|
|
94
|
+
if (coded) {
|
|
95
|
+
if (SITE_CONTEXT_CODES.includes(coded[2])) {
|
|
96
|
+
return copyParam(
|
|
97
|
+
"ownerCommon.noSiteContext",
|
|
98
|
+
"This business isn’t available to your Wix account right now. Switch business, or sign in again as its owner.",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return copyParam(
|
|
102
|
+
"ownerCommon.upstreamStatus",
|
|
103
|
+
`Wix returned an error (HTTP ${coded[1]}). Try again in a moment.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
72
106
|
if (HTML_BODY.test(msg)) {
|
|
73
107
|
if (status === "403") {
|
|
74
108
|
return copyParam(
|
|
@@ -101,36 +135,46 @@ export function ownerPreviewUnavailable(): string {
|
|
|
101
135
|
/**
|
|
102
136
|
* `ownerLoadError` for a screen that does nothing but RENDER the string.
|
|
103
137
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* native write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
138
|
+
* One difference left, and it is about WHERE the app is rather than what the
|
|
139
|
+
* error says: this names the web preview when there IS one. `isBridgeUnavailable`
|
|
140
|
+
* reads "not live" as "preview", and native injects no mode at all, so the
|
|
141
|
+
* default would answer a device-side `HTTP 503` with "open this app on a device"
|
|
142
|
+
* — on the device. That predicate is deliberately left alone: native
|
|
143
|
+
* write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
111
144
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* `CATALOG_V3_CALLING_CATALOG_V1_API` in it to choose its v1 fallback, and
|
|
115
|
-
* `owner-load-error.test.ts` pins that verbatim. A display-only caller has
|
|
116
|
-
* no such reader, and the bridge's typed refusals are JSON and short enough
|
|
117
|
-
* (68 chars) to slip under MAX_RAW, so nothing else was catching them.
|
|
118
|
-
*
|
|
119
|
-
* So: use this ONLY where the value is rendered and never matched on.
|
|
145
|
+
* The reductions this used to add are now in `humanWireError`, so every owner
|
|
146
|
+
* screen gets them rather than the two that happened to call this.
|
|
120
147
|
*/
|
|
121
148
|
export function ownerDisplayError(e: unknown): string {
|
|
122
149
|
if (isOwnerPreviewHost() && isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
123
|
-
|
|
124
|
-
const status = STATUS.exec(msg)?.[1];
|
|
125
|
-
if (JSON_BODY.test(msg) && status) {
|
|
126
|
-
return copyParam(
|
|
127
|
-
"ownerCommon.upstreamStatus",
|
|
128
|
-
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
return humanWireError(msg);
|
|
150
|
+
return humanWireError(String((e as Error)?.message ?? e));
|
|
132
151
|
}
|
|
133
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The default. Reduces the same shapes as `ownerDisplayError`.
|
|
155
|
+
*
|
|
156
|
+
* It used to reduce LESS, on the stated grounds that its output is parsed
|
|
157
|
+
* downstream — "the products worker matches `CATALOG_V3_CALLING_CATALOG_V1_API`
|
|
158
|
+
* in it to choose its v1 fallback". **That was not true**, and it cost 17 owner
|
|
159
|
+
* screens their error copy: they printed `HTTP 428 [MISSING_METASITE_ID]: …`
|
|
160
|
+
* verbatim for a contract that does not exist.
|
|
161
|
+
*
|
|
162
|
+
* Checked before changing it, and worth recording so nobody restores the belief:
|
|
163
|
+
*
|
|
164
|
+
* • the catalog v1/v3 decision is made INSIDE the Wix stores SDK, on the RAW
|
|
165
|
+
* thrown error — its `catalogVersionFromMismatch` reads the error's own
|
|
166
|
+
* `message`, and only that module calls it. It never sees this function's
|
|
167
|
+
* output.
|
|
168
|
+
* • `CATALOG_V3_CALLING_CATALOG_V1_API` appears nowhere else in the codebase
|
|
169
|
+
* outside comments, tests and that one SDK module.
|
|
170
|
+
* • the collection framework's `clearOnError` is handed the RAW error
|
|
171
|
+
* (`error => /401|403|forbidden/i.test(String(error))`), separately from
|
|
172
|
+
* `errorMessage: ownerLoadError` — so the one place that does match on a
|
|
173
|
+
* failure is unaffected by what this returns.
|
|
174
|
+
*
|
|
175
|
+
* So: the raw error remains available to logic everywhere it was; this function's
|
|
176
|
+
* result is display copy, and now reads like it.
|
|
177
|
+
*/
|
|
134
178
|
export function ownerLoadError(e: unknown): string {
|
|
135
179
|
const msg = String((e as Error)?.message ?? e);
|
|
136
180
|
if (isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
@@ -13,7 +13,11 @@ import { queryMembers } from "@himalaya/wix-members";
|
|
|
13
13
|
import { queryReviews } from "@himalaya/wix-reviews";
|
|
14
14
|
import { queryReservations } from "@himalaya/wix-table-reservations";
|
|
15
15
|
import { getSiteAnalytics, getSiteTimeZone, localDateRange, localDateOf, localMidnightUtc } from "@himalaya/wix-analytics";
|
|
16
|
-
|
|
16
|
+
// `ownerDisplayError`, not `ownerLoadError`: every string below is bound into a
|
|
17
|
+
// `text(...)` and never matched on — the RAW reason is kept beside it in
|
|
18
|
+
// `<part>Reason` for anything that needs it — so the display-only reduction is
|
|
19
|
+
// both safe here and the reason a 428 reason code stopped reaching the owner.
|
|
20
|
+
import { ownerDisplayError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
|
|
17
21
|
import { DEMO_DASHBOARD, DEMO_NOTE, DEMO_TODAY } from "../_shared/owner-preview-demo.js";
|
|
18
22
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
19
23
|
import { formatCurrency } from "../_shared/engine-intl.js";
|
|
@@ -566,7 +570,7 @@ async function loadSource(source: HomeSourceId, parts = sourceParts(source)): Pr
|
|
|
566
570
|
const item = settled[index];
|
|
567
571
|
if (item.status === "fulfilled") result[part] = item.value.payload;
|
|
568
572
|
else {
|
|
569
|
-
result[`${part}Error`] =
|
|
573
|
+
result[`${part}Error`] = ownerDisplayError(item.reason);
|
|
570
574
|
result[`${part}Reason`] = item.reason;
|
|
571
575
|
}
|
|
572
576
|
}
|
|
@@ -798,7 +802,7 @@ async function loadDashboard(s: HomeState, sources: HomeSourceId[]): Promise<Hom
|
|
|
798
802
|
if (failedReasons.length > 0 && failedReasons.every((reason) => isBridgeUnavailable(reason))) {
|
|
799
803
|
return demoDashboard(shape({ ...s, sourceStates: [], sourceFailures: [] }));
|
|
800
804
|
}
|
|
801
|
-
return shape({ ...composeState(), status: "error", error:
|
|
805
|
+
return shape({ ...composeState(), status: "error", error: ownerDisplayError(failedReasons[0]) });
|
|
802
806
|
}
|
|
803
807
|
return filteredSchedule(composeState(), activeScheduleFilter);
|
|
804
808
|
}
|
|
@@ -53,6 +53,17 @@ const HTML_BODY = /<!DOCTYPE html|<html[\s>]|<head[\s>]/i;
|
|
|
53
53
|
* "app":"…"}` — and it is short enough to slip under MAX_RAW, so truncation
|
|
54
54
|
* never caught it and the owner read the machine's word for it. */
|
|
55
55
|
const JSON_BODY = /HTTP \d{3}:\s*[[{]/;
|
|
56
|
+
/** `HTTP <status> [SERVICE_CODE]: message` — the shape a Wix service uses when
|
|
57
|
+
* it refuses with a named reason. */
|
|
58
|
+
const CODED = /HTTP (\d{3}) \[([A-Z0-9_]+)\]/;
|
|
59
|
+
/**
|
|
60
|
+
* The codes that all mean one thing to an owner: the session cannot address this
|
|
61
|
+
* business. Found on a real session whose account did not own the business the app
|
|
62
|
+
* had persisted — Home rendered
|
|
63
|
+
* `HTTP 428 [MISSING_METASITE_ID]: Couldn't extract metasiteId from the request
|
|
64
|
+
* context` where "6 orders" belongs.
|
|
65
|
+
*/
|
|
66
|
+
const SITE_CONTEXT_CODES = ["MISSING_METASITE_ID", "MISSING_REQUEST_SITE_CONTEXT", "MISSING_SITE_CONTEXT"];
|
|
56
67
|
/** Longest raw upstream text worth showing. Beyond this it stops being a
|
|
57
68
|
* message and starts being a payload dump. */
|
|
58
69
|
const MAX_RAW = 200;
|
|
@@ -69,6 +80,29 @@ const MAX_RAW = 200;
|
|
|
69
80
|
*/
|
|
70
81
|
function humanWireError(msg: string): string {
|
|
71
82
|
const status = STATUS.exec(msg)?.[1];
|
|
83
|
+
// A JSON ENVELOPE or a NAMED REASON CODE is the machine's word for it, and the
|
|
84
|
+
// owner gets neither. Both reductions used to live in `ownerDisplayError` only,
|
|
85
|
+
// on the belief that this function's output was parsed downstream — see the note
|
|
86
|
+
// on `ownerLoadError`, which records why that was wrong and how it was checked.
|
|
87
|
+
if (JSON_BODY.test(msg) && status) {
|
|
88
|
+
return copyParam(
|
|
89
|
+
"ownerCommon.upstreamStatus",
|
|
90
|
+
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const coded = CODED.exec(msg);
|
|
94
|
+
if (coded) {
|
|
95
|
+
if (SITE_CONTEXT_CODES.includes(coded[2])) {
|
|
96
|
+
return copyParam(
|
|
97
|
+
"ownerCommon.noSiteContext",
|
|
98
|
+
"This business isn’t available to your Wix account right now. Switch business, or sign in again as its owner.",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return copyParam(
|
|
102
|
+
"ownerCommon.upstreamStatus",
|
|
103
|
+
`Wix returned an error (HTTP ${coded[1]}). Try again in a moment.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
72
106
|
if (HTML_BODY.test(msg)) {
|
|
73
107
|
if (status === "403") {
|
|
74
108
|
return copyParam(
|
|
@@ -101,36 +135,46 @@ export function ownerPreviewUnavailable(): string {
|
|
|
101
135
|
/**
|
|
102
136
|
* `ownerLoadError` for a screen that does nothing but RENDER the string.
|
|
103
137
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* native write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
138
|
+
* One difference left, and it is about WHERE the app is rather than what the
|
|
139
|
+
* error says: this names the web preview when there IS one. `isBridgeUnavailable`
|
|
140
|
+
* reads "not live" as "preview", and native injects no mode at all, so the
|
|
141
|
+
* default would answer a device-side `HTTP 503` with "open this app on a device"
|
|
142
|
+
* — on the device. That predicate is deliberately left alone: native
|
|
143
|
+
* write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
111
144
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* `CATALOG_V3_CALLING_CATALOG_V1_API` in it to choose its v1 fallback, and
|
|
115
|
-
* `owner-load-error.test.ts` pins that verbatim. A display-only caller has
|
|
116
|
-
* no such reader, and the bridge's typed refusals are JSON and short enough
|
|
117
|
-
* (68 chars) to slip under MAX_RAW, so nothing else was catching them.
|
|
118
|
-
*
|
|
119
|
-
* So: use this ONLY where the value is rendered and never matched on.
|
|
145
|
+
* The reductions this used to add are now in `humanWireError`, so every owner
|
|
146
|
+
* screen gets them rather than the two that happened to call this.
|
|
120
147
|
*/
|
|
121
148
|
export function ownerDisplayError(e: unknown): string {
|
|
122
149
|
if (isOwnerPreviewHost() && isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
123
|
-
|
|
124
|
-
const status = STATUS.exec(msg)?.[1];
|
|
125
|
-
if (JSON_BODY.test(msg) && status) {
|
|
126
|
-
return copyParam(
|
|
127
|
-
"ownerCommon.upstreamStatus",
|
|
128
|
-
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
return humanWireError(msg);
|
|
150
|
+
return humanWireError(String((e as Error)?.message ?? e));
|
|
132
151
|
}
|
|
133
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The default. Reduces the same shapes as `ownerDisplayError`.
|
|
155
|
+
*
|
|
156
|
+
* It used to reduce LESS, on the stated grounds that its output is parsed
|
|
157
|
+
* downstream — "the products worker matches `CATALOG_V3_CALLING_CATALOG_V1_API`
|
|
158
|
+
* in it to choose its v1 fallback". **That was not true**, and it cost 17 owner
|
|
159
|
+
* screens their error copy: they printed `HTTP 428 [MISSING_METASITE_ID]: …`
|
|
160
|
+
* verbatim for a contract that does not exist.
|
|
161
|
+
*
|
|
162
|
+
* Checked before changing it, and worth recording so nobody restores the belief:
|
|
163
|
+
*
|
|
164
|
+
* • the catalog v1/v3 decision is made INSIDE the Wix stores SDK, on the RAW
|
|
165
|
+
* thrown error — its `catalogVersionFromMismatch` reads the error's own
|
|
166
|
+
* `message`, and only that module calls it. It never sees this function's
|
|
167
|
+
* output.
|
|
168
|
+
* • `CATALOG_V3_CALLING_CATALOG_V1_API` appears nowhere else in the codebase
|
|
169
|
+
* outside comments, tests and that one SDK module.
|
|
170
|
+
* • the collection framework's `clearOnError` is handed the RAW error
|
|
171
|
+
* (`error => /401|403|forbidden/i.test(String(error))`), separately from
|
|
172
|
+
* `errorMessage: ownerLoadError` — so the one place that does match on a
|
|
173
|
+
* failure is unaffected by what this returns.
|
|
174
|
+
*
|
|
175
|
+
* So: the raw error remains available to logic everywhere it was; this function's
|
|
176
|
+
* result is display copy, and now reads like it.
|
|
177
|
+
*/
|
|
134
178
|
export function ownerLoadError(e: unknown): string {
|
|
135
179
|
const msg = String((e as Error)?.message ?? e);
|
|
136
180
|
if (isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
@@ -53,6 +53,17 @@ const HTML_BODY = /<!DOCTYPE html|<html[\s>]|<head[\s>]/i;
|
|
|
53
53
|
* "app":"…"}` — and it is short enough to slip under MAX_RAW, so truncation
|
|
54
54
|
* never caught it and the owner read the machine's word for it. */
|
|
55
55
|
const JSON_BODY = /HTTP \d{3}:\s*[[{]/;
|
|
56
|
+
/** `HTTP <status> [SERVICE_CODE]: message` — the shape a Wix service uses when
|
|
57
|
+
* it refuses with a named reason. */
|
|
58
|
+
const CODED = /HTTP (\d{3}) \[([A-Z0-9_]+)\]/;
|
|
59
|
+
/**
|
|
60
|
+
* The codes that all mean one thing to an owner: the session cannot address this
|
|
61
|
+
* business. Found on a real session whose account did not own the business the app
|
|
62
|
+
* had persisted — Home rendered
|
|
63
|
+
* `HTTP 428 [MISSING_METASITE_ID]: Couldn't extract metasiteId from the request
|
|
64
|
+
* context` where "6 orders" belongs.
|
|
65
|
+
*/
|
|
66
|
+
const SITE_CONTEXT_CODES = ["MISSING_METASITE_ID", "MISSING_REQUEST_SITE_CONTEXT", "MISSING_SITE_CONTEXT"];
|
|
56
67
|
/** Longest raw upstream text worth showing. Beyond this it stops being a
|
|
57
68
|
* message and starts being a payload dump. */
|
|
58
69
|
const MAX_RAW = 200;
|
|
@@ -69,6 +80,29 @@ const MAX_RAW = 200;
|
|
|
69
80
|
*/
|
|
70
81
|
function humanWireError(msg: string): string {
|
|
71
82
|
const status = STATUS.exec(msg)?.[1];
|
|
83
|
+
// A JSON ENVELOPE or a NAMED REASON CODE is the machine's word for it, and the
|
|
84
|
+
// owner gets neither. Both reductions used to live in `ownerDisplayError` only,
|
|
85
|
+
// on the belief that this function's output was parsed downstream — see the note
|
|
86
|
+
// on `ownerLoadError`, which records why that was wrong and how it was checked.
|
|
87
|
+
if (JSON_BODY.test(msg) && status) {
|
|
88
|
+
return copyParam(
|
|
89
|
+
"ownerCommon.upstreamStatus",
|
|
90
|
+
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const coded = CODED.exec(msg);
|
|
94
|
+
if (coded) {
|
|
95
|
+
if (SITE_CONTEXT_CODES.includes(coded[2])) {
|
|
96
|
+
return copyParam(
|
|
97
|
+
"ownerCommon.noSiteContext",
|
|
98
|
+
"This business isn’t available to your Wix account right now. Switch business, or sign in again as its owner.",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return copyParam(
|
|
102
|
+
"ownerCommon.upstreamStatus",
|
|
103
|
+
`Wix returned an error (HTTP ${coded[1]}). Try again in a moment.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
72
106
|
if (HTML_BODY.test(msg)) {
|
|
73
107
|
if (status === "403") {
|
|
74
108
|
return copyParam(
|
|
@@ -101,36 +135,46 @@ export function ownerPreviewUnavailable(): string {
|
|
|
101
135
|
/**
|
|
102
136
|
* `ownerLoadError` for a screen that does nothing but RENDER the string.
|
|
103
137
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* native write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
138
|
+
* One difference left, and it is about WHERE the app is rather than what the
|
|
139
|
+
* error says: this names the web preview when there IS one. `isBridgeUnavailable`
|
|
140
|
+
* reads "not live" as "preview", and native injects no mode at all, so the
|
|
141
|
+
* default would answer a device-side `HTTP 503` with "open this app on a device"
|
|
142
|
+
* — on the device. That predicate is deliberately left alone: native
|
|
143
|
+
* write-behind (`shouldQueueOwnerWrite`) depends on exactly it.
|
|
111
144
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* `CATALOG_V3_CALLING_CATALOG_V1_API` in it to choose its v1 fallback, and
|
|
115
|
-
* `owner-load-error.test.ts` pins that verbatim. A display-only caller has
|
|
116
|
-
* no such reader, and the bridge's typed refusals are JSON and short enough
|
|
117
|
-
* (68 chars) to slip under MAX_RAW, so nothing else was catching them.
|
|
118
|
-
*
|
|
119
|
-
* So: use this ONLY where the value is rendered and never matched on.
|
|
145
|
+
* The reductions this used to add are now in `humanWireError`, so every owner
|
|
146
|
+
* screen gets them rather than the two that happened to call this.
|
|
120
147
|
*/
|
|
121
148
|
export function ownerDisplayError(e: unknown): string {
|
|
122
149
|
if (isOwnerPreviewHost() && isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|
|
123
|
-
|
|
124
|
-
const status = STATUS.exec(msg)?.[1];
|
|
125
|
-
if (JSON_BODY.test(msg) && status) {
|
|
126
|
-
return copyParam(
|
|
127
|
-
"ownerCommon.upstreamStatus",
|
|
128
|
-
`Wix returned an error (HTTP ${status}). Try again in a moment.`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
return humanWireError(msg);
|
|
150
|
+
return humanWireError(String((e as Error)?.message ?? e));
|
|
132
151
|
}
|
|
133
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The default. Reduces the same shapes as `ownerDisplayError`.
|
|
155
|
+
*
|
|
156
|
+
* It used to reduce LESS, on the stated grounds that its output is parsed
|
|
157
|
+
* downstream — "the products worker matches `CATALOG_V3_CALLING_CATALOG_V1_API`
|
|
158
|
+
* in it to choose its v1 fallback". **That was not true**, and it cost 17 owner
|
|
159
|
+
* screens their error copy: they printed `HTTP 428 [MISSING_METASITE_ID]: …`
|
|
160
|
+
* verbatim for a contract that does not exist.
|
|
161
|
+
*
|
|
162
|
+
* Checked before changing it, and worth recording so nobody restores the belief:
|
|
163
|
+
*
|
|
164
|
+
* • the catalog v1/v3 decision is made INSIDE the Wix stores SDK, on the RAW
|
|
165
|
+
* thrown error — its `catalogVersionFromMismatch` reads the error's own
|
|
166
|
+
* `message`, and only that module calls it. It never sees this function's
|
|
167
|
+
* output.
|
|
168
|
+
* • `CATALOG_V3_CALLING_CATALOG_V1_API` appears nowhere else in the codebase
|
|
169
|
+
* outside comments, tests and that one SDK module.
|
|
170
|
+
* • the collection framework's `clearOnError` is handed the RAW error
|
|
171
|
+
* (`error => /401|403|forbidden/i.test(String(error))`), separately from
|
|
172
|
+
* `errorMessage: ownerLoadError` — so the one place that does match on a
|
|
173
|
+
* failure is unaffected by what this returns.
|
|
174
|
+
*
|
|
175
|
+
* So: the raw error remains available to logic everywhere it was; this function's
|
|
176
|
+
* result is display copy, and now reads like it.
|
|
177
|
+
*/
|
|
134
178
|
export function ownerLoadError(e: unknown): string {
|
|
135
179
|
const msg = String((e as Error)?.message ?? e);
|
|
136
180
|
if (isBridgeUnavailable(e)) return ownerPreviewUnavailable();
|