@wix/himalaya-cli 0.1592.0 → 0.1594.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/contacts/src/index.d.ts +52 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/sdk-types/src/capabilities.generated.d.ts +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/audio-record.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/calendar.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/calls.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/contacts.mjs +90 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/location.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/motion.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/photos.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdk-types.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/tasks.mjs +1 -1
- package/dist/cli.mjs +47 -41
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/one-app-to-himi-app.md +12 -0
- package/guides/sdk-reference.json +60 -0
- package/guides/web-page-sdk-reference.md +1 -1
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +216 -8
- package/templates/beauty-salon/tier5-src/_shared/himi-store-facets.ts +26 -2
- package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -3
- package/templates/beauty-salon/tier5-src/himi-branded-lite-shop/index.ts +4 -4
- package/templates/branded-lite/dev/index.ts +216 -8
- package/templates/branded-lite/tier5-src/_shared/business-chat-transport.ts +9 -0
- package/templates/branded-lite/tier5-src/_shared/himi-store-facets.ts +26 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-shop/index.ts +3 -3
- package/templates/gym-fitness/dev/index.ts +216 -8
- package/templates/gym-fitness/tier5-src/_shared/himi-store-facets.ts +26 -2
- package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -3
- package/templates/gym-fitness/tier5-src/himi-branded-lite-shop/index.ts +4 -4
- package/templates/portfolio-creative/dev/index.ts +216 -8
- package/templates/portfolio-creative/tier5-src/_shared/himi-store-facets.ts +26 -2
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -3
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-shop/index.ts +4 -4
- package/templates/retail-store/dev/index.ts +216 -8
- package/templates/retail-store/tier5-src/_shared/himi-store-facets.ts +26 -2
- package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -3
- package/templates/retail-store/tier5-src/himi-branded-lite-shop/index.ts +3 -3
|
@@ -1180,6 +1180,66 @@
|
|
|
1180
1180
|
"jsdoc": "/** Search contacts by name (requires read permission). [] when denied/no match. */",
|
|
1181
1181
|
"decl": "export async function search(query: string, limit?: number): Promise<Contact[]>;"
|
|
1182
1182
|
},
|
|
1183
|
+
{
|
|
1184
|
+
"name": "ContactField",
|
|
1185
|
+
"kind": "interface",
|
|
1186
|
+
"jsdoc": "/** One labelled phone number or email address. `label` is free text (\"work\", \"mobile\"…);\n * each host maps the common ones to its native label and keeps the rest as a custom label. */",
|
|
1187
|
+
"decl": "export interface ContactField {\n label?: string;\n value: string;\n}"
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
"name": "NewContact",
|
|
1191
|
+
"kind": "interface",
|
|
1192
|
+
"jsdoc": "/** A contact to create. At least one of `givenName`, `familyName` or `organization` must be\n * non-blank; every list holds at most {@link MAX_CONTACT_ENTRIES} entries. */",
|
|
1193
|
+
"decl": "export interface NewContact {\n givenName?: string;\n familyName?: string;\n organization?: string;\n phones?: ContactField[];\n emails?: ContactField[];\n urls?: string[];\n note?: string;\n}"
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
"name": "MAX_CONTACT_ENTRIES",
|
|
1197
|
+
"kind": "const",
|
|
1198
|
+
"jsdoc": "/** The most entries `phones`, `emails` or `urls` may carry. */",
|
|
1199
|
+
"decl": "export const MAX_CONTACT_ENTRIES = 20;"
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
"name": "ContactsErrorCode",
|
|
1203
|
+
"kind": "type",
|
|
1204
|
+
"jsdoc": "/** Why a create verb rejected. */",
|
|
1205
|
+
"decl": "export type ContactsErrorCode = \"invalid_contact\" | \"permission_denied\" | \"unavailable\";"
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
"name": "ContactsError",
|
|
1209
|
+
"kind": "interface",
|
|
1210
|
+
"jsdoc": "/** A create-verb rejection: an `Error` named \"ContactsError\" carrying a stable `code`. (A plain\n * Error, not a subclass — Tier-5 bundles target an engine without class syntax.) Branch on\n * `isContactsError(e) && e.code === \"permission_denied\"`. */",
|
|
1211
|
+
"decl": "export interface ContactsError extends Error {\n name: \"ContactsError\";\n code: ContactsErrorCode;\n}"
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
"name": "contactsError",
|
|
1215
|
+
"kind": "function",
|
|
1216
|
+
"jsdoc": "/** Build a coded contacts rejection. */",
|
|
1217
|
+
"decl": "export function contactsError(code: ContactsErrorCode, message?: string): ContactsError;"
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
"name": "isContactsError",
|
|
1221
|
+
"kind": "function",
|
|
1222
|
+
"jsdoc": "/** Whether `e` is a coded contacts rejection. */",
|
|
1223
|
+
"decl": "export function isContactsError(e: unknown): e is ContactsError;"
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
"name": "normalizeNewContact",
|
|
1227
|
+
"kind": "function",
|
|
1228
|
+
"jsdoc": "/** Validate and normalize a {@link NewContact}: strings trimmed, blank entries dropped, blank\n * fields omitted. Throws `invalid_contact` when there is no name or organization, or a list\n * holds more than {@link MAX_CONTACT_ENTRIES} entries. Every host re-checks the same rules. */",
|
|
1229
|
+
"decl": "export function normalizeNewContact(contact: NewContact): NewContact;"
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
"name": "presentNewContact",
|
|
1233
|
+
"kind": "function",
|
|
1234
|
+
"jsdoc": "/** Open the OS new-contact sheet prefilled with `contact` — the recommended way to save a\n * contact: it needs NO contacts permission, because the user reviews and confirms the save.\n * Resolves `{ saved: true }` when the user saved it, `{ saved: false }` on cancel. Web\n * downloads a `.vcf` instead (and resolves `saved: true` once the download is handed off).\n * Rejects `invalid_contact` (see {@link normalizeNewContact}) or `unavailable`. */",
|
|
1235
|
+
"decl": "export async function presentNewContact(contact: NewContact): Promise<{ saved: boolean }>;"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
"name": "add",
|
|
1239
|
+
"kind": "function",
|
|
1240
|
+
"jsdoc": "/** Write `contact` straight into the address book and resolve its new `id`. Needs contacts\n * WRITE permission — ask with {@link requestPermission} first; without it this rejects\n * `permission_denied` (it never prompts). Rejects `invalid_contact`, or `unavailable` where\n * the host has no address book (web). Prefer {@link presentNewContact} unless the app already\n * holds the permission. */",
|
|
1241
|
+
"decl": "export async function add(contact: NewContact): Promise<{ id: string }>;"
|
|
1242
|
+
},
|
|
1183
1243
|
{
|
|
1184
1244
|
"name": "version",
|
|
1185
1245
|
"kind": "const",
|
|
@@ -23,7 +23,7 @@ the SDK sources, so it matches the shipped SDKs.
|
|
|
23
23
|
- [`calls`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fcalls?format=md) — Real-time 1:1 audio calls (Stage 1). 16 methods.
|
|
24
24
|
- [`camera`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fcamera?format=md) — Camera capability. 4 methods · returns FileHandles.
|
|
25
25
|
- [`clipboard`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fclipboard?format=md) — System clipboard. 5 methods.
|
|
26
|
-
- [`contacts`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fcontacts?format=md) — Device address book.
|
|
26
|
+
- [`contacts`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fcontacts?format=md) — Device address book. 6 methods.
|
|
27
27
|
- [`file_picker`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Ffile_picker?format=md) — User-mediated document access OUTSIDE the app sandbox. 3 methods · returns FileHandles.
|
|
28
28
|
- [`files`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Ffiles?format=md) — App-scoped document storage. 9 methods · returns FileHandles.
|
|
29
29
|
- [`godot`](https://apps.wix.com/_api/himi-serve/authoring/resource/web-sdk%2Fgodot?format=md) — A Godot game surface. 3 methods · not in Brandy.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1594.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": [
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"artifactId": "himalaya-cli"
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
-
"falconPackageHash": "
|
|
75
|
+
"falconPackageHash": "dd497985a86806681ab680998c9ccbacefeafa76497a4557b76146a4"
|
|
76
76
|
}
|
|
@@ -8991,7 +8991,33 @@ const SCREENS = runtimeSetting({
|
|
|
8991
8991
|
"top": 2,
|
|
8992
8992
|
"bottom": 2
|
|
8993
8993
|
},
|
|
8994
|
-
"hiddenPath": "$item.
|
|
8994
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
8995
|
+
}
|
|
8996
|
+
},
|
|
8997
|
+
{
|
|
8998
|
+
"id": "",
|
|
8999
|
+
"body": {
|
|
9000
|
+
"package": "himalaya",
|
|
9001
|
+
"type": "Text",
|
|
9002
|
+
"props": {
|
|
9003
|
+
"text": "$item.ribbon",
|
|
9004
|
+
"style": "caption",
|
|
9005
|
+
"color": "accentPrimary",
|
|
9006
|
+
"maxLines": 1
|
|
9007
|
+
}
|
|
9008
|
+
},
|
|
9009
|
+
"modifiers": {
|
|
9010
|
+
"background": {
|
|
9011
|
+
"token": "accentSurface"
|
|
9012
|
+
},
|
|
9013
|
+
"cornerRadius": 6,
|
|
9014
|
+
"padding": {
|
|
9015
|
+
"leading": 6,
|
|
9016
|
+
"trailing": 6,
|
|
9017
|
+
"top": 2,
|
|
9018
|
+
"bottom": 2
|
|
9019
|
+
},
|
|
9020
|
+
"hiddenPath": "$item.noRibbon"
|
|
8995
9021
|
}
|
|
8996
9022
|
},
|
|
8997
9023
|
{
|
|
@@ -9434,7 +9460,33 @@ const SCREENS = runtimeSetting({
|
|
|
9434
9460
|
"top": 2,
|
|
9435
9461
|
"bottom": 2
|
|
9436
9462
|
},
|
|
9437
|
-
"hiddenPath": "$item.
|
|
9463
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
9464
|
+
}
|
|
9465
|
+
},
|
|
9466
|
+
{
|
|
9467
|
+
"id": "",
|
|
9468
|
+
"body": {
|
|
9469
|
+
"package": "himalaya",
|
|
9470
|
+
"type": "Text",
|
|
9471
|
+
"props": {
|
|
9472
|
+
"text": "$item.ribbon",
|
|
9473
|
+
"style": "caption",
|
|
9474
|
+
"color": "accentPrimary",
|
|
9475
|
+
"maxLines": 1
|
|
9476
|
+
}
|
|
9477
|
+
},
|
|
9478
|
+
"modifiers": {
|
|
9479
|
+
"background": {
|
|
9480
|
+
"token": "accentSurface"
|
|
9481
|
+
},
|
|
9482
|
+
"cornerRadius": 6,
|
|
9483
|
+
"padding": {
|
|
9484
|
+
"leading": 6,
|
|
9485
|
+
"trailing": 6,
|
|
9486
|
+
"top": 2,
|
|
9487
|
+
"bottom": 2
|
|
9488
|
+
},
|
|
9489
|
+
"hiddenPath": "$item.noRibbon"
|
|
9438
9490
|
}
|
|
9439
9491
|
},
|
|
9440
9492
|
{
|
|
@@ -9909,7 +9961,33 @@ const SCREENS = runtimeSetting({
|
|
|
9909
9961
|
"top": 2,
|
|
9910
9962
|
"bottom": 2
|
|
9911
9963
|
},
|
|
9912
|
-
"hiddenPath": "$item.
|
|
9964
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
9965
|
+
}
|
|
9966
|
+
},
|
|
9967
|
+
{
|
|
9968
|
+
"id": "",
|
|
9969
|
+
"body": {
|
|
9970
|
+
"package": "himalaya",
|
|
9971
|
+
"type": "Text",
|
|
9972
|
+
"props": {
|
|
9973
|
+
"text": "$item.ribbon",
|
|
9974
|
+
"style": "caption",
|
|
9975
|
+
"color": "accentPrimary",
|
|
9976
|
+
"maxLines": 1
|
|
9977
|
+
}
|
|
9978
|
+
},
|
|
9979
|
+
"modifiers": {
|
|
9980
|
+
"background": {
|
|
9981
|
+
"token": "accentSurface"
|
|
9982
|
+
},
|
|
9983
|
+
"cornerRadius": 6,
|
|
9984
|
+
"padding": {
|
|
9985
|
+
"leading": 6,
|
|
9986
|
+
"trailing": 6,
|
|
9987
|
+
"top": 2,
|
|
9988
|
+
"bottom": 2
|
|
9989
|
+
},
|
|
9990
|
+
"hiddenPath": "$item.noRibbon"
|
|
9913
9991
|
}
|
|
9914
9992
|
},
|
|
9915
9993
|
{
|
|
@@ -10360,7 +10438,33 @@ const SCREENS = runtimeSetting({
|
|
|
10360
10438
|
"top": 2,
|
|
10361
10439
|
"bottom": 2
|
|
10362
10440
|
},
|
|
10363
|
-
"hiddenPath": "$item.
|
|
10441
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
10442
|
+
}
|
|
10443
|
+
},
|
|
10444
|
+
{
|
|
10445
|
+
"id": "",
|
|
10446
|
+
"body": {
|
|
10447
|
+
"package": "himalaya",
|
|
10448
|
+
"type": "Text",
|
|
10449
|
+
"props": {
|
|
10450
|
+
"text": "$item.ribbon",
|
|
10451
|
+
"style": "caption",
|
|
10452
|
+
"color": "accentPrimary",
|
|
10453
|
+
"maxLines": 1
|
|
10454
|
+
}
|
|
10455
|
+
},
|
|
10456
|
+
"modifiers": {
|
|
10457
|
+
"background": {
|
|
10458
|
+
"token": "accentSurface"
|
|
10459
|
+
},
|
|
10460
|
+
"cornerRadius": 6,
|
|
10461
|
+
"padding": {
|
|
10462
|
+
"leading": 6,
|
|
10463
|
+
"trailing": 6,
|
|
10464
|
+
"top": 2,
|
|
10465
|
+
"bottom": 2
|
|
10466
|
+
},
|
|
10467
|
+
"hiddenPath": "$item.noRibbon"
|
|
10364
10468
|
}
|
|
10365
10469
|
},
|
|
10366
10470
|
{
|
|
@@ -12990,7 +13094,33 @@ const SCREENS = runtimeSetting({
|
|
|
12990
13094
|
"top": 2,
|
|
12991
13095
|
"bottom": 2
|
|
12992
13096
|
},
|
|
12993
|
-
"hiddenPath": "$item.
|
|
13097
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
13098
|
+
}
|
|
13099
|
+
},
|
|
13100
|
+
{
|
|
13101
|
+
"id": "",
|
|
13102
|
+
"body": {
|
|
13103
|
+
"package": "himalaya",
|
|
13104
|
+
"type": "Text",
|
|
13105
|
+
"props": {
|
|
13106
|
+
"text": "$item.ribbon",
|
|
13107
|
+
"style": "caption",
|
|
13108
|
+
"color": "accentPrimary",
|
|
13109
|
+
"maxLines": 1
|
|
13110
|
+
}
|
|
13111
|
+
},
|
|
13112
|
+
"modifiers": {
|
|
13113
|
+
"background": {
|
|
13114
|
+
"token": "accentSurface"
|
|
13115
|
+
},
|
|
13116
|
+
"cornerRadius": 6,
|
|
13117
|
+
"padding": {
|
|
13118
|
+
"leading": 6,
|
|
13119
|
+
"trailing": 6,
|
|
13120
|
+
"top": 2,
|
|
13121
|
+
"bottom": 2
|
|
13122
|
+
},
|
|
13123
|
+
"hiddenPath": "$item.noRibbon"
|
|
12994
13124
|
}
|
|
12995
13125
|
},
|
|
12996
13126
|
{
|
|
@@ -13446,7 +13576,33 @@ const SCREENS = runtimeSetting({
|
|
|
13446
13576
|
"top": 2,
|
|
13447
13577
|
"bottom": 2
|
|
13448
13578
|
},
|
|
13449
|
-
"hiddenPath": "$item.
|
|
13579
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
13580
|
+
}
|
|
13581
|
+
},
|
|
13582
|
+
{
|
|
13583
|
+
"id": "",
|
|
13584
|
+
"body": {
|
|
13585
|
+
"package": "himalaya",
|
|
13586
|
+
"type": "Text",
|
|
13587
|
+
"props": {
|
|
13588
|
+
"text": "$item.ribbon",
|
|
13589
|
+
"style": "caption",
|
|
13590
|
+
"color": "accentPrimary",
|
|
13591
|
+
"maxLines": 1
|
|
13592
|
+
}
|
|
13593
|
+
},
|
|
13594
|
+
"modifiers": {
|
|
13595
|
+
"background": {
|
|
13596
|
+
"token": "accentSurface"
|
|
13597
|
+
},
|
|
13598
|
+
"cornerRadius": 6,
|
|
13599
|
+
"padding": {
|
|
13600
|
+
"leading": 6,
|
|
13601
|
+
"trailing": 6,
|
|
13602
|
+
"top": 2,
|
|
13603
|
+
"bottom": 2
|
|
13604
|
+
},
|
|
13605
|
+
"hiddenPath": "$item.noRibbon"
|
|
13450
13606
|
}
|
|
13451
13607
|
},
|
|
13452
13608
|
{
|
|
@@ -13934,7 +14090,33 @@ const SCREENS = runtimeSetting({
|
|
|
13934
14090
|
"top": 2,
|
|
13935
14091
|
"bottom": 2
|
|
13936
14092
|
},
|
|
13937
|
-
"hiddenPath": "$item.
|
|
14093
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
14094
|
+
}
|
|
14095
|
+
},
|
|
14096
|
+
{
|
|
14097
|
+
"id": "",
|
|
14098
|
+
"body": {
|
|
14099
|
+
"package": "himalaya",
|
|
14100
|
+
"type": "Text",
|
|
14101
|
+
"props": {
|
|
14102
|
+
"text": "$item.ribbon",
|
|
14103
|
+
"style": "caption",
|
|
14104
|
+
"color": "accentPrimary",
|
|
14105
|
+
"maxLines": 1
|
|
14106
|
+
}
|
|
14107
|
+
},
|
|
14108
|
+
"modifiers": {
|
|
14109
|
+
"background": {
|
|
14110
|
+
"token": "accentSurface"
|
|
14111
|
+
},
|
|
14112
|
+
"cornerRadius": 6,
|
|
14113
|
+
"padding": {
|
|
14114
|
+
"leading": 6,
|
|
14115
|
+
"trailing": 6,
|
|
14116
|
+
"top": 2,
|
|
14117
|
+
"bottom": 2
|
|
14118
|
+
},
|
|
14119
|
+
"hiddenPath": "$item.noRibbon"
|
|
13938
14120
|
}
|
|
13939
14121
|
},
|
|
13940
14122
|
{
|
|
@@ -14398,7 +14580,33 @@ const SCREENS = runtimeSetting({
|
|
|
14398
14580
|
"top": 2,
|
|
14399
14581
|
"bottom": 2
|
|
14400
14582
|
},
|
|
14401
|
-
"hiddenPath": "$item.
|
|
14583
|
+
"hiddenPath": "$item.saleTagHidden"
|
|
14584
|
+
}
|
|
14585
|
+
},
|
|
14586
|
+
{
|
|
14587
|
+
"id": "",
|
|
14588
|
+
"body": {
|
|
14589
|
+
"package": "himalaya",
|
|
14590
|
+
"type": "Text",
|
|
14591
|
+
"props": {
|
|
14592
|
+
"text": "$item.ribbon",
|
|
14593
|
+
"style": "caption",
|
|
14594
|
+
"color": "accentPrimary",
|
|
14595
|
+
"maxLines": 1
|
|
14596
|
+
}
|
|
14597
|
+
},
|
|
14598
|
+
"modifiers": {
|
|
14599
|
+
"background": {
|
|
14600
|
+
"token": "accentSurface"
|
|
14601
|
+
},
|
|
14602
|
+
"cornerRadius": 6,
|
|
14603
|
+
"padding": {
|
|
14604
|
+
"leading": 6,
|
|
14605
|
+
"trailing": 6,
|
|
14606
|
+
"top": 2,
|
|
14607
|
+
"bottom": 2
|
|
14608
|
+
},
|
|
14609
|
+
"hiddenPath": "$item.noRibbon"
|
|
14402
14610
|
}
|
|
14403
14611
|
},
|
|
14404
14612
|
{
|
|
@@ -58,8 +58,14 @@ export interface ProductCard {
|
|
|
58
58
|
swatch1: string; swatch2: string; swatch3: string; swatch4: string; swatch5: string;
|
|
59
59
|
swatch1Hidden: boolean; swatch2Hidden: boolean; swatch3Hidden: boolean; swatch4Hidden: boolean; swatch5Hidden: boolean;
|
|
60
60
|
noSwatches: boolean;
|
|
61
|
-
/** Hides the Sale tag
|
|
61
|
+
/** Hides the tag row (Sale tag, ribbon, swatches) when it has nothing to show. */
|
|
62
62
|
noTagRow: boolean;
|
|
63
|
+
/** The merchant's ribbon text ("New", "Best Seller"…), "" when the product has none. The ribbon replaces
|
|
64
|
+
* the price-derived Sale tag, so a product never carries two tags. */
|
|
65
|
+
ribbon: string;
|
|
66
|
+
noRibbon: boolean;
|
|
67
|
+
/** Hides the price-derived Sale tag: the product is not on sale, or its ribbon takes the tag's place. */
|
|
68
|
+
saleTagHidden: boolean;
|
|
63
69
|
/** The Wix price before any App Store presentation rewrites `price`. */
|
|
64
70
|
commercePrice: string;
|
|
65
71
|
/** Original Wix sale metadata retained when App Store presentation hides it. */
|
|
@@ -179,6 +185,21 @@ function swatchFields(hexes: string[], onSale: boolean) {
|
|
|
179
185
|
};
|
|
180
186
|
}
|
|
181
187
|
|
|
188
|
+
/** The ribbon the merchant set, whichever catalog answered: V3 `{ id, name }`, V1 a plain string. Read through a
|
|
189
|
+
* local type, not a `StoreProduct` member: other workers already extend that type with their own `ribbon`. */
|
|
190
|
+
export function ribbonText(p: StoreProduct): string {
|
|
191
|
+
const ribbon = (p as { ribbon?: unknown }).ribbon;
|
|
192
|
+
const name = typeof ribbon === "string" ? ribbon : typeof (ribbon as { name?: unknown } | null | undefined)?.name === "string" ? (ribbon as { name: string }).name : "";
|
|
193
|
+
return name.trim();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** What the tag row (Sale tag, ribbon, swatches) shows. One rule for every screen that rebuilds it, including
|
|
197
|
+
* after the App Store presentation changes `onSale`: the ribbon wins over the Sale tag, so a product never
|
|
198
|
+
* carries two, and the row hides when it has nothing to show. */
|
|
199
|
+
export function tagFields(onSale: boolean, noSwatches: boolean, ribbon: string | undefined) {
|
|
200
|
+
return { ribbon: ribbon ?? "", noRibbon: !ribbon, saleTagHidden: !onSale || !!ribbon, noTagRow: !onSale && noSwatches && !ribbon };
|
|
201
|
+
}
|
|
202
|
+
|
|
182
203
|
export function productCard(p: StoreProduct, saved: Set<string> = savedIds()): ProductCard {
|
|
183
204
|
const { now, was } = prices(p);
|
|
184
205
|
const groups = productOptions(p);
|
|
@@ -187,11 +208,14 @@ export function productCard(p: StoreProduct, saved: Set<string> = savedIds()): P
|
|
|
187
208
|
const image = productImage(p);
|
|
188
209
|
const id = p.id ?? "";
|
|
189
210
|
const onSale = !!was;
|
|
211
|
+
const ribbon = ribbonText(p);
|
|
212
|
+
const swatches = swatchFields((color?.choices ?? []).map((c) => c.colorCode ?? ""), onSale);
|
|
190
213
|
return {
|
|
191
214
|
id, name, image, hasImage: !!image, noImage: !image, initial: initials(name),
|
|
192
215
|
price: now, wasPrice: was, onSale, notOnSale: !onSale,
|
|
193
216
|
saved: saved.has(id), notSaved: !saved.has(id),
|
|
194
|
-
...
|
|
217
|
+
...swatches,
|
|
218
|
+
...tagFields(onSale, swatches.noSwatches, ribbon),
|
|
195
219
|
commercePrice: now,
|
|
196
220
|
detailScreenId: "himi_product",
|
|
197
221
|
};
|
|
@@ -7,7 +7,7 @@ import { searchStoreProducts, type StoreProduct } from "../_shared/himi-store.js
|
|
|
7
7
|
import { createCollectionQuery } from "../_shared/collection-query.js";
|
|
8
8
|
import { detailInputId, presence, presenceAfterError, type PresenceFlags } from "../_shared/detail-presence.js";
|
|
9
9
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
10
|
-
import { FACETS_BOOT, PAGE_SIZE, applyFacets, currencyOf, facetActions, idOf, readViewPrefs, toRows, toggleSaved, type FacetState } from "../_shared/himi-store-facets.js";
|
|
10
|
+
import { FACETS_BOOT, PAGE_SIZE, applyFacets, currencyOf, facetActions, idOf, readViewPrefs, tagFields, toRows, toggleSaved, type FacetState } from "../_shared/himi-store-facets.js";
|
|
11
11
|
import { withIapPresentation } from "../_shared/iap-presentation.js";
|
|
12
12
|
|
|
13
13
|
interface State extends FacetState, PresenceFlags {
|
|
@@ -187,8 +187,8 @@ const register = withIapPresentation<State>({
|
|
|
187
187
|
const onSale = stored.commerceOnSale ?? row.onSale;
|
|
188
188
|
return { ...row, price: price(row.id, row.commercePrice) || row.price,
|
|
189
189
|
commerceWasPrice: wasPrice, commerceOnSale: onSale,
|
|
190
|
-
...(apple(row.id) ? { wasPrice: "", onSale: false, notOnSale: true,
|
|
191
|
-
: { wasPrice, onSale, notOnSale: !onSale,
|
|
190
|
+
...(apple(row.id) ? { wasPrice: "", onSale: false, notOnSale: true, ...tagFields(false, row.noSwatches, row.ribbon) }
|
|
191
|
+
: { wasPrice, onSale, notOnSale: !onSale, ...tagFields(onSale, row.noSwatches, row.ribbon) }),
|
|
192
192
|
};
|
|
193
193
|
}) }),
|
|
194
194
|
});
|
|
@@ -16,7 +16,7 @@ import { withIapPresentation } from "../_shared/iap-presentation.js";
|
|
|
16
16
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
17
17
|
import { loadStoreCategories, type StoreCategoryCard } from "../_shared/himi-store-categories.js";
|
|
18
18
|
import {
|
|
19
|
-
FACETS_BOOT, PAGE_SIZE, applyFacets, countText, currencyOf, facetActions, idOf, option, readViewPrefs, selected, toRows, toggleSaved,
|
|
19
|
+
FACETS_BOOT, PAGE_SIZE, applyFacets, countText, currencyOf, facetActions, idOf, option, readViewPrefs, selected, tagFields, toRows, toggleSaved,
|
|
20
20
|
type FacetState, type Option, type ProductCard, type Row,
|
|
21
21
|
} from "../_shared/himi-store-facets.js";
|
|
22
22
|
|
|
@@ -187,7 +187,7 @@ function cachedCard(value: unknown): CachedCard | undefined {
|
|
|
187
187
|
price, wasPrice: "", onSale: false, notOnSale: true, saved: false, notSaved: true,
|
|
188
188
|
swatch1: "", swatch2: "", swatch3: "", swatch4: "", swatch5: "",
|
|
189
189
|
swatch1Hidden: true, swatch2Hidden: true, swatch3Hidden: true, swatch4Hidden: true, swatch5Hidden: true,
|
|
190
|
-
noSwatches: true,
|
|
190
|
+
noSwatches: true, ...tagFields(false, true, ""), commercePrice: raw.commercePrice ?? price,
|
|
191
191
|
detailScreenId: raw.detailScreenId || "himi_product", legacyCache: true,
|
|
192
192
|
};
|
|
193
193
|
}
|
|
@@ -616,7 +616,7 @@ const register = withIapPresentation<S>({
|
|
|
616
616
|
wasPrice: "",
|
|
617
617
|
onSale: false,
|
|
618
618
|
notOnSale: true,
|
|
619
|
-
|
|
619
|
+
...tagFields(false, row.noSwatches, row.ribbon),
|
|
620
620
|
};
|
|
621
621
|
return {
|
|
622
622
|
...row,
|
|
@@ -624,7 +624,7 @@ const register = withIapPresentation<S>({
|
|
|
624
624
|
wasPrice,
|
|
625
625
|
onSale,
|
|
626
626
|
notOnSale: !onSale,
|
|
627
|
-
|
|
627
|
+
...tagFields(onSale, row.noSwatches, row.ribbon),
|
|
628
628
|
};
|
|
629
629
|
}) }),
|
|
630
630
|
});
|