@wix/himalaya-cli 0.1570.0 → 0.1572.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.
Files changed (142) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +8 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/index.d.ts +7 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +6 -3
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-feed-viewer/src/index.d.ts +6 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/auth.mjs +17 -7
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core/validation.mjs +17 -7
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +17 -7
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +17 -7
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/state.mjs +17 -7
  10. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth.mjs +7 -1
  11. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-blog.mjs +1 -0
  12. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members-feed-viewer.mjs +18 -0
  13. package/dist/cli.mjs +2014 -1252
  14. package/dist/preview-assets.generated.bin +0 -0
  15. package/guides/base44-app-to-himi-app.md +1 -1
  16. package/guides/capabilities.md +7 -0
  17. package/guides/himi-json-output.md +11 -0
  18. package/guides/index.json +7 -0
  19. package/guides/map-one-app-coverage.js +117 -0
  20. package/guides/one-app-to-himi-app.md +209 -11
  21. package/guides/recipe-one-app-coverage-mapping.md +74 -0
  22. package/guides/sdk-reference.json +8 -2
  23. package/guides/splash-screens.md +10 -1
  24. package/guides/trim-a-template.md +5 -0
  25. package/guides/wix-business-context.md +11 -2
  26. package/package.json +2 -2
  27. package/templates/beauty-salon/config.ts +1 -1
  28. package/templates/beauty-salon/dev/index.ts +31 -1
  29. package/templates/beauty-salon/tier5-src/_shared/member-read.ts +52 -0
  30. package/templates/beauty-salon/tier5-src/_shared/program-description.ts +11 -0
  31. package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +35 -12
  32. package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +3 -3
  33. package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +6 -9
  34. package/templates/beauty-salon-owner/config.ts +1 -1
  35. package/templates/beauty-salon-owner/dev/index.ts +2 -3
  36. package/templates/branded-lite/config.ts +1 -1
  37. package/templates/branded-lite/dev/index.ts +163 -2
  38. package/templates/branded-lite/tier5-src/_shared/member-read.ts +52 -0
  39. package/templates/branded-lite/tier5-src/_shared/program-description.ts +11 -0
  40. package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +35 -12
  41. package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +3 -3
  42. package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +16 -14
  43. package/templates/branded-lite/tier5-src/himi-branded-lite-programs/index.ts +31 -18
  44. package/templates/branded-lite/tier5-src/himi-events-my-events/index.ts +76 -42
  45. package/templates/branded-lite/tier5-src/himi-store-product/index.ts +6 -9
  46. package/templates/branded-lite/tier5-src/wix-spaces-chat-thread/index.ts +101 -34
  47. package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +23 -6
  48. package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +26 -11
  49. package/templates/community-club/config.ts +1 -1
  50. package/templates/community-club/dev/index.ts +65 -2
  51. package/templates/community-club/tier5-src/_shared/branded-load-state.ts +106 -0
  52. package/templates/community-club/tier5-src/_shared/member-read.ts +52 -0
  53. package/templates/community-club/tier5-src/_shared/program-description.ts +11 -0
  54. package/templates/community-club/tier5-src/himi-blog-post/index.ts +35 -12
  55. package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +3 -3
  56. package/templates/community-club/tier5-src/himi-events-my-events/index.ts +76 -42
  57. package/templates/community-club-owner/config.ts +1 -1
  58. package/templates/community-club-owner/dev/index.ts +2 -3
  59. package/templates/events-meetups/config.ts +1 -1
  60. package/templates/events-meetups/dev/index.ts +65 -2
  61. package/templates/events-meetups/tier5-src/_shared/branded-load-state.ts +106 -0
  62. package/templates/events-meetups/tier5-src/_shared/member-read.ts +52 -0
  63. package/templates/events-meetups/tier5-src/_shared/program-description.ts +11 -0
  64. package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +35 -12
  65. package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +3 -3
  66. package/templates/events-meetups/tier5-src/himi-events-my-events/index.ts +76 -42
  67. package/templates/events-meetups-owner/config.ts +1 -1
  68. package/templates/events-meetups-owner/dev/index.ts +2 -3
  69. package/templates/gym-fitness/config.ts +1 -1
  70. package/templates/gym-fitness/dev/index.ts +65 -2
  71. package/templates/gym-fitness/tier5-src/_shared/member-read.ts +52 -0
  72. package/templates/gym-fitness/tier5-src/_shared/program-description.ts +11 -0
  73. package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +35 -12
  74. package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +3 -3
  75. package/templates/gym-fitness/tier5-src/himi-events-my-events/index.ts +76 -42
  76. package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +6 -9
  77. package/templates/gym-fitness-owner/config.ts +1 -1
  78. package/templates/gym-fitness-owner/dev/index.ts +2 -3
  79. package/templates/nonprofit-cause/config.ts +1 -1
  80. package/templates/nonprofit-cause/dev/index.ts +65 -2
  81. package/templates/nonprofit-cause/tier5-src/_shared/branded-load-state.ts +106 -0
  82. package/templates/nonprofit-cause/tier5-src/_shared/member-read.ts +52 -0
  83. package/templates/nonprofit-cause/tier5-src/_shared/program-description.ts +11 -0
  84. package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +35 -12
  85. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +3 -3
  86. package/templates/nonprofit-cause/tier5-src/himi-events-my-events/index.ts +76 -42
  87. package/templates/nonprofit-cause-owner/config.ts +1 -1
  88. package/templates/nonprofit-cause-owner/dev/index.ts +2 -3
  89. package/templates/owner-lite/config.ts +1 -1
  90. package/templates/owner-lite/dev/index.ts +2 -3
  91. package/templates/podcast-creator/config.ts +1 -1
  92. package/templates/podcast-creator/dev/index.ts +65 -2
  93. package/templates/podcast-creator/tier5-src/_shared/branded-load-state.ts +106 -0
  94. package/templates/podcast-creator/tier5-src/_shared/member-read.ts +52 -0
  95. package/templates/podcast-creator/tier5-src/_shared/program-description.ts +11 -0
  96. package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +35 -12
  97. package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +3 -3
  98. package/templates/podcast-creator/tier5-src/himi-events-my-events/index.ts +76 -42
  99. package/templates/podcast-creator-owner/config.ts +1 -1
  100. package/templates/podcast-creator-owner/dev/index.ts +2 -3
  101. package/templates/portfolio-creative/config.ts +1 -1
  102. package/templates/portfolio-creative/dev/index.ts +65 -2
  103. package/templates/portfolio-creative/tier5-src/_shared/branded-load-state.ts +106 -0
  104. package/templates/portfolio-creative/tier5-src/_shared/member-read.ts +52 -0
  105. package/templates/portfolio-creative/tier5-src/_shared/program-description.ts +11 -0
  106. package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +35 -12
  107. package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +3 -3
  108. package/templates/portfolio-creative/tier5-src/himi-events-my-events/index.ts +76 -42
  109. package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +6 -9
  110. package/templates/portfolio-creative-owner/config.ts +1 -1
  111. package/templates/portfolio-creative-owner/dev/index.ts +2 -3
  112. package/templates/restaurant/config.ts +1 -1
  113. package/templates/restaurant/dev/index.ts +65 -2
  114. package/templates/restaurant/tier5-src/_shared/branded-load-state.ts +106 -0
  115. package/templates/restaurant/tier5-src/_shared/member-read.ts +52 -0
  116. package/templates/restaurant/tier5-src/_shared/program-description.ts +11 -0
  117. package/templates/restaurant/tier5-src/himi-blog-post/index.ts +35 -12
  118. package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +3 -3
  119. package/templates/restaurant/tier5-src/himi-events-my-events/index.ts +76 -42
  120. package/templates/restaurant-owner/config.ts +1 -1
  121. package/templates/restaurant-owner/dev/index.ts +2 -3
  122. package/templates/retail-store/config.ts +1 -1
  123. package/templates/retail-store/dev/index.ts +31 -1
  124. package/templates/retail-store/tier5-src/_shared/branded-load-state.ts +106 -0
  125. package/templates/retail-store/tier5-src/_shared/member-read.ts +52 -0
  126. package/templates/retail-store/tier5-src/_shared/program-description.ts +11 -0
  127. package/templates/retail-store/tier5-src/himi-blog-post/index.ts +35 -12
  128. package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +3 -3
  129. package/templates/retail-store/tier5-src/himi-store-product/index.ts +6 -9
  130. package/templates/retail-store-owner/config.ts +1 -1
  131. package/templates/retail-store-owner/dev/index.ts +2 -3
  132. package/templates/yoga-studio/config.ts +1 -1
  133. package/templates/yoga-studio/dev/index.ts +93 -2
  134. package/templates/yoga-studio/tier5-src/_shared/member-read.ts +52 -0
  135. package/templates/yoga-studio/tier5-src/_shared/program-description.ts +11 -0
  136. package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +35 -12
  137. package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +3 -3
  138. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +16 -14
  139. package/templates/yoga-studio/tier5-src/himi-branded-lite-programs/index.ts +31 -18
  140. package/templates/yoga-studio/tier5-src/himi-events-my-events/index.ts +76 -42
  141. package/templates/yoga-studio-owner/config.ts +1 -1
  142. package/templates/yoga-studio-owner/dev/index.ts +2 -3
