@wix/himalaya-cli 0.1071.0 → 0.1073.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 (49) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-config.d.ts +18 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +21 -3
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +4 -2
  4. package/dist/cli.mjs +114 -42
  5. package/dist/preview-assets.generated.bin +0 -0
  6. package/guides/sdk-reference.json +17 -5
  7. package/package.json +2 -2
  8. package/templates/beauty-salon/dev/index.ts +1 -0
  9. package/templates/beauty-salon-owner/dev/index.ts +64 -0
  10. package/templates/beauty-salon-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  11. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  12. package/templates/community-club-owner/dev/index.ts +96 -0
  13. package/templates/community-club-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  14. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  15. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  16. package/templates/events-meetups-owner/dev/index.ts +32 -0
  17. package/templates/events-meetups-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  18. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  19. package/templates/gym-fitness/dev/index.ts +1 -0
  20. package/templates/gym-fitness-owner/dev/index.ts +96 -0
  21. package/templates/gym-fitness-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  22. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  23. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  24. package/templates/nonprofit-cause-owner/dev/index.ts +32 -0
  25. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  26. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  27. package/templates/owner-lite/dev/index.ts +192 -0
  28. package/templates/owner-lite/tier5-src/_shared/owner-rich-guard.ts +64 -0
  29. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  30. package/templates/owner-lite/tier5-src/himi-owner-lite-faq-question-form/index.ts +18 -5
  31. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  32. package/templates/podcast-creator-owner/dev/index.ts +96 -0
  33. package/templates/podcast-creator-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  34. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  35. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  36. package/templates/portfolio-creative-owner/dev/index.ts +64 -0
  37. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  38. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  39. package/templates/restaurant/dev/index.ts +1 -0
  40. package/templates/restaurant-owner/dev/index.ts +96 -0
  41. package/templates/restaurant-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  42. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
  43. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  44. package/templates/retail-store-owner/dev/index.ts +64 -0
  45. package/templates/retail-store-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  46. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +24 -5
  47. package/templates/yoga-studio-owner/dev/index.ts +32 -0
  48. package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +64 -0
  49. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +44 -10
