@wix/himalaya-cli 0.1396.0 → 0.1398.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/serve-runtime/src/wix-bridge.d.ts +30 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/icon-catalog.generated.d.ts +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/validation.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/copy.generated.d.ts +109 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/feedback.d.ts +15 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/auth/src/index.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/screens/src/index.d.ts +44 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/auth.mjs +304 -18
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core/validation.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +31 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +377 -20
- package/dist/cli.mjs +1260 -540
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +1 -1
- package/guides/component-reference.md +2 -0
- package/guides/headless-loop.md +1 -1
- package/guides/himi-json-output.md +1 -0
- package/guides/importable-sdks.md +2 -1
- package/guides/one-app-to-himi-app.md +72 -2
- package/guides/one-app-viewer.md +8 -1
- package/guides/sdk-reference.json +92 -1
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +41 -1
- package/templates/beauty-salon/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/branded-lite/dev/index.ts +41 -1
- package/templates/branded-lite/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/community-club/dev/index.ts +41 -1
- package/templates/community-club/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/events-meetups/dev/index.ts +41 -1
- package/templates/events-meetups/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/gym-fitness/dev/index.ts +41 -1
- package/templates/gym-fitness/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/nonprofit-cause/dev/index.ts +41 -1
- package/templates/nonprofit-cause/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/podcast-creator/dev/index.ts +41 -1
- package/templates/podcast-creator/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/portfolio-creative/dev/index.ts +41 -1
- package/templates/portfolio-creative/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/restaurant/dev/index.ts +41 -1
- package/templates/restaurant/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/retail-store/dev/index.ts +41 -1
- package/templates/retail-store/tier5-src/himi-store-account/index.ts +90 -76
- package/templates/yoga-studio/dev/index.ts +41 -1
- package/templates/yoga-studio/tier5-src/himi-store-account/index.ts +90 -76
|
@@ -2124,6 +2124,16 @@ const SCREENS = runtimeSetting({
|
|
|
2124
2124
|
"props": {
|
|
2125
2125
|
"placeholder": "Email",
|
|
2126
2126
|
"keyboard": "email",
|
|
2127
|
+
"validation": {
|
|
2128
|
+
"required": true,
|
|
2129
|
+
"type": "email",
|
|
2130
|
+
"mode": "on_blur"
|
|
2131
|
+
},
|
|
2132
|
+
"errorPath": "$service:himiStoreAccount.emailError",
|
|
2133
|
+
"submitLabel": "go",
|
|
2134
|
+
"onSubmit": {
|
|
2135
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
2136
|
+
},
|
|
2127
2137
|
"autoCapitalization": "none",
|
|
2128
2138
|
"focusPath": "$service:himiStoreAccount.emailFocus",
|
|
2129
2139
|
"onChange": {
|
|
@@ -2139,8 +2149,19 @@ const SCREENS = runtimeSetting({
|
|
|
2139
2149
|
"type": "TextField",
|
|
2140
2150
|
"props": {
|
|
2141
2151
|
"placeholder": "Password",
|
|
2142
|
-
"valuePath": "$service:himiStoreAccount.password",
|
|
2143
2152
|
"secure": true,
|
|
2153
|
+
"visibilityToggle": true,
|
|
2154
|
+
"validation": {
|
|
2155
|
+
"required": true,
|
|
2156
|
+
"mode": "on_blur",
|
|
2157
|
+
"message": "Enter your password."
|
|
2158
|
+
},
|
|
2159
|
+
"errorPath": "$service:himiStoreAccount.passwordError",
|
|
2160
|
+
"focusPath": "$service:himiStoreAccount.passwordFocus",
|
|
2161
|
+
"submitLabel": "go",
|
|
2162
|
+
"onSubmit": {
|
|
2163
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
2164
|
+
},
|
|
2144
2165
|
"autoCapitalization": "none",
|
|
2145
2166
|
"onChange": {
|
|
2146
2167
|
"actionId": "tier5.himiStoreAccount.setPassword"
|
|
@@ -2151,6 +2172,18 @@ const SCREENS = runtimeSetting({
|
|
|
2151
2172
|
"hiddenPath": "$service:himiStoreAccount.isRecovering"
|
|
2152
2173
|
}
|
|
2153
2174
|
},
|
|
2175
|
+
{
|
|
2176
|
+
"id": "",
|
|
2177
|
+
"body": {
|
|
2178
|
+
"package": "himalaya",
|
|
2179
|
+
"type": "Text",
|
|
2180
|
+
"props": {
|
|
2181
|
+
"text": "$service:himiStoreAccount.busyMessage",
|
|
2182
|
+
"style": "footnote",
|
|
2183
|
+
"collapseWhenEmpty": true
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
},
|
|
2154
2187
|
{
|
|
2155
2188
|
"id": "himi_account.message",
|
|
2156
2189
|
"body": {
|
|
@@ -2173,6 +2206,7 @@ const SCREENS = runtimeSetting({
|
|
|
2173
2206
|
"title": "Sign in",
|
|
2174
2207
|
"style": "primary",
|
|
2175
2208
|
"fullWidth": true,
|
|
2209
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2176
2210
|
"action": {
|
|
2177
2211
|
"actionId": "tier5.himiStoreAccount.signIn"
|
|
2178
2212
|
}
|
|
@@ -2191,6 +2225,7 @@ const SCREENS = runtimeSetting({
|
|
|
2191
2225
|
"title": "Create account",
|
|
2192
2226
|
"style": "primary",
|
|
2193
2227
|
"fullWidth": true,
|
|
2228
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2194
2229
|
"action": {
|
|
2195
2230
|
"actionId": "tier5.himiStoreAccount.register"
|
|
2196
2231
|
}
|
|
@@ -2209,6 +2244,7 @@ const SCREENS = runtimeSetting({
|
|
|
2209
2244
|
"title": "Send reset link",
|
|
2210
2245
|
"style": "primary",
|
|
2211
2246
|
"fullWidth": true,
|
|
2247
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2212
2248
|
"action": {
|
|
2213
2249
|
"actionId": "tier5.himiStoreAccount.resetPassword"
|
|
2214
2250
|
}
|
|
@@ -2227,6 +2263,7 @@ const SCREENS = runtimeSetting({
|
|
|
2227
2263
|
"title": "Forgot password?",
|
|
2228
2264
|
"style": "secondary",
|
|
2229
2265
|
"fullWidth": true,
|
|
2266
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2230
2267
|
"action": {
|
|
2231
2268
|
"actionId": "tier5.himiStoreAccount.showRecovery"
|
|
2232
2269
|
}
|
|
@@ -2245,6 +2282,7 @@ const SCREENS = runtimeSetting({
|
|
|
2245
2282
|
"title": "Register",
|
|
2246
2283
|
"style": "secondary",
|
|
2247
2284
|
"fullWidth": true,
|
|
2285
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2248
2286
|
"action": {
|
|
2249
2287
|
"actionId": "tier5.himiStoreAccount.showRegister"
|
|
2250
2288
|
}
|
|
@@ -2263,6 +2301,7 @@ const SCREENS = runtimeSetting({
|
|
|
2263
2301
|
"title": "Sign in instead",
|
|
2264
2302
|
"style": "secondary",
|
|
2265
2303
|
"fullWidth": true,
|
|
2304
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2266
2305
|
"action": {
|
|
2267
2306
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
2268
2307
|
}
|
|
@@ -2281,6 +2320,7 @@ const SCREENS = runtimeSetting({
|
|
|
2281
2320
|
"title": "Back to sign in",
|
|
2282
2321
|
"style": "secondary",
|
|
2283
2322
|
"fullWidth": true,
|
|
2323
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
2284
2324
|
"action": {
|
|
2285
2325
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
2286
2326
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { authFailure, authMessage, identityErrors, type AuthOperation } from "@himalaya/auth";
|
|
1
2
|
// Tier-5 bundle: himi-store — visitor/member account state.
|
|
2
3
|
//
|
|
3
4
|
// SINGLE-SITE BY DESIGN. A Branded Lite build talks to exactly one Wix site, and the
|
|
@@ -75,23 +76,50 @@ function resumeAfterAuth(next: S): S {
|
|
|
75
76
|
// Actions are not serialized: two quick Sign in taps both run against the pre-tap
|
|
76
77
|
// state, so without this both would submit credentials and both would resume.
|
|
77
78
|
let authInFlight = false;
|
|
79
|
+
// Never projected or persisted. The renderer retains its own masked draft for retry.
|
|
80
|
+
let passwordDraft = "";
|
|
81
|
+
let editRevision = 0;
|
|
82
|
+
// Descriptor configuration belongs to the worker session. Keep it even when a
|
|
83
|
+
// delayed profile probe is discarded because the user edited the form.
|
|
84
|
+
let memberAccountLinksRequested = false;
|
|
85
|
+
const translated = (key: string) => copyParam(key, authMessage(key));
|
|
78
86
|
|
|
79
|
-
|
|
87
|
+
function validateAuth(s: S, operation: AuthOperation): S {
|
|
88
|
+
const errors = identityErrors({ email: s.email, password: passwordDraft }, operation);
|
|
89
|
+
return derive({ ...s, emailError: errors.email ? translated(errors.email) : "",
|
|
90
|
+
passwordError: errors.password ? translated(errors.password) : "",
|
|
91
|
+
emailFocus: errors.email ? bumpToken(s.emailFocus) : s.emailFocus,
|
|
92
|
+
passwordFocus: !errors.email && errors.password ? bumpToken(s.passwordFocus) : s.passwordFocus,
|
|
93
|
+
message: "" });
|
|
94
|
+
}
|
|
95
|
+
function rejectResult(raw: unknown, operation: AuthOperation) {
|
|
96
|
+
const value = raw as { status?: string; error?: unknown; payload?: { error?: unknown } } | null;
|
|
97
|
+
if (value?.status === "error" || value?.error || value?.payload?.error) throw authFailure(raw, operation, translated);
|
|
98
|
+
}
|
|
99
|
+
async function authenticate(s: S, operation: "signIn" | "register"): Promise<S | undefined> {
|
|
80
100
|
if (authInFlight) return undefined;
|
|
101
|
+
const checked = validateAuth(s, operation);
|
|
102
|
+
if (checked.emailError || checked.passwordError) return checked;
|
|
81
103
|
authInFlight = true;
|
|
104
|
+
const revision = editRevision;
|
|
105
|
+
const password = passwordDraft;
|
|
82
106
|
try {
|
|
83
|
-
await
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return derive({ ...
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
await svc.beginAuth(); // publish busy before waiting for the network
|
|
108
|
+
const raw = await dispatch(operation === "signIn" ? "himi.wix.signInDirect" : "himi.wix.registerDirect", {
|
|
109
|
+
email: s.email.trim(), password,
|
|
110
|
+
...(operation === "register" ? { firstName: s.firstName, lastName: s.lastName } : {}),
|
|
111
|
+
});
|
|
112
|
+
rejectResult(raw, operation);
|
|
113
|
+
if (revision !== editRevision) return derive({ ...svc.getState(), authBusy: false });
|
|
114
|
+
const next = await probe(svc.getState());
|
|
115
|
+
if (revision !== editRevision) return derive({ ...svc.getState(), authBusy: false });
|
|
116
|
+
if (!next.isMember) throw { code: "unknown" };
|
|
117
|
+
passwordDraft = "";
|
|
118
|
+
return resumeAfterAuth(completedAuth(next));
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return derive({ ...svc.getState(), authBusy: false,
|
|
121
|
+
message: revision === editRevision ? authFailure(error, operation, translated).reason : "" });
|
|
122
|
+
} finally { authInFlight = false; }
|
|
95
123
|
}
|
|
96
124
|
|
|
97
125
|
// Next value of a focus token: monotonic, and never empty once requested. A counter
|
|
@@ -180,10 +208,14 @@ interface S extends IapRestoreFields {
|
|
|
180
208
|
noReturnPath: boolean;
|
|
181
209
|
returnCta: string;
|
|
182
210
|
email: string;
|
|
183
|
-
/**
|
|
184
|
-
*
|
|
185
|
-
* do recovery and sign-out. Sign-in <-> register keeps it: the field stays up. */
|
|
211
|
+
/** Legacy snapshot slot, always empty. The active form keeps its password in
|
|
212
|
+
* transient memory for retry; hydration never restores a persisted secret. */
|
|
186
213
|
password: string;
|
|
214
|
+
authBusy: boolean;
|
|
215
|
+
busyMessage?: string;
|
|
216
|
+
emailError: string;
|
|
217
|
+
passwordError: string;
|
|
218
|
+
passwordFocus: string;
|
|
187
219
|
firstName: string;
|
|
188
220
|
lastName: string;
|
|
189
221
|
// Focus TOKENS (`TextFieldProps.focus_path`), not flags: the bound field focuses
|
|
@@ -247,6 +279,8 @@ function derive(s: S): S {
|
|
|
247
279
|
const hasReturnPath = !!s.isMember && !!s.returnScreenId;
|
|
248
280
|
return {
|
|
249
281
|
...s,
|
|
282
|
+
password: "",
|
|
283
|
+
busyMessage: s.authBusy ? translated("auth.feedback.busy") : "",
|
|
250
284
|
isLoading: s.status === "loading",
|
|
251
285
|
notLoading: s.status !== "loading",
|
|
252
286
|
notMember: !s.isMember,
|
|
@@ -309,9 +343,10 @@ async function orderRows(memberEmail: string): Promise<AccountActivityRow[]> {
|
|
|
309
343
|
}
|
|
310
344
|
|
|
311
345
|
async function probe(s: S, arg?: unknown): Promise<S> {
|
|
346
|
+
memberAccountLinksRequested ||= s.memberAccountLinks || strField(arg, "memberAccountLinks") === "1";
|
|
312
347
|
const intent = authIntentFromArg(arg, s);
|
|
313
348
|
const profile = await loadMemberProfile(copyParam("storeAccount.guestDetail", "Sign in to keep your cart and orders connected."));
|
|
314
|
-
const memberAccountLinks =
|
|
349
|
+
const memberAccountLinks = memberAccountLinksRequested;
|
|
315
350
|
const restorePurchases = s.restorePurchases || strField(arg, "restorePurchases") === "1";
|
|
316
351
|
if (restorePurchases) enterCommerce();
|
|
317
352
|
const routes = memberAccountLinks ? await memberAccountRoutes() : { addresses: false, wallet: false };
|
|
@@ -353,21 +388,11 @@ async function probe(s: S, arg?: unknown): Promise<S> {
|
|
|
353
388
|
});
|
|
354
389
|
}
|
|
355
390
|
|
|
356
|
-
function
|
|
391
|
+
function completedAuth(s: S): S {
|
|
357
392
|
return derive({
|
|
358
393
|
...s,
|
|
359
|
-
status: "ready",
|
|
360
|
-
isMember: true,
|
|
361
|
-
identityLine: copyParam("storeAccount.signedIn", "Signed in"),
|
|
362
|
-
detailLine: email,
|
|
363
|
-
memberName: email,
|
|
364
|
-
memberEmail: email,
|
|
365
|
-
memberImage: "",
|
|
366
|
-
memberInitials: "M",
|
|
367
|
-
hasMemberImage: false,
|
|
368
|
-
noMemberImage: true,
|
|
369
|
-
email,
|
|
370
394
|
password: "",
|
|
395
|
+
authBusy: false, emailError: "", passwordError: "", passwordFocus: "",
|
|
371
396
|
firstName: "",
|
|
372
397
|
lastName: "",
|
|
373
398
|
isRegistering: false,
|
|
@@ -377,6 +402,8 @@ function optimisticMember(s: S, email: string): S {
|
|
|
377
402
|
}
|
|
378
403
|
|
|
379
404
|
const svc = defineService<S, {
|
|
405
|
+
beginAuth: (s: S) => S;
|
|
406
|
+
submit: (s: S) => Promise<S | undefined>;
|
|
380
407
|
load: (s: S, arg?: unknown) => Promise<S>;
|
|
381
408
|
refresh: (s: S, arg?: unknown) => Promise<S>;
|
|
382
409
|
setEmail: (s: S, arg?: unknown) => S;
|
|
@@ -395,7 +422,7 @@ const svc = defineService<S, {
|
|
|
395
422
|
restorePublish: (s: S) => S;
|
|
396
423
|
iapRestore: (s: S) => Promise<undefined>;
|
|
397
424
|
}>("himiStoreAccount", {
|
|
398
|
-
notHydrated: [...IAP_RESTORE_KEYS],
|
|
425
|
+
notHydrated: ["password", "authBusy", "emailError", "passwordError", "passwordFocus", ...IAP_RESTORE_KEYS],
|
|
399
426
|
state: derive({
|
|
400
427
|
status: "loading",
|
|
401
428
|
isMember: false,
|
|
@@ -420,6 +447,7 @@ const svc = defineService<S, {
|
|
|
420
447
|
returnCta: "Continue",
|
|
421
448
|
email: "",
|
|
422
449
|
password: "",
|
|
450
|
+
authBusy: false, emailError: "", passwordError: "", passwordFocus: "",
|
|
423
451
|
firstName: "",
|
|
424
452
|
lastName: "",
|
|
425
453
|
lastNameFocus: "",
|
|
@@ -445,12 +473,14 @@ const svc = defineService<S, {
|
|
|
445
473
|
...NO_IAP_RESTORE,
|
|
446
474
|
}),
|
|
447
475
|
actions: {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
476
|
+
submit: (s): Promise<S | undefined> => s.isRecovering ? svc.resetPassword() : authenticate(s, s.isRegistering ? "register" : "signIn"),
|
|
477
|
+
beginAuth: (s) => derive({ ...s, authBusy: true, message: "", emailError: "", passwordError: "" }),
|
|
478
|
+
load: async (s, arg): Promise<S> => { stashCopy(arg); const revision = editRevision; const next = await probe(s, arg); return authInFlight || revision !== editRevision ? svc.getState() : next; },
|
|
479
|
+
refresh: async (s, arg): Promise<S> => { stashCopy(arg); const revision = editRevision; const next = await probe(s, arg); return authInFlight || revision !== editRevision ? svc.getState() : next; },
|
|
480
|
+
setEmail: (s, arg) => { editRevision++; const next = { ...s, email: strOf(arg).trim(), message: "" }; return derive({ ...next, emailError: s.emailError ? (identityErrors({ email: next.email }, "reset").email ? translated(identityErrors({ email: next.email }, "reset").email!) : "") : "" }); },
|
|
481
|
+
setPassword: (s, arg) => { editRevision++; passwordDraft = strOf(arg); return derive({ ...s, message: "", passwordError: s.passwordError && !passwordDraft ? translated("auth.validation.passwordRequired") : "" }); },
|
|
482
|
+
setFirstName: (s, arg) => { editRevision++; return derive({ ...s, firstName: strOf(arg), message: "" }); },
|
|
483
|
+
setLastName: (s, arg) => { editRevision++; return derive({ ...s, lastName: strOf(arg), message: "" }); },
|
|
454
484
|
// The register form's Next keys. Only first/last name carry one: they share a
|
|
455
485
|
// single visibility gate (notRegistering) so their target is always on screen.
|
|
456
486
|
// Email deliberately does NOT chain to password — see the comment on the
|
|
@@ -463,48 +493,32 @@ const svc = defineService<S, {
|
|
|
463
493
|
// register and coming back would open focused on Last name, skipping First name.
|
|
464
494
|
// Only the tokens whose fields actually unmount here are cleared: see
|
|
465
495
|
// NO_FOCUS_MODE_SWITCH for why Email's is deliberately NOT among them.
|
|
466
|
-
showRegister: (s) => derive({ ...s, isRegistering: true, isRecovering: false, message: "", ...NO_FOCUS_MODE_SWITCH }),
|
|
467
|
-
showSignIn: (s) => derive({ ...s, isRegistering: false, isRecovering: false, message: "", ...NO_FOCUS_MODE_SWITCH }),
|
|
468
|
-
showRecovery: (s) => derive({ ...s, isRegistering: false, isRecovering: true, password: "", message: "", ...NO_FOCUS_MODE_SWITCH }),
|
|
469
|
-
resetPassword: async (s) => {
|
|
470
|
-
|
|
471
|
-
|
|
496
|
+
showRegister: (s) => { if (authInFlight) return s; editRevision++; return derive({ ...s, isRegistering: true, isRecovering: false, message: "", emailError: "", passwordError: "", ...NO_FOCUS_MODE_SWITCH }) },
|
|
497
|
+
showSignIn: (s) => { if (authInFlight) return s; editRevision++; return derive({ ...s, isRegistering: false, isRecovering: false, message: "", emailError: "", passwordError: "", ...NO_FOCUS_MODE_SWITCH }) },
|
|
498
|
+
showRecovery: (s) => { if (authInFlight) return s; editRevision++; return derive({ ...s, isRegistering: false, isRecovering: true, password: "", message: "", emailError: "", passwordError: "", ...NO_FOCUS_MODE_SWITCH }) },
|
|
499
|
+
resetPassword: async (s): Promise<S> => {
|
|
500
|
+
if (authInFlight) return s;
|
|
501
|
+
const checked = validateAuth(s, "reset");
|
|
502
|
+
if (checked.emailError) return checked;
|
|
503
|
+
authInFlight = true;
|
|
504
|
+
const revision = editRevision;
|
|
472
505
|
try {
|
|
473
|
-
await
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
message: copyParam("storeAccount.resetSent", "If that email is registered, a reset link is on its way.")
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
},
|
|
484
|
-
signIn: async (s) => {
|
|
485
|
-
if (!s.email || !s.password) return derive({ ...s, message: copyParam("storeAccount.validationEmailPassword", "Enter your email and password.") });
|
|
486
|
-
return authenticate(
|
|
487
|
-
s,
|
|
488
|
-
() => dispatch("himi.wix.signInDirect", { email: s.email, password: s.password }),
|
|
489
|
-
copyParam("storeAccount.signInCheckDetails", "Sign in failed. Check your details."),
|
|
490
|
-
copyParam("storeAccount.signInFailed", "Sign in failed. Try again."),
|
|
491
|
-
);
|
|
492
|
-
},
|
|
493
|
-
register: async (s) => {
|
|
494
|
-
if (!s.email || !s.password) return derive({ ...s, message: copyParam("storeAccount.validationEmailPassword", "Enter your email and password.") });
|
|
495
|
-
return authenticate(
|
|
496
|
-
s,
|
|
497
|
-
() => dispatch("himi.wix.registerDirect", {
|
|
498
|
-
email: s.email,
|
|
499
|
-
password: s.password,
|
|
500
|
-
firstName: s.firstName,
|
|
501
|
-
lastName: s.lastName,
|
|
502
|
-
}),
|
|
503
|
-
copyParam("storeAccount.registerTrySignIn", "Account creation failed. Try signing in."),
|
|
504
|
-
copyParam("storeAccount.registerFailed", "Account creation failed. Try another email."),
|
|
505
|
-
);
|
|
506
|
+
await svc.beginAuth();
|
|
507
|
+
const raw = await dispatch("himi.wix.resetPassword", { email: s.email.trim() });
|
|
508
|
+
rejectResult(raw, "reset");
|
|
509
|
+
if (revision !== editRevision) return derive({ ...svc.getState(), authBusy: false });
|
|
510
|
+
return derive({ ...svc.getState(), authBusy: false, isRecovering: false,
|
|
511
|
+
message: copyParam("storeAccount.resetSent", "If that email is registered, a reset link is on its way.") });
|
|
512
|
+
} catch (error) {
|
|
513
|
+
return derive({ ...svc.getState(), authBusy: false,
|
|
514
|
+
message: revision === editRevision ? authFailure(error, "reset", translated).reason : "" });
|
|
515
|
+
} finally { authInFlight = false; }
|
|
506
516
|
},
|
|
507
|
-
|
|
517
|
+
signIn: (s) => authenticate(s, "signIn"),
|
|
518
|
+
register: (s) => authenticate(s, "register"),
|
|
519
|
+
signOut: async (s): Promise<S> => {
|
|
520
|
+
if (authInFlight) return svc.getState();
|
|
521
|
+
passwordDraft = ""; editRevision++;
|
|
508
522
|
routeInputConsumed = true;
|
|
509
523
|
try { await dispatch("himi.wix.signOut"); } catch { /* ignore */ }
|
|
510
524
|
// Do NOT re-probe via getMyData after logout — visitor-scoped my-data can
|
|
@@ -1602,6 +1602,16 @@ const SCREENS = runtimeSetting({
|
|
|
1602
1602
|
"props": {
|
|
1603
1603
|
"placeholder": "Email",
|
|
1604
1604
|
"keyboard": "email",
|
|
1605
|
+
"validation": {
|
|
1606
|
+
"required": true,
|
|
1607
|
+
"type": "email",
|
|
1608
|
+
"mode": "on_blur"
|
|
1609
|
+
},
|
|
1610
|
+
"errorPath": "$service:himiStoreAccount.emailError",
|
|
1611
|
+
"submitLabel": "go",
|
|
1612
|
+
"onSubmit": {
|
|
1613
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
1614
|
+
},
|
|
1605
1615
|
"autoCapitalization": "none",
|
|
1606
1616
|
"focusPath": "$service:himiStoreAccount.emailFocus",
|
|
1607
1617
|
"onChange": {
|
|
@@ -1617,8 +1627,19 @@ const SCREENS = runtimeSetting({
|
|
|
1617
1627
|
"type": "TextField",
|
|
1618
1628
|
"props": {
|
|
1619
1629
|
"placeholder": "Password",
|
|
1620
|
-
"valuePath": "$service:himiStoreAccount.password",
|
|
1621
1630
|
"secure": true,
|
|
1631
|
+
"visibilityToggle": true,
|
|
1632
|
+
"validation": {
|
|
1633
|
+
"required": true,
|
|
1634
|
+
"mode": "on_blur",
|
|
1635
|
+
"message": "Enter your password."
|
|
1636
|
+
},
|
|
1637
|
+
"errorPath": "$service:himiStoreAccount.passwordError",
|
|
1638
|
+
"focusPath": "$service:himiStoreAccount.passwordFocus",
|
|
1639
|
+
"submitLabel": "go",
|
|
1640
|
+
"onSubmit": {
|
|
1641
|
+
"actionId": "tier5.himiStoreAccount.submit"
|
|
1642
|
+
},
|
|
1622
1643
|
"autoCapitalization": "none",
|
|
1623
1644
|
"onChange": {
|
|
1624
1645
|
"actionId": "tier5.himiStoreAccount.setPassword"
|
|
@@ -1629,6 +1650,18 @@ const SCREENS = runtimeSetting({
|
|
|
1629
1650
|
"hiddenPath": "$service:himiStoreAccount.isRecovering"
|
|
1630
1651
|
}
|
|
1631
1652
|
},
|
|
1653
|
+
{
|
|
1654
|
+
"id": "",
|
|
1655
|
+
"body": {
|
|
1656
|
+
"package": "himalaya",
|
|
1657
|
+
"type": "Text",
|
|
1658
|
+
"props": {
|
|
1659
|
+
"text": "$service:himiStoreAccount.busyMessage",
|
|
1660
|
+
"style": "footnote",
|
|
1661
|
+
"collapseWhenEmpty": true
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
},
|
|
1632
1665
|
{
|
|
1633
1666
|
"id": "himi_account.message",
|
|
1634
1667
|
"body": {
|
|
@@ -1651,6 +1684,7 @@ const SCREENS = runtimeSetting({
|
|
|
1651
1684
|
"title": "Sign in",
|
|
1652
1685
|
"style": "primary",
|
|
1653
1686
|
"fullWidth": true,
|
|
1687
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1654
1688
|
"action": {
|
|
1655
1689
|
"actionId": "tier5.himiStoreAccount.signIn"
|
|
1656
1690
|
}
|
|
@@ -1669,6 +1703,7 @@ const SCREENS = runtimeSetting({
|
|
|
1669
1703
|
"title": "Create account",
|
|
1670
1704
|
"style": "primary",
|
|
1671
1705
|
"fullWidth": true,
|
|
1706
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1672
1707
|
"action": {
|
|
1673
1708
|
"actionId": "tier5.himiStoreAccount.register"
|
|
1674
1709
|
}
|
|
@@ -1687,6 +1722,7 @@ const SCREENS = runtimeSetting({
|
|
|
1687
1722
|
"title": "Send reset link",
|
|
1688
1723
|
"style": "primary",
|
|
1689
1724
|
"fullWidth": true,
|
|
1725
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1690
1726
|
"action": {
|
|
1691
1727
|
"actionId": "tier5.himiStoreAccount.resetPassword"
|
|
1692
1728
|
}
|
|
@@ -1705,6 +1741,7 @@ const SCREENS = runtimeSetting({
|
|
|
1705
1741
|
"title": "Forgot password?",
|
|
1706
1742
|
"style": "secondary",
|
|
1707
1743
|
"fullWidth": true,
|
|
1744
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1708
1745
|
"action": {
|
|
1709
1746
|
"actionId": "tier5.himiStoreAccount.showRecovery"
|
|
1710
1747
|
}
|
|
@@ -1723,6 +1760,7 @@ const SCREENS = runtimeSetting({
|
|
|
1723
1760
|
"title": "Register",
|
|
1724
1761
|
"style": "secondary",
|
|
1725
1762
|
"fullWidth": true,
|
|
1763
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1726
1764
|
"action": {
|
|
1727
1765
|
"actionId": "tier5.himiStoreAccount.showRegister"
|
|
1728
1766
|
}
|
|
@@ -1741,6 +1779,7 @@ const SCREENS = runtimeSetting({
|
|
|
1741
1779
|
"title": "Sign in instead",
|
|
1742
1780
|
"style": "secondary",
|
|
1743
1781
|
"fullWidth": true,
|
|
1782
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1744
1783
|
"action": {
|
|
1745
1784
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
1746
1785
|
}
|
|
@@ -1759,6 +1798,7 @@ const SCREENS = runtimeSetting({
|
|
|
1759
1798
|
"title": "Back to sign in",
|
|
1760
1799
|
"style": "secondary",
|
|
1761
1800
|
"fullWidth": true,
|
|
1801
|
+
"disabledPath": "$service:himiStoreAccount.authBusy",
|
|
1762
1802
|
"action": {
|
|
1763
1803
|
"actionId": "tier5.himiStoreAccount.showSignIn"
|
|
1764
1804
|
}
|