@@ -229,6 +229,14 @@ export interface AppConfig {
229
229
  * omitted. Must satisfy `capabilities ⊆ capabilityEnvelope`.
230
230
  */
231
231
  capabilityEnvelope?: Capability[];
232
+ /**
233
+ * For a shell that `himi dist` builds other apps from: the capabilities such a build STARTS from,
234
+ * instead of this config's own `capabilities`. The build adds what the release declares, so a
235
+ * customer's binary carries this base plus its own opt-ins, not every feature the shell's
236
+ * reference app has. Must list what the shell's boot needs and what a build cannot add
237
+ * (`distAddRefusal`). A local build of the shell still uses `capabilities`.
238
+ */
239
+ capabilityBase?: Capability[];
232
240
  /**
233
241
  * Per-capability permission prompt copy — the sentence the OS shows when the app asks for
234
242
  * camera, location, photos, … (iOS usage strings). Served on app-config, so `himi dist` bakes
@@ -128,5 +128,12 @@ export interface WixNativeAuthConfig {
128
128
  * active site (`HostIdentity`) and show no login of its own. Run standalone, the app keeps this
129
129
  * provider and its login, unchanged. Baked into auth.json by tools/auth-bake. */
130
130
  hostProvided?: boolean;
131
+ /** #4655 — OWNER mode only. On the first launch after this app replaced an older one IN PLACE
132
+ * (same bundle id / applicationId and signing identity), adopt — once — a live Wix session the
133
+ * previous app left in the platform cookie jars (iOS `HTTPCookieStorage.shared`, Android WebView
134
+ * `CookieManager`), so the upgrading owner lands signed in. A dead session falls through to the
135
+ * login gate; a Himi sign-out is never undone by it. Refused in consumer and account mode.
136
+ * See docs/wix-authentication.md → "Adopting a legacy session on an in-place upgrade". */
137
+ adoptLegacySession?: boolean;
131
138
  }