@@ -224,5 +224,23 @@ export interface AppConfigDocument {
224
224
  * `/v1/boot` uses this too, so the first-paint optimization cannot drift from
225
225
  * the authoritative per-document fallback in locale handling, overrides, or
226
226
  * navigation-bundle expansion. */
227
+ /** Every linkable-screen entry with all five fields — the defaults Kotlin and Swift apply. Binaries
228
+ * shipped before #3318 decode a linkable screen with all five REQUIRED and drop the whole
229
+ * NavigationConfig when one is missing, so nothing served may carry a partial entry. */
230
+ export declare function completeLinkableScreens<T extends {
231
+ screenId: string;
232
+ isPublic?: boolean;
233
+ paramKeys?: string[];
234
+ parentScreenId?: string;
235
+ tabId?: string;
236
+ }>(list: readonly T[]): (T & {
237
+ isPublic: boolean;
238
+ paramKeys: string[];
239
+ parentScreenId: string;
240
+ tabId: string;
241
+ })[];
242
+ /** A merged (overridden) config with its linkable screens completed — ONE rule for every place that
243
+ * shows or serves the effective config, so the admin view and the device payload cannot diverge. */
244
+ export declare function withCompleteLinkables<T extends object>(cfg: T): T;
227
245
  export declare function buildAppConfigDocument(req: IncomingMessage, meta: DerivedAppMeta, override?: Record<string, unknown>, bundleCtx?: NavBundleContext): AppConfigDocument;
228
246
  export declare function handleAppConfigRequest(req: IncomingMessage, res: ServerResponse, meta: DerivedAppMeta, override?: Record<string, unknown>, bundleCtx?: NavBundleContext): void;
@@ -51,7 +51,9 @@ export interface WixEvent {
51
51
  mainImage?: WixEventImage;
52
52
  slug?: string;
53
53
  about?: string;
54
- description?: string;
54
+ /** Events v3: a Ricos document ({@link WixEventRichContent}), returned only when the `TEXTS`
55
+ * fieldset is requested (`getEvent(id, { fields: ["TEXTS"] })`). Older payloads sent a string. */
56
+ description?: string | WixEventRichContent;
55
57
  }
56
58
  export interface WixGetEventListResponse {
57
59
  events: WixEvent[];
@@ -132,12 +134,26 @@ export declare function decodeEvent(raw: WixEvent): WixEvent;
132
134
  * not just an owner session. (NOT the owner-only GET /events-in-clubs/chunked-events,
133
135
  * which returns an HTML error page for a visitor token.) */
134
136
  export declare function queryEvents(opts?: WixQueryEventsOptions): Promise<WixGetEventListResponse>;
137
+ /** Events v3 response fieldsets (`RequestedFields`). A bare read returns the base fieldset;
138
+ * each value adds fields: `DETAILS` → `shortDescription`, `mainImage`, `calendarUrls`;
139
+ * `TEXTS` → the Ricos `description`; `REGISTRATION` → `registration`; `URLS` → `eventPageUrl`. */
140
+ export type WixEventFieldset = "DETAILS" | "TEXTS" | "REGISTRATION" | "URLS";
141
+ /** A Ricos document (Events v3 `description`). Opaque here: read it with a Ricos walker, and
142
+ * write it back whole — a PATCH replaces the entire description. */
143
+ export interface WixEventRichContent {
144
+ nodes?: unknown[];
145
+ metadata?: unknown;
146
+ documentStyle?: unknown;
147
+ }
135
148
  /** Get one event — GET /events/v3/events/{eventId}. Response wraps as `{ event }`.
136
149
  * NOTE: this GET returns the Events v3 BASE fieldset — slimmer than `queryEvents`,
137
150
  * which returns the richer default (fields such as `registration` and `calendarUrls`
138
151
  * are absent from a bare `getEvent`). If a detail screen needs those fields for one
139
- * event, prefer `queryEvents` and pick the row by id over `getEvent`. */
140
- export declare function getEvent(eventId: string): Promise<WixGetEventResponse>;
152
+ * event, prefer `queryEvents` and pick the row by id over `getEvent`.
153
+ * `opts.fields` requests extra v3 fieldsets; `["TEXTS"]` returns `description`. */
154
+ export declare function getEvent(eventId: string, opts?: {
155
+ fields?: WixEventFieldset[];
156
+ }): Promise<WixGetEventResponse>;
141
157
  /** Delete an event — DELETE /events/v3/events/{eventId}. */
142
158
  export declare function deleteEvent(eventId: string): Promise<WixDeleteEventResponse>;
143
159
  /** Write shape for create/update (Events v3). Verified-minimal: a create needs
@@ -160,6 +176,8 @@ export interface WixEventWrite {
160
176
  };
161
177
  mainImage?: WixEventImage;
162
178
  about?: string;
179
+ /** Ricos document; replaces the whole description. */
180
+ description?: WixEventRichContent;
163
181
  }
164
182
  /** Create an event — POST /events/v3/events → { event }. */
165
183
  export declare function createEvent(event: WixEventWrite): Promise<WixGetEventResponse>;
@@ -301,9 +301,11 @@ async function queryEvents(opts = {}) {
301
301
  if (opts.order === "start") events = events.slice().sort((a, b) => eventStartMs(a) - eventStartMs(b));
302
302
  return { ...res, events };
303
303
  }
304
- async function getEvent(eventId) {
304
+ async function getEvent(eventId, opts = {}) {
305
305
  if (!eventId) throw new Error("getEvent: eventId is required");
306
- const res = await wixCall("GET", `/events/v3/events/${encodeURIComponent(eventId)}`);
306
+ const fields = (opts.fields ?? []).map((f) => `fields=${encodeURIComponent(f)}`).join("&");
307
+ const query = fields ? `?${fields}` : "";
308
+ const res = await wixCall("GET", `/events/v3/events/${encodeURIComponent(eventId)}${query}`);
307
309
  return { ...res, event: decodeEvent(res.event) };
308
310
  }
309
311
  function deleteEvent(eventId) {
package/dist/cli.mjs CHANGED
@@ -6732,7 +6732,6 @@ function walk(node, registry, path2, out) {
6732
6732
  var SYSTEM_FONT_FAMILY, TONAL_ELEVATION_ALPHA;
6733
6733
  var init_tokens = __esm({
6734
6734
  "../../core/ts/src/tokens.ts"() {
6735
- "use strict";
6736
6735
  SYSTEM_FONT_FAMILY = "$system";
6737
6736
  TONAL_ELEVATION_ALPHA = [0, 0.05, 0.08, 0.11, 0.12, 0.14];
6738
6737
  }
@@ -6759,7 +6758,6 @@ function resolveTranslation(value, catalog, sourceCatalog) {
6759
6758
  var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
6760
6759
  var init_bindings = __esm({
6761
6760
  "../../core/ts/src/bindings.ts"() {
6762
- "use strict";
6763
6761
  BINDING_SIGILS = ["service", "flag", "item", "t"];
6764
6762
  BINDING_SIGIL_RE = new RegExp(
6765
6763
  `^\\$(?:${BINDING_SIGILS.filter((s) => s !== "t").join("|")})\\b|^\\$t:`
@@ -23003,6 +23001,7 @@ function shouldRevealError(args) {
23003
23001
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
23004
23002
  var init_validation = __esm({
23005
23003
  "../../core/ts/src/validation.ts"() {
23004
+ "use strict";
23006
23005
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
23007
23006
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
23008
23007
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -26603,6 +26602,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
26603
26602
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
26604
26603
  var init_worker_subtree = __esm({
26605
26604
  "../../core/ts/src/worker-subtree.ts"() {
26605
+ "use strict";
26606
26606
  init_worker_subtree_safe_types_generated();
26607
26607
  WORKER_SUBTREE_CEILINGS = Object.freeze({
26608
26608
  maxEncodedBytes: 65536,
@@ -27755,6 +27755,13 @@ function fitZoom(pts, w, h, fallback) {
27755
27755
  }
27756
27756
  return 1;
27757
27757
  }
27758
+ function layoutScale(el) {
27759
+ const r = el.getBoundingClientRect();
27760
+ return {
27761
+ kx: r.width > 0 && el.offsetWidth > 0 ? el.offsetWidth / r.width : 1,
27762
+ ky: r.height > 0 && el.offsetHeight > 0 ? el.offsetHeight / r.height : 1
27763
+ };
27764
+ }
27758
27765
  function parseLocalDate(when) {
27759
27766
  if (when == null || when === "") return null;
27760
27767
  if (typeof when === "string") {
@@ -31750,18 +31757,18 @@ var init_renderNode = __esm({
31750
31757
  }), [JSON.stringify(shapesRaw)]);
31751
31758
  const boundCameraRaw = useResolvedScalar(props.cameraPath, ctx);
31752
31759
  const commandedCamera = React5.useMemo(() => decodeCamera(boundCameraRaw), [boundCameraRaw]);
31753
- const boxRef = React5.useRef(null);
31754
31760
  const [box, setBox] = React5.useState({ w: 400, h });
31755
31761
  const [userCam, setUserCam] = React5.useState(null);
31756
31762
  const dragRef = React5.useRef(null);
31757
31763
  const dragMovedRef = React5.useRef(false);
31758
31764
  const regionReportedRef = React5.useRef(false);
31765
+ const [boxEl, setBoxEl] = React5.useState(null);
31766
+ const attachBox = React5.useCallback((el) => setBoxEl(el), []);
31759
31767
  React5.useEffect(() => {
31760
- const el = boxRef.current;
31768
+ const el = boxEl;
31761
31769
  if (!el) return;
31762
31770
  const measure = () => {
31763
- const r = el.getBoundingClientRect();
31764
- if (r.width > 0 && r.height > 0) setBox({ w: r.width, h: r.height });
31771
+ if (el.clientWidth > 0 && el.clientHeight > 0) setBox({ w: el.clientWidth, h: el.clientHeight });
31765
31772
  };
31766
31773
  measure();
31767
31774
  const RO = globalThis.ResizeObserver;
@@ -31769,12 +31776,18 @@ var init_renderNode = __esm({
31769
31776
  const ro = new RO(measure);
31770
31777
  ro.observe(el);
31771
31778
  return () => ro.disconnect();
31772
- }, [h]);
31773
- const usesTileArm = (route.length > 0 || shapes.length > 0 || hasEvents || props.cameraPath != null || props.showUserLocation === true || props.fitToContent === true) && !usesSchematicRoute(props);
31779
+ }, [boxEl, h]);
31780
+ const hasMarkerFeed = typeof props.markersPath === "string" && props.markersPath !== "";
31781
+ const hasStaticMarkers = markers.length > 0 && !hasMarkerFeed;
31782
+ const otherTileReason = route.length > 0 || shapes.length > 0 || hasEvents || props.cameraPath != null || props.showUserLocation === true || props.fitToContent === true;
31783
+ const usesTileArm = (otherTileReason || hasStaticMarkers) && !usesSchematicRoute(props);
31784
+ const pinsOnly = hasStaticMarkers && !otherTileReason;
31774
31785
  {
31775
31786
  const all = [...route, ...markers, ...shapes.flatMap((sh) => sh.points)].filter((p) => p && typeof p.latitude === "number" && typeof p.longitude === "number");
31776
31787
  const declared = typeof props.zoom === "number" && props.zoom > 0 ? Math.max(1, Math.min(19, props.zoom)) : 13;
31777
- const shouldFit = props.fitToContent === true || route.length > 0;
31788
+ const hasCenter = typeof props.latitude === "number" && typeof props.longitude === "number";
31789
+ const hasZoom = typeof props.zoom === "number" && props.zoom > 0;
31790
+ const shouldFit = props.fitToContent === true || route.length > 0 || pinsOnly && (!hasCenter || markers.length > 1 && !hasZoom);
31778
31791
  const W = box.w;
31779
31792
  const H = box.h;
31780
31793
  const fitted = shouldFit ? fitZoom(all, W - 48, H - 48, declared) : declared;
@@ -31794,7 +31807,7 @@ var init_renderNode = __esm({
31794
31807
  }, [commandedCamera]);
31795
31808
  const originX = mercatorX(cLng, z) - W / 2;
31796
31809
  const originY = mercatorY(cLat, z) - H / 2;
31797
- const interactive = props.interactive !== false;
31810
+ const interactive = pinsOnly ? props.interactive === true : props.interactive !== false;
31798
31811
  const resolvedTileSource = resolveTileSource(props.tileSource);
31799
31812
  const fireMapEvent = (action, payload) => {
31800
31813
  if (!action || !ctx.onAction) return;
@@ -31806,9 +31819,11 @@ var init_renderNode = __esm({
31806
31819
  return;
31807
31820
  }
31808
31821
  if (!props.onMapTap && !props.onMarkerTap) return;
31809
- const r = e.currentTarget.getBoundingClientRect();
31810
- const px = e.clientX - r.left;
31811
- const py = e.clientY - r.top;
31822
+ const el = e.currentTarget;
31823
+ const r = el.getBoundingClientRect();
31824
+ const { kx, ky } = layoutScale(el);
31825
+ const px = (e.clientX - r.left) * kx - el.clientLeft;
31826
+ const py = (e.clientY - r.top) * ky - el.clientTop;
31812
31827
  const hit = markerHit(px, py, markers, z, originX, originY);
31813
31828
  if (hit !== null) {
31814
31829
  const m = markers[hit];
@@ -31840,14 +31855,14 @@ var init_renderNode = __esm({
31840
31855
  };
31841
31856
  const onPointerDown = (e) => {
31842
31857
  if (!interactive) return;
31843
- dragRef.current = { x: e.clientX, y: e.clientY, lat: cLat, lng: cLng, z };
31858
+ dragRef.current = { x: e.clientX, y: e.clientY, lat: cLat, lng: cLng, z, ...layoutScale(e.currentTarget) };
31844
31859
  dragMovedRef.current = false;
31845
31860
  };
31846
31861
  const onPointerMove = (e) => {
31847
31862
  const d2 = dragRef.current;
31848
31863
  if (!d2) return;
31849
- const dx = e.clientX - d2.x;
31850
- const dy = e.clientY - d2.y;
31864
+ const dx = (e.clientX - d2.x) * d2.kx;
31865
+ const dy = (e.clientY - d2.y) * d2.ky;
31851
31866
  if (Math.abs(dx) + Math.abs(dy) < 3) return;
31852
31867
  dragMovedRef.current = true;
31853
31868
  const cx = mercatorX(d2.lng, d2.z) - dx;
@@ -31900,7 +31915,7 @@ var init_renderNode = __esm({
31900
31915
  if (usesTileArm) return /* @__PURE__ */ jsxs3(
31901
31916
  "div",
31902
31917
  {
31903
- ref: boxRef,
31918
+ ref: attachBox,
31904
31919
  "data-map-mode": "tile",
31905
31920
  "data-route-points": route.length,
31906
31921
  "data-map-zoom": z,
@@ -31912,6 +31927,7 @@ var init_renderNode = __esm({
31912
31927
  onWheel,
31913
31928
  style: {
31914
31929
  width: "100%",
31930
+ boxSizing: "border-box",
31915
31931
  height: h,
31916
31932
  borderRadius: ctx.radius("md", 8),
31917
31933
  overflow: "hidden",
@@ -33402,7 +33418,7 @@ function deriveNavigationConfig(app, bundleCtx) {
33402
33418
  if (ov.parents[s.screenId]) s.parentScreenId = ov.parents[s.screenId];
33403
33419
  }
33404
33420
  }
33405
- const linkableScreens = app.linkableScreens?.length ? app.linkableScreens : [...concrete, ...templated];
33421
+ const linkableScreens = app.linkableScreens?.length ? completeLinkableScreens(app.linkableScreens) : [...concrete, ...templated];
33406
33422
  const config = {
33407
33423
  scheme: app.urlScheme,
33408
33424
  deepLinkPatterns: app.deepLinkPatterns ?? ov?.deepLinkPatterns ?? [],
@@ -33475,8 +33491,21 @@ function mergeConfig(base, patch) {
33475
33491
  }
33476
33492
  return out;
33477
33493
  }
33494
+ function completeLinkableScreens(list) {
33495
+ return list.map((s) => ({
33496
+ ...s,
33497
+ isPublic: s.isPublic ?? false,
33498
+ paramKeys: s.paramKeys ?? [],
33499
+ parentScreenId: s.parentScreenId ?? "",
33500
+ tabId: s.tabId ?? ""
33501
+ }));
33502
+ }
33503
+ function withCompleteLinkables(cfg) {
33504
+ const list = cfg.linkableScreens;
33505
+ return Array.isArray(list) ? { ...cfg, linkableScreens: completeLinkableScreens(list) } : cfg;
33506
+ }
33478
33507
  function buildAppConfigDocument(req, meta, override, bundleCtx) {
33479
- const baseline = override ? mergeConfig(deriveNavigationConfig(meta, bundleCtx), override) : deriveNavigationConfig(meta, bundleCtx);
33508
+ const baseline = override ? withCompleteLinkables(mergeConfig(deriveNavigationConfig(meta, bundleCtx), override)) : deriveNavigationConfig(meta, bundleCtx);
33480
33509
  const acceptLanguage = req.headers["accept-language"];
33481
33510
  const locale = pickLocale(typeof acceptLanguage === "string" ? acceptLanguage : null);
33482
33511
  const config = locale ? translate(JSON.parse(JSON.stringify(baseline)), locale) : baseline;
@@ -37300,9 +37329,9 @@ async function handleAdminPlayground(req, res, state) {
37300
37329
  }
37301
37330
  if (path2 === "/v1/admin/app-config" && state.app) {
37302
37331
  const built = deriveNavigationConfig(state.app.meta);
37332
+ const effectiveConfig = () => state.appConfigOverride ? withCompleteLinkables(deepMerge3(built, state.appConfigOverride)) : built;
37303
37333
  if (req.method === "GET") {
37304
- const effective = state.appConfigOverride ? deepMerge3(built, state.appConfigOverride) : built;
37305
- return sendJson(res, 200, { source: state.appConfigOverride ? "override" : "built", built, effective });
37334
+ return sendJson(res, 200, { source: state.appConfigOverride ? "override" : "built", built, effective: effectiveConfig() });
37306
37335
  }
37307
37336
  if (req.method === "PUT") {
37308
37337
  let patch;
@@ -37315,7 +37344,7 @@ async function handleAdminPlayground(req, res, state) {
37315
37344
  const nav = isNavControlPatch(patch);
37316
37345
  state.appConfigOverride = nav && state.appConfigOverride ? deepMerge3(state.appConfigOverride, patch) : patch;
37317
37346
  publishSSE(state, "config.invalidated", { reason: nav ? "navigate" : "admin_override", at: Date.now() });
37318
- return sendJson(res, 200, { status: "ok", effective: deepMerge3(built, state.appConfigOverride) });
37347
+ return sendJson(res, 200, { status: "ok", effective: effectiveConfig() });
37319
37348
  }
37320
37349
  if (req.method === "DELETE") {
37321
37350
  const existed = state.appConfigOverride !== void 0;
@@ -47770,6 +47799,43 @@ function unreachedNativeWrites(screen, bundleJs, observed) {
47770
47799
  }
47771
47800
  return out;
47772
47801
  }
47802
+ function splitEntries(cell) {
47803
+ const out = [];
47804
+ let depth = 0;
47805
+ let cur = "";
47806
+ for (const ch of cell) {
47807
+ if (ch === "(" || ch === "[") depth++;
47808
+ else if ((ch === ")" || ch === "]") && depth > 0) depth--;
47809
+ if ((ch === "," || ch === ";") && depth === 0) {
47810
+ out.push(cur);
47811
+ cur = "";
47812
+ continue;
47813
+ }
47814
+ cur += ch;
47815
+ }
47816
+ out.push(cur);
47817
+ if (depth > 0) return cell.split(/[,;]/).map((e) => e.trim()).filter(Boolean);
47818
+ return out.map((e) => e.trim()).filter(Boolean);
47819
+ }
47820
+ function entryHead(entry) {
47821
+ if (/^\s*[—–-]\s/.test(entry)) return "";
47822
+ return entry.split(/\s*[([]|\s+[—–]\s*|\s+-\s+/)[0].trim();
47823
+ }
47824
+ function entryNames(entry) {
47825
+ const head = entryHead(entry);
47826
+ return head ? [head] : [];
47827
+ }
47828
+ function hasNote(entry) {
47829
+ return entryHead(entry) !== entry.trim();
47830
+ }
47831
+ function namesLine(allowed2) {
47832
+ const names = [...new Set(allowed2.flatMap(entryNames))];
47833
+ return names.length ? `it names: ${names.join(", ")}` : "its entries are only notes, which approve nothing";
47834
+ }
47835
+ function isNoneEntry(entry) {
47836
+ const head = entryHead(entry);
47837
+ return NONE.test(entry) || head !== "" && NONE.test(head);
47838
+ }
47773
47839
  function parseDataAccess(text5, from) {
47774
47840
  const body = text5.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
47775
47841
  const heading = new RegExp(`(?:^|\\n)##[ \\t]+${DATA_ACCESS_HEADING}\\b[^\\n]*([\\s\\S]*?)(?=\\n##[ \\t]|$)`, "i").exec(body);
@@ -47789,7 +47855,7 @@ function parseDataAccess(text5, from) {
47789
47855
  const screen = unquote(row[screenCol] ?? "");
47790
47856
  if (!screen) continue;
47791
47857
  const cell = unquote(row[writesCol] ?? "");
47792
- const entries = cell.split(/[,;]/).map((e) => e.trim()).filter((e) => e && !NONE.test(e));
47858
+ const entries = splitEntries(cell).filter((e) => !isNoneEntry(e));
47793
47859
  rows.push({ screen, allowed: NONE.test(cell) || !entries.length ? null : entries });
47794
47860
  }
47795
47861
  return rows.length ? { from, rows } : null;
@@ -47810,15 +47876,19 @@ function readDataAccess(dir) {
47810
47876
  return null;
47811
47877
  }
47812
47878
  function entryApproves(entry, w) {
47813
- const e = entry.trim();
47879
+ const head = entryHead(entry);
47880
+ return head !== "" && nameApproves(head, w, !hasNote(entry));
47881
+ }
47882
+ function nameApproves(name, w, kinds) {
47883
+ const e = name.trim();
47814
47884
  const lower = e.toLowerCase();
47815
47885
  const actionTail = w.action.split(".").pop() ?? w.action;
47816
47886
  if (e === w.action || e === actionTail) return true;
47817
47887
  if (w.via === "native") {
47818
47888
  const tail = w.capability.split(".").pop();
47819
47889
  if (e === w.capability || e === tail || e === nativeWriteOf(w.capability)?.canonical) return true;
47820
- if (w.kind === "payment" && /^payments?$/.test(lower)) return true;
47821
- if (w.kind === "member-signup" && /^(sign-?up|register|registration|member[- ]signup)$/.test(lower)) return true;
47890
+ if (kinds && w.kind === "payment" && /^payments?$/.test(lower)) return true;
47891
+ if (kinds && w.kind === "member-signup" && /^(sign-?up|register|registration|member[- ]signup)$/.test(lower)) return true;
47822
47892
  return false;
47823
47893
  }
47824
47894
  const m = /^(?:(GET|POST|PUT|PATCH|DELETE)\s+)?(\/\S*|https?:\/\/\S+)$/i.exec(e);
@@ -47863,7 +47933,9 @@ function unapprovedWriteFindings(writes, plan) {
47863
47933
  trigger,
47864
47934
  invariant: "write-not-approved",
47865
47935
  severity: "warning",
47866
- message: allowed2.length ? `${does}, which ${plan.from}'s data-access table does not name for this screen (approved: ${allowed2.join(", ")})` : `${does}, but ${plan.from}'s data-access table approves no writes on this screen`,
47936
+ // Quote the NAMES the table offers, not its raw cells: printing `registerDirect (member sign-up)`
47937
+ // as "approved" beside "does not name registerDirect" read as a contradiction (#3317).
47938
+ message: allowed2.length ? `${does}, which ${plan.from}'s data-access table does not name for this screen (${namesLine(allowed2)})` : `${does}, but ${plan.from}'s data-access table approves no writes on this screen`,
47867
47939
  hint
47868
47940
  });
47869
47941
  }
@@ -53306,21 +53378,21 @@ var init_preview_assets_generated = __esm({
53306
53378
  "../../packages/serve/src/preview-assets.generated.ts"() {
53307
53379
  init_preview_assets_format();
53308
53380
  PREVIEW_ASSET_MANIFEST = [
53309
- { key: "assets/index-DlDXdHId.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1063092, sha256: "758c655ba88cbb54101f690281513fcff56aaa8b4a31dd49545d0f30f45e05f8" },
53310
- { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1063100, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
53311
- { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1067710, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
53312
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1556294, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
53313
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1647218, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
53314
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1738202, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
53315
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1829182, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
53316
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1920054, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
53317
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2011034, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
53318
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2119670, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
53319
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2228754, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
53320
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2337802, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
53321
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2445502, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
53322
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 2533610, length: 4947, sha256: "7a5bedfb0fdf0c376ce40bba70539332bca4b2fad4e4112465fb1875e03aa29b" },
53323
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2538557, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
53381
+ { key: "assets/index-m9AT09y1.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1063636, sha256: "21533f17025f9aff5e289562f02ca918ecb42fe690ccd8456a479b934be895f9" },
53382
+ { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1063644, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
53383
+ { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1068254, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
53384
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1556838, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
53385
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1647762, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
53386
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1738746, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
53387
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1829726, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
53388
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1920598, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
53389
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2011578, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
53390
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2120214, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
53391
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2229298, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
53392
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2338346, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
53393
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2446046, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
53394
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 2534154, length: 4947, sha256: "087ac1ca63900b0a2a73517170f77427493eb3c5ad226e535d14998227157118" },
53395
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2539101, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
53324
53396
  ];
53325
53397
  }
53326
53398
  });
Binary file
@@ -14370,7 +14370,7 @@
14370
14370
  "name": "WixEvent",
14371
14371
  "kind": "interface",
14372
14372
  "jsdoc": "",
14373
- "decl": "export interface WixEvent {\n id: string;\n title?: string;\n /** Normally one of `WixEventStatus` — `UPCOMING` (published and scheduled to start),\n * `STARTED`, `ENDED`, `CANCELED`, `DRAFT`. Events v1 called the first of those `SCHEDULED`,\n * and this SDK reads v3, so a row here never carries `SCHEDULED`.\n *\n * Deliberately NOT narrowed to that union: `decodeEvent` fills this from the server's\n * `status` and passes a value it does not recognise straight through, because dropping or\n * rewriting one would lose a real event. A union here would be a claim this SDK cannot\n * enforce. Compare against `WixEventStatus` when you need the set it knows. */\n eventStatus?: string;\n /** EventType: RSVP | TICKETS | EXTERNAL | NO_REGISTRATION */\n eventType?: string;\n scheduling?: WixEventScheduling;\n location?: WixEventLocation;\n mainImage?: WixEventImage;\n slug?: string;\n about?: string;\n description?: string;\n}"
14373
+ "decl": "export interface WixEvent {\n id: string;\n title?: string;\n /** Normally one of `WixEventStatus` — `UPCOMING` (published and scheduled to start),\n * `STARTED`, `ENDED`, `CANCELED`, `DRAFT`. Events v1 called the first of those `SCHEDULED`,\n * and this SDK reads v3, so a row here never carries `SCHEDULED`.\n *\n * Deliberately NOT narrowed to that union: `decodeEvent` fills this from the server's\n * `status` and passes a value it does not recognise straight through, because dropping or\n * rewriting one would lose a real event. A union here would be a claim this SDK cannot\n * enforce. Compare against `WixEventStatus` when you need the set it knows. */\n eventStatus?: string;\n /** EventType: RSVP | TICKETS | EXTERNAL | NO_REGISTRATION */\n eventType?: string;\n scheduling?: WixEventScheduling;\n location?: WixEventLocation;\n mainImage?: WixEventImage;\n slug?: string;\n about?: string;\n /** Events v3: a Ricos document ({@link WixEventRichContent}), returned only when the `TEXTS`\n * fieldset is requested (`getEvent(id, { fields: [\"TEXTS\"] })`). Older payloads sent a string. */\n description?: string | WixEventRichContent;\n}"
14374
14374
  },
14375
14375
  {
14376
14376
  "name": "WixGetEventListResponse",
@@ -14421,12 +14421,24 @@
14421
14421
  "decl": "export async function queryEvents(opts: WixQueryEventsOptions = {}): Promise<WixGetEventListResponse>;",
14422
14422
  "http": "POST /events/v3/events/query"
14423
14423
  },
14424
+ {
14425
+ "name": "WixEventFieldset",
14426
+ "kind": "type",
14427
+ "jsdoc": "/** Events v3 response fieldsets (`RequestedFields`). A bare read returns the base fieldset;\n * each value adds fields: `DETAILS` → `shortDescription`, `mainImage`, `calendarUrls`;\n * `TEXTS` → the Ricos `description`; `REGISTRATION` → `registration`; `URLS` → `eventPageUrl`. */",
14428
+ "decl": "export type WixEventFieldset = \"DETAILS\" | \"TEXTS\" | \"REGISTRATION\" | \"URLS\";"
14429
+ },
14430
+ {
14431
+ "name": "WixEventRichContent",
14432
+ "kind": "interface",
14433
+ "jsdoc": "/** A Ricos document (Events v3 `description`). Opaque here: read it with a Ricos walker, and\n * write it back whole — a PATCH replaces the entire description. */",
14434
+ "decl": "export interface WixEventRichContent { nodes?: unknown[]; metadata?: unknown; documentStyle?: unknown }"
14435
+ },
14424
14436
  {
14425
14437
  "name": "getEvent",
14426
14438
  "kind": "function",
14427
- "jsdoc": "/** Get one event — GET /events/v3/events/{eventId}. Response wraps as `{ event }`.\n * NOTE: this GET returns the Events v3 BASE fieldset — slimmer than `queryEvents`,\n * which returns the richer default (fields such as `registration` and `calendarUrls`\n * are absent from a bare `getEvent`). If a detail screen needs those fields for one\n * event, prefer `queryEvents` and pick the row by id over `getEvent`. */",
14428
- "decl": "export async function getEvent(eventId: string): Promise<WixGetEventResponse>;",
14429
- "http": "GET /events/v3/events/{…}"
14439
+ "jsdoc": "/** Get one event — GET /events/v3/events/{eventId}. Response wraps as `{ event }`.\n * NOTE: this GET returns the Events v3 BASE fieldset — slimmer than `queryEvents`,\n * which returns the richer default (fields such as `registration` and `calendarUrls`\n * are absent from a bare `getEvent`). If a detail screen needs those fields for one\n * event, prefer `queryEvents` and pick the row by id over `getEvent`.\n * `opts.fields` requests extra v3 fieldsets; `[\"TEXTS\"]` returns `description`. */",
14440
+ "decl": "export async function getEvent(eventId: string, opts: { fields?: WixEventFieldset[] } = {}): Promise<WixGetEventResponse>;",
14441
+ "http": "GET /events/v3/events/{…}{…}"
14430
14442
  },
14431
14443
  {
14432
14444
  "name": "deleteEvent",
@@ -14439,7 +14451,7 @@
14439
14451
  "name": "WixEventWrite",
14440
14452
  "kind": "interface",
14441
14453
  "jsdoc": "/** Write shape for create/update (Events v3). Verified-minimal: a create needs\n * BOTH `name` and `title`, a `dateAndTimeSettings` window, a `location`, and a\n * `registration.initialType` (RSVP | TICKETS | RSVP_AND_TICKETS). */",
14442
- "decl": "export interface WixEventWrite {\n name?: string;\n title?: string;\n dateAndTimeSettings?: { startDate?: string; endDate?: string; timeZoneId?: string };\n location?: { type?: string; name?: string };\n registration?: { initialType?: string };\n mainImage?: WixEventImage;\n about?: string;\n}"
14454
+ "decl": "export interface WixEventWrite {\n name?: string;\n title?: string;\n dateAndTimeSettings?: { startDate?: string; endDate?: string; timeZoneId?: string };\n location?: { type?: string; name?: string };\n registration?: { initialType?: string };\n mainImage?: WixEventImage;\n about?: string;\n /** Ricos document; replaces the whole description. */\n description?: WixEventRichContent;\n}"
14443
14455
  },
14444
14456
  {
14445
14457
  "name": "createEvent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1071.0",
3
+ "version": "0.1073.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": [
@@ -65,5 +65,5 @@
65
65
  "artifactId": "himalaya-cli"
66
66
  }
67
67
  },
68
- "falconPackageHash": "6640fad907fef656cbb5c2fa0b681448939515cf50af74a45c59083c"
68
+ "falconPackageHash": "f53841877488b72f64021f8682b974243c8e0b92b972ba48c02e5c78"
69
69
  }
@@ -1092,6 +1092,7 @@ const SCREENS = runtimeSetting({
1092
1092
  "top": 16,
1093
1093
  "bottom": 16
1094
1094
  },
1095
+ "fillMaxWidth": true,
1095
1096
  "hiddenPath": "$service:himiBrandedHome.hideHeroFallback"
1096
1097
  }
1097
1098
  },
@@ -73953,6 +73953,35 @@ const SCREENS = runtimeSetting({
73953
73953
  }
73954
73954
  }
73955
73955
  },
73956
+ {
73957
+ "id": "product_form.description_note",
73958
+ "body": {
73959
+ "package": "himalaya",
73960
+ "type": "Text",
73961
+ "props": {
73962
+ "text": "$service:himiOwnerLiteProductForm.descriptionNote",
73963
+ "style": "footnote",
73964
+ "color": "textSecondary",
73965
+ "collapseWhenEmpty": true
73966
+ }
73967
+ }
73968
+ },
73969
+ {
73970
+ "id": "product_form.description_preview",
73971
+ "body": {
73972
+ "package": "himalaya",
73973
+ "type": "Text",
73974
+ "props": {
73975
+ "text": "$service:himiOwnerLiteProductForm.description",
73976
+ "style": "body",
73977
+ "maxLines": 8,
73978
+ "collapseWhenEmpty": true
73979
+ }
73980
+ },
73981
+ "modifiers": {
73982
+ "hiddenPath": "$service:himiOwnerLiteProductForm.descriptionEditable"
73983
+ }
73984
+ },
73956
73985
  {
73957
73986
  "id": "product_form.form",
73958
73987
  "body": {
@@ -74039,6 +74068,9 @@ const SCREENS = runtimeSetting({
74039
74068
  "multilineMaxLines": 3
74040
74069
  }
74041
74070
  }
74071
+ },
74072
+ "modifiers": {
74073
+ "hiddenPath": "$service:himiOwnerLiteProductForm.descriptionProtected"
74042
74074
  }
74043
74075
  }
74044
74076
  ],
@@ -74566,6 +74598,35 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
74566
74598
  }
74567
74599
  }
74568
74600
  },
74601
+ {
74602
+ "id": "product_form.description_note",
74603
+ "body": {
74604
+ "package": "himalaya",
74605
+ "type": "Text",
74606
+ "props": {
74607
+ "text": "$service:himiOwnerLiteProductForm.descriptionNote",
74608
+ "style": "footnote",
74609
+ "color": "textSecondary",
74610
+ "collapseWhenEmpty": true
74611
+ }
74612
+ }
74613
+ },
74614
+ {
74615
+ "id": "product_form.description_preview",
74616
+ "body": {
74617
+ "package": "himalaya",
74618
+ "type": "Text",
74619
+ "props": {
74620
+ "text": "$service:himiOwnerLiteProductForm.description",
74621
+ "style": "body",
74622
+ "maxLines": 8,
74623
+ "collapseWhenEmpty": true
74624
+ }
74625
+ },
74626
+ "modifiers": {
74627
+ "hiddenPath": "$service:himiOwnerLiteProductForm.descriptionEditable"
74628
+ }
74629
+ },
74569
74630
  {
74570
74631
  "id": "product_form.form",
74571
74632
  "body": {
@@ -74652,6 +74713,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
74652
74713
  "multilineMaxLines": 3
74653
74714
  }
74654
74715
  }
74716
+ },
74717
+ "modifiers": {
74718
+ "hiddenPath": "$service:himiOwnerLiteProductForm.descriptionProtected"
74655
74719
  }
74656
74720
  }
74657
74721
  ],