132
139
  export declare function WixNativeAuthProvider(config: WixNativeAuthConfig): AuthProvider;
@@ -34,11 +34,12 @@ export interface WixGetPostRequest {
34
34
  * but a body-less 200 was never the "body preserved whenever the backend is
35
35
  * healthy" the earlier comment claimed; the body was simply never requested.)
36
36
  *
37
- * On any rejection (network / backend error) we still fall back to a queryPosts
37
+ * On network / backend rejection we still fall back to a queryPosts
38
38
  * filter-by-id — a graceful degrade to the LIST projection (no body) that keeps
39
39
  * blog detail + saved screens rendering instead of erroring out. `queryPosts`'s
40
40
  * request type has no `fieldsets` field, so that fallback path cannot carry the
41
- * body.
41
+ * body. Detail readers can opt into `preserveAccessErrors` to keep HTTP 401/403
42
+ * refusals instead of a public metadata fallback; default callers are unchanged.
42
43
  *
43
44
  * When that fallback ALSO finds nothing — a deleted post, or one this visitor
44
45
  * may not see — we reject rather than resolve. `WixGetPostResponse.post`
@@ -50,7 +51,9 @@ export interface WixGetPostRequest {
50
51
  * `catch`, or an `allSettled` filter), so rejecting is what routes them into the
51
52
  * graceful degrade they already implement. The originating failure travels as
52
53
  * `cause`, so the 404-vs-network distinction is not lost. */
53
- export declare function getPost(postId: string, req?: WixGetPostRequest, readOptions?: WixCallOptions): Promise<WixGetPostResponse>;
54
+ export declare function getPost(postId: string, req?: WixGetPostRequest, readOptions?: WixCallOptions & {
55
+ preserveAccessErrors?: boolean;
56
+ }): Promise<WixGetPostResponse>;
54
57
  export interface WixBlogCategory {
55
58
  id: string;
56
59
  label?: string;
@@ -66,6 +66,12 @@ export interface MfvNotification {
66
66
  export declare function __resetMfvRouteForTests(): void;
67
67
  /** List the signed-in member's notifications, newest first. MOBILE channel. */
68
68
  export declare function queryNotifications(limit?: number, options?: WixCallOptions): Promise<MfvNotification[]>;
69
+ /** Source member-app MOBILE/UNSEEN aggregate, capped at 100. Requires a bound
70
+ * single-site Member transport; old native binaries and web reject. A missing,
71
+ * malformed or failed result is unavailable, never an authoritative zero. */
72
+ export declare function countUnseenNotifications(options: {
73
+ site: string;
74
+ }): Promise<number>;
69
75
  /** Mark the given notification ids as READ (bulk, by-filter). */
70
76
  export declare function markRead(ids: string[]): Promise<void>;
71
77
  /** Mark ALL of the member's MOBILE notifications that aren't already READ as READ. */
@@ -74,6 +74,21 @@ function matchesType(type, value) {
74
74
  return true;
75
75
  }
76
76
  }
77
+ var AUTHORED_PATTERN_LIMIT = 64;
78
+ var authoredPatterns = /* @__PURE__ */ new Map();
79
+ function authoredPattern(pattern) {
80
+ const known = authoredPatterns.get(pattern);
81
+ if (known !== void 0) return known;
82
+ let re;
83
+ try {
84
+ re = new RegExp(`^(?:${pattern})$`);
85
+ } catch {
86
+ re = null;
87
+ }
88
+ if (authoredPatterns.size >= AUTHORED_PATTERN_LIMIT) authoredPatterns.delete(authoredPatterns.keys().next().value);
89
+ authoredPatterns.set(pattern, re);
90
+ return re;
91
+ }
77
92
  function validate(rule, rawValue) {
78
93
  if (!rule) return null;
79
94
  const value = rawValue ?? "";
@@ -84,13 +99,8 @@ function validate(rule, rawValue) {
84
99
  return { rule: "type", type: rule.type };
85
100
  }
86
101
  if (rule.regex) {
87
- let ok;
88
- try {
89
- ok = new RegExp(`^(?:${rule.regex})$`).test(value);
90
- } catch {
91
- ok = true;
92
- }
93
- if (!ok) return { rule: "regex" };
102
+ const re = authoredPattern(rule.regex);
103
+ if (re && !re.test(value)) return { rule: "regex" };
94
104
  }
95
105
  if (typeof rule.minLength === "number" && rule.minLength > 0 && value.length < rule.minLength) {
96
106
  return { rule: "minLength", limit: rule.minLength };
@@ -112,6 +112,21 @@ function matchesType(type, value) {
112
112
  return true;
113
113
  }
114
114
  }
115
+ var AUTHORED_PATTERN_LIMIT = 64;
116
+ var authoredPatterns = /* @__PURE__ */ new Map();
117
+ function authoredPattern(pattern) {
118
+ const known = authoredPatterns.get(pattern);
119
+ if (known !== void 0) return known;
120
+ let re;
121
+ try {
122
+ re = new RegExp(`^(?:${pattern})$`);
123
+ } catch {
124
+ re = null;
125
+ }
126
+ if (authoredPatterns.size >= AUTHORED_PATTERN_LIMIT) authoredPatterns.delete(authoredPatterns.keys().next().value);
127
+ authoredPatterns.set(pattern, re);
128
+ return re;
129
+ }
115
130
  function validate(rule, rawValue) {
116
131
  if (!rule) return null;
117
132
  const value = rawValue ?? "";
@@ -122,13 +137,8 @@ function validate(rule, rawValue) {
122
137
  return { rule: "type", type: rule.type };
123
138
  }
124
139
  if (rule.regex) {
125
- let ok;
126
- try {
127
- ok = new RegExp(`^(?:${rule.regex})$`).test(value);
128
- } catch {
129
- ok = true;
130
- }
131
- if (!ok) return { rule: "regex" };
140
+ const re = authoredPattern(rule.regex);
141
+ if (re && !re.test(value)) return { rule: "regex" };
132
142
  }
133
143
  if (typeof rule.minLength === "number" && rule.minLength > 0 && value.length < rule.minLength) {
134
144
  return { rule: "minLength", limit: rule.minLength };
@@ -9827,6 +9827,21 @@ function matchesType(type, value) {
9827
9827
  return true;
9828
9828
  }
9829
9829
  }
9830
+ var AUTHORED_PATTERN_LIMIT = 64;
9831
+ var authoredPatterns = /* @__PURE__ */ new Map();
9832
+ function authoredPattern(pattern) {
9833
+ const known = authoredPatterns.get(pattern);
9834
+ if (known !== void 0) return known;
9835
+ let re;
9836
+ try {
9837
+ re = new RegExp(`^(?:${pattern})$`);
9838
+ } catch {
9839
+ re = null;
9840
+ }
9841
+ if (authoredPatterns.size >= AUTHORED_PATTERN_LIMIT) authoredPatterns.delete(authoredPatterns.keys().next().value);
9842
+ authoredPatterns.set(pattern, re);
9843
+ return re;
9844
+ }
9830
9845
  function validate(rule, rawValue) {
9831
9846
  if (!rule) return null;
9832
9847
  const value = rawValue ?? "";
@@ -9837,13 +9852,8 @@ function validate(rule, rawValue) {
9837
9852
  return { rule: "type", type: rule.type };
9838
9853
  }
9839
9854
  if (rule.regex) {
9840
- let ok;
9841
- try {
9842
- ok = new RegExp(`^(?:${rule.regex})$`).test(value);
9843
- } catch {
9844
- ok = true;
9845
- }
9846
- if (!ok) return { rule: "regex" };
9855
+ const re = authoredPattern(rule.regex);
9856
+ if (re && !re.test(value)) return { rule: "regex" };
9847
9857
  }
9848
9858
  if (typeof rule.minLength === "number" && rule.minLength > 0 && value.length < rule.minLength) {
9849
9859
  return { rule: "minLength", limit: rule.minLength };
@@ -74,6 +74,21 @@ function matchesType(type, value) {
74
74
  return true;
75
75
  }
76
76
  }
77
+ var AUTHORED_PATTERN_LIMIT = 64;
78
+ var authoredPatterns = /* @__PURE__ */ new Map();
79
+ function authoredPattern(pattern) {
80
+ const known = authoredPatterns.get(pattern);
81
+ if (known !== void 0) return known;
82
+ let re;
83
+ try {
84
+ re = new RegExp(`^(?:${pattern})$`);
85
+ } catch {
86
+ re = null;
87
+ }
88
+ if (authoredPatterns.size >= AUTHORED_PATTERN_LIMIT) authoredPatterns.delete(authoredPatterns.keys().next().value);
89
+ authoredPatterns.set(pattern, re);
90
+ return re;
91
+ }
77
92
  function validate(rule, rawValue) {
78
93
  if (!rule) return null;
79
94
  const value = rawValue ?? "";
@@ -84,13 +99,8 @@ function validate(rule, rawValue) {
84
99
  return { rule: "type", type: rule.type };
85
100
  }
86
101
  if (rule.regex) {
87
- let ok;
88
- try {
89
- ok = new RegExp(`^(?:${rule.regex})$`).test(value);
90
- } catch {
91
- ok = true;
92
- }
93
- if (!ok) return { rule: "regex" };
102
+ const re = authoredPattern(rule.regex);
103
+ if (re && !re.test(value)) return { rule: "regex" };
94
104
  }
95
105
  if (typeof rule.minLength === "number" && rule.minLength > 0 && value.length < rule.minLength) {
96
106
  return { rule: "minLength", limit: rule.minLength };
@@ -275,6 +275,21 @@ function matchesType(type, value) {
275
275
  return true;
276
276
  }
277
277
  }
278
+ var AUTHORED_PATTERN_LIMIT = 64;
279
+ var authoredPatterns = /* @__PURE__ */ new Map();
280
+ function authoredPattern(pattern) {
281
+ const known = authoredPatterns.get(pattern);
282
+ if (known !== void 0) return known;
283
+ let re;
284
+ try {
285
+ re = new RegExp(`^(?:${pattern})$`);
286
+ } catch {
287
+ re = null;
288
+ }
289
+ if (authoredPatterns.size >= AUTHORED_PATTERN_LIMIT) authoredPatterns.delete(authoredPatterns.keys().next().value);
290
+ authoredPatterns.set(pattern, re);
291
+ return re;
292
+ }
278
293
  function validate(rule, rawValue) {
279
294
  if (!rule) return null;
280
295
  const value = rawValue ?? "";
@@ -285,13 +300,8 @@ function validate(rule, rawValue) {
285
300
  return { rule: "type", type: rule.type };
286
301
  }
287
302
  if (rule.regex) {
288
- let ok;
289
- try {
290
- ok = new RegExp(`^(?:${rule.regex})$`).test(value);
291
- } catch {
292
- ok = true;
293
- }
294
- if (!ok) return { rule: "regex" };
303
+ const re = authoredPattern(rule.regex);
304
+ if (re && !re.test(value)) return { rule: "regex" };
295
305
  }
296
306
  if (typeof rule.minLength === "number" && rule.minLength > 0 && value.length < rule.minLength) {
297
307
  return { rule: "minLength", limit: rule.minLength };
@@ -1254,6 +1254,11 @@ function WixNativeAuthProvider(config) {
1254
1254
  if (config.mode !== "owner" && config.mode !== "consumer" && config.mode !== "account") {
1255
1255
  throw new Error('WixNativeAuthProvider: mode must be "owner", "consumer" or "account".');
1256
1256
  }
1257
+ if (config.adoptLegacySession && config.mode !== "owner") {
1258
+ throw new Error(
1259
+ `WixNativeAuthProvider: adoptLegacySession is owner mode only (got mode "${config.mode}"): it adopts a Wix ACCOUNT session the previous app left in the platform cookie jars.`
1260
+ );
1261
+ }
1257
1262
  return {
1258
1263
  providerId: "wix-native",
1259
1264
  config: {
@@ -1266,7 +1271,8 @@ function WixNativeAuthProvider(config) {
1266
1271
  ...config.pxToken ? { pxToken: config.pxToken } : {},
1267
1272
  ...config.petriOverrides ? { petriOverrides: config.petriOverrides } : {},
1268
1273
  devMode: config.devMode ?? false,
1269
- ...config.hostProvided ? { hostProvided: true } : {}
1274
+ ...config.hostProvided ? { hostProvided: true } : {},
1275
+ ...config.adoptLegacySession ? { adoptLegacySession: true } : {}
1270
1276
  }
1271
1277
  };
1272
1278
  }
@@ -15,6 +15,7 @@ function getPost(postId, req = {}, readOptions) {
15
15
  void 0,
16
16
  readOptions
17
17
  ).catch(async (cause) => {
18
+ if (readOptions?.preserveAccessErrors && /^HTTP\s*(?:401|403)\b/i.test(String(cause?.message ?? cause))) throw cause;
18
19
  if (readOptions?.cache || readOptions?.onCacheResult) throw cause;
19
20
  const resp = await queryPosts({ query: { filter: { id: postId } } }, readOptions);
20
21
  const post = resp.posts?.[0];
@@ -61,6 +61,23 @@ async function queryNotifications(limit = 25, options) {
61
61
  );
62
62
  return res.viewerFeedNotifications ?? [];
63
63
  }
64
+ async function countUnseenNotifications(options) {
65
+ const site = options?.site;
66
+ if (typeof site !== "string" || !/^[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}$/i.test(site)) {
67
+ throw new Error("@himalaya/wix-members-feed-viewer: notification count requires its bound site");
68
+ }
69
+ const res = await wixCall(
70
+ "POST",
71
+ "https://apps.wix.com/_api/members-feed-viewer/v1/members-viewer-feed-notifications/count",
72
+ { filter: { channel: "MOBILE", status: "UNSEEN" }, maxCount: 100 },
73
+ { site }
74
+ );
75
+ const count = res?.count;
76
+ if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0 || count > 100) {
77
+ throw new Error("@himalaya/wix-members-feed-viewer: unavailable unseen notification count");
78
+ }
79
+ return count;
80
+ }
64
81
  async function markRead(ids) {
65
82
  if (!ids.length) return;
66
83
  await mfvCall(
@@ -78,6 +95,7 @@ async function markAllRead() {
78
95
  }
79
96
  export {
80
97
  __resetMfvRouteForTests,
98
+ countUnseenNotifications,
81
99
  markAllRead,
82
100
  markRead,
83
101
  queryNotifications