@wix/himalaya-cli 0.1173.0 → 0.1175.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/stdlib/wix-sdk/stores-v1/src/extensions.d.ts +13 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/products-v3.d.ts +13 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +10 -3
- package/dist/cli.mjs +66 -23
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/sdk-reference.json +15 -3
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +63 -41
- package/templates/beauty-salon-owner/dev/index.ts +172 -6
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/branded-lite/dev/index.ts +71 -47
- package/templates/community-club/dev/index.ts +63 -41
- package/templates/community-club-owner/dev/index.ts +257 -8
- package/templates/community-club-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/community-club-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/events-meetups/dev/index.ts +63 -41
- package/templates/events-meetups-owner/dev/index.ts +87 -4
- package/templates/events-meetups-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/gym-fitness/dev/index.ts +63 -41
- package/templates/gym-fitness-owner/dev/index.ts +257 -8
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/nonprofit-cause/dev/index.ts +63 -41
- package/templates/nonprofit-cause-owner/dev/index.ts +87 -4
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/owner-lite/dev/index.ts +512 -17
- package/templates/owner-lite/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/owner-lite/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/owner-lite/tier5-src/himi-owner-lite-faq-question-form/index.ts +77 -10
- package/templates/owner-lite/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/podcast-creator/dev/index.ts +63 -41
- package/templates/podcast-creator-owner/dev/index.ts +257 -8
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/portfolio-creative/dev/index.ts +63 -41
- package/templates/portfolio-creative-owner/dev/index.ts +172 -6
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/restaurant/dev/index.ts +71 -47
- package/templates/restaurant-owner/dev/index.ts +257 -8
- package/templates/restaurant-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/restaurant-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/retail-store/dev/index.ts +63 -41
- package/templates/retail-store-owner/dev/index.ts +172 -6
- package/templates/retail-store-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/retail-store-owner/tier5-src/_shared/owner-rich-guard.ts +1 -9
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +130 -27
- package/templates/yoga-studio/dev/index.ts +63 -41
- package/templates/yoga-studio-owner/dev/index.ts +87 -4
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-editor-value.ts +71 -5
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +117 -51
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post-form/index.ts +17 -42
- package/templates/events-meetups-owner/tier5-src/_shared/owner-rich-guard.ts +0 -35
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +0 -35
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +0 -35
|
@@ -76635,7 +76635,7 @@ const SCREENS = runtimeSetting({
|
|
|
76635
76635
|
"package": "himalaya",
|
|
76636
76636
|
"type": "FormField",
|
|
76637
76637
|
"props": {
|
|
76638
|
-
"id": "
|
|
76638
|
+
"id": "descriptionText",
|
|
76639
76639
|
"label": "Description",
|
|
76640
76640
|
"kind": "text",
|
|
76641
76641
|
"text": {
|
|
@@ -76648,7 +76648,90 @@ const SCREENS = runtimeSetting({
|
|
|
76648
76648
|
}
|
|
76649
76649
|
},
|
|
76650
76650
|
"modifiers": {
|
|
76651
|
-
"hiddenPath": "$service:himiOwnerLiteProductForm.
|
|
76651
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionFieldHidden"
|
|
76652
|
+
}
|
|
76653
|
+
},
|
|
76654
|
+
{
|
|
76655
|
+
"id": "product_form.description_slot",
|
|
76656
|
+
"body": {
|
|
76657
|
+
"package": "himalaya",
|
|
76658
|
+
"type": "VStack",
|
|
76659
|
+
"props": {
|
|
76660
|
+
"spacing": 6,
|
|
76661
|
+
"alignment": "leading",
|
|
76662
|
+
"children": [
|
|
76663
|
+
{
|
|
76664
|
+
"id": "",
|
|
76665
|
+
"body": {
|
|
76666
|
+
"package": "himalaya",
|
|
76667
|
+
"type": "Text",
|
|
76668
|
+
"props": {
|
|
76669
|
+
"text": "Description",
|
|
76670
|
+
"style": "bodyEmphasis"
|
|
76671
|
+
}
|
|
76672
|
+
}
|
|
76673
|
+
},
|
|
76674
|
+
{
|
|
76675
|
+
"id": "product_description_editor",
|
|
76676
|
+
"body": {
|
|
76677
|
+
"package": "himalaya",
|
|
76678
|
+
"type": "RichContentEditor",
|
|
76679
|
+
"props": {
|
|
76680
|
+
"name": "description",
|
|
76681
|
+
"documentPath": "$service:himiOwnerLiteProductForm.descriptionJson",
|
|
76682
|
+
"placeholder": "Optional",
|
|
76683
|
+
"uploadService": "himiOwnerLiteProductFormUploads",
|
|
76684
|
+
"onChange": {
|
|
76685
|
+
"actionId": "tier5.himiOwnerLiteProductForm.descriptionChanged"
|
|
76686
|
+
},
|
|
76687
|
+
"minHeight": 200,
|
|
76688
|
+
"fallback": {
|
|
76689
|
+
"id": "product_form.description_unavailable",
|
|
76690
|
+
"body": {
|
|
76691
|
+
"package": "himalaya",
|
|
76692
|
+
"type": "VStack",
|
|
76693
|
+
"props": {
|
|
76694
|
+
"spacing": 4,
|
|
76695
|
+
"alignment": "leading",
|
|
76696
|
+
"children": [
|
|
76697
|
+
{
|
|
76698
|
+
"id": "",
|
|
76699
|
+
"body": {
|
|
76700
|
+
"package": "himalaya",
|
|
76701
|
+
"type": "Text",
|
|
76702
|
+
"props": {
|
|
76703
|
+
"text": "Editor unavailable",
|
|
76704
|
+
"style": "title3"
|
|
76705
|
+
}
|
|
76706
|
+
}
|
|
76707
|
+
},
|
|
76708
|
+
{
|
|
76709
|
+
"id": "",
|
|
76710
|
+
"body": {
|
|
76711
|
+
"package": "himalaya",
|
|
76712
|
+
"type": "Text",
|
|
76713
|
+
"props": {
|
|
76714
|
+
"text": "The description can’t be edited here right now. Name, price and SKU still save, and the description stays as it is.",
|
|
76715
|
+
"style": "footnote",
|
|
76716
|
+
"color": "textSecondary"
|
|
76717
|
+
}
|
|
76718
|
+
}
|
|
76719
|
+
}
|
|
76720
|
+
]
|
|
76721
|
+
}
|
|
76722
|
+
}
|
|
76723
|
+
}
|
|
76724
|
+
}
|
|
76725
|
+
},
|
|
76726
|
+
"modifiers": {
|
|
76727
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionPending"
|
|
76728
|
+
}
|
|
76729
|
+
}
|
|
76730
|
+
]
|
|
76731
|
+
}
|
|
76732
|
+
},
|
|
76733
|
+
"modifiers": {
|
|
76734
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionEditorHidden"
|
|
76652
76735
|
}
|
|
76653
76736
|
}
|
|
76654
76737
|
],
|
|
@@ -76917,7 +77000,7 @@ const SCREENS = runtimeSetting({
|
|
|
76917
77000
|
"onChange": {
|
|
76918
77001
|
"actionId": "tier5.himiOwnerLitePostForm.bodyChanged"
|
|
76919
77002
|
},
|
|
76920
|
-
"minHeight":
|
|
77003
|
+
"minHeight": 240,
|
|
76921
77004
|
"fallback": {
|
|
76922
77005
|
"id": "post_form.body_unavailable",
|
|
76923
77006
|
"body": {
|
|
@@ -77374,7 +77457,7 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
77374
77457
|
"package": "himalaya",
|
|
77375
77458
|
"type": "FormField",
|
|
77376
77459
|
"props": {
|
|
77377
|
-
"id": "
|
|
77460
|
+
"id": "descriptionText",
|
|
77378
77461
|
"label": "Description",
|
|
77379
77462
|
"kind": "text",
|
|
77380
77463
|
"text": {
|
|
@@ -77387,7 +77470,90 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
77387
77470
|
}
|
|
77388
77471
|
},
|
|
77389
77472
|
"modifiers": {
|
|
77390
|
-
"hiddenPath": "$service:himiOwnerLiteProductForm.
|
|
77473
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionFieldHidden"
|
|
77474
|
+
}
|
|
77475
|
+
},
|
|
77476
|
+
{
|
|
77477
|
+
"id": "product_form.description_slot",
|
|
77478
|
+
"body": {
|
|
77479
|
+
"package": "himalaya",
|
|
77480
|
+
"type": "VStack",
|
|
77481
|
+
"props": {
|
|
77482
|
+
"spacing": 6,
|
|
77483
|
+
"alignment": "leading",
|
|
77484
|
+
"children": [
|
|
77485
|
+
{
|
|
77486
|
+
"id": "",
|
|
77487
|
+
"body": {
|
|
77488
|
+
"package": "himalaya",
|
|
77489
|
+
"type": "Text",
|
|
77490
|
+
"props": {
|
|
77491
|
+
"text": "Description",
|
|
77492
|
+
"style": "bodyEmphasis"
|
|
77493
|
+
}
|
|
77494
|
+
}
|
|
77495
|
+
},
|
|
77496
|
+
{
|
|
77497
|
+
"id": "product_description_editor",
|
|
77498
|
+
"body": {
|
|
77499
|
+
"package": "himalaya",
|
|
77500
|
+
"type": "RichContentEditor",
|
|
77501
|
+
"props": {
|
|
77502
|
+
"name": "description",
|
|
77503
|
+
"documentPath": "$service:himiOwnerLiteProductForm.descriptionJson",
|
|
77504
|
+
"placeholder": "Optional",
|
|
77505
|
+
"uploadService": "himiOwnerLiteProductFormUploads",
|
|
77506
|
+
"onChange": {
|
|
77507
|
+
"actionId": "tier5.himiOwnerLiteProductForm.descriptionChanged"
|
|
77508
|
+
},
|
|
77509
|
+
"minHeight": 200,
|
|
77510
|
+
"fallback": {
|
|
77511
|
+
"id": "product_form.description_unavailable",
|
|
77512
|
+
"body": {
|
|
77513
|
+
"package": "himalaya",
|
|
77514
|
+
"type": "VStack",
|
|
77515
|
+
"props": {
|
|
77516
|
+
"spacing": 4,
|
|
77517
|
+
"alignment": "leading",
|
|
77518
|
+
"children": [
|
|
77519
|
+
{
|
|
77520
|
+
"id": "",
|
|
77521
|
+
"body": {
|
|
77522
|
+
"package": "himalaya",
|
|
77523
|
+
"type": "Text",
|
|
77524
|
+
"props": {
|
|
77525
|
+
"text": "Editor unavailable",
|
|
77526
|
+
"style": "title3"
|
|
77527
|
+
}
|
|
77528
|
+
}
|
|
77529
|
+
},
|
|
77530
|
+
{
|
|
77531
|
+
"id": "",
|
|
77532
|
+
"body": {
|
|
77533
|
+
"package": "himalaya",
|
|
77534
|
+
"type": "Text",
|
|
77535
|
+
"props": {
|
|
77536
|
+
"text": "The description can’t be edited here right now. Name, price and SKU still save, and the description stays as it is.",
|
|
77537
|
+
"style": "footnote",
|
|
77538
|
+
"color": "textSecondary"
|
|
77539
|
+
}
|
|
77540
|
+
}
|
|
77541
|
+
}
|
|
77542
|
+
]
|
|
77543
|
+
}
|
|
77544
|
+
}
|
|
77545
|
+
}
|
|
77546
|
+
}
|
|
77547
|
+
},
|
|
77548
|
+
"modifiers": {
|
|
77549
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionPending"
|
|
77550
|
+
}
|
|
77551
|
+
}
|
|
77552
|
+
]
|
|
77553
|
+
}
|
|
77554
|
+
},
|
|
77555
|
+
"modifiers": {
|
|
77556
|
+
"hiddenPath": "$service:himiOwnerLiteProductForm.descriptionEditorHidden"
|
|
77391
77557
|
}
|
|
77392
77558
|
}
|
|
77393
77559
|
],
|
|
@@ -77888,7 +78054,7 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
77888
78054
|
"package": "himalaya",
|
|
77889
78055
|
"type": "FormField",
|
|
77890
78056
|
"props": {
|
|
77891
|
-
"id": "
|
|
78057
|
+
"id": "descriptionText",
|
|
77892
78058
|
"label": "Description",
|
|
77893
78059
|
"kind": "text",
|
|
77894
78060
|
"text": {
|
|
@@ -77901,7 +78067,90 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
77901
78067
|
}
|
|
77902
78068
|
},
|
|
77903
78069
|
"modifiers": {
|
|
77904
|
-
"hiddenPath": "$service:himiOwnerLiteEventForm.
|
|
78070
|
+
"hiddenPath": "$service:himiOwnerLiteEventForm.descriptionFieldHidden"
|
|
78071
|
+
}
|
|
78072
|
+
},
|
|
78073
|
+
{
|
|
78074
|
+
"id": "event_form.description_slot",
|
|
78075
|
+
"body": {
|
|
78076
|
+
"package": "himalaya",
|
|
78077
|
+
"type": "VStack",
|
|
78078
|
+
"props": {
|
|
78079
|
+
"spacing": 6,
|
|
78080
|
+
"alignment": "leading",
|
|
78081
|
+
"children": [
|
|
78082
|
+
{
|
|
78083
|
+
"id": "",
|
|
78084
|
+
"body": {
|
|
78085
|
+
"package": "himalaya",
|
|
78086
|
+
"type": "Text",
|
|
78087
|
+
"props": {
|
|
78088
|
+
"text": "Description",
|
|
78089
|
+
"style": "bodyEmphasis"
|
|
78090
|
+
}
|
|
78091
|
+
}
|
|
78092
|
+
},
|
|
78093
|
+
{
|
|
78094
|
+
"id": "event_description_editor",
|
|
78095
|
+
"body": {
|
|
78096
|
+
"package": "himalaya",
|
|
78097
|
+
"type": "RichContentEditor",
|
|
78098
|
+
"props": {
|
|
78099
|
+
"name": "description",
|
|
78100
|
+
"documentPath": "$service:himiOwnerLiteEventForm.descriptionJson",
|
|
78101
|
+
"placeholder": "Optional",
|
|
78102
|
+
"uploadService": "himiOwnerLiteEventFormUploads",
|
|
78103
|
+
"onChange": {
|
|
78104
|
+
"actionId": "tier5.himiOwnerLiteEventForm.descriptionChanged"
|
|
78105
|
+
},
|
|
78106
|
+
"minHeight": 200,
|
|
78107
|
+
"fallback": {
|
|
78108
|
+
"id": "event_form.description_unavailable",
|
|
78109
|
+
"body": {
|
|
78110
|
+
"package": "himalaya",
|
|
78111
|
+
"type": "VStack",
|
|
78112
|
+
"props": {
|
|
78113
|
+
"spacing": 4,
|
|
78114
|
+
"alignment": "leading",
|
|
78115
|
+
"children": [
|
|
78116
|
+
{
|
|
78117
|
+
"id": "",
|
|
78118
|
+
"body": {
|
|
78119
|
+
"package": "himalaya",
|
|
78120
|
+
"type": "Text",
|
|
78121
|
+
"props": {
|
|
78122
|
+
"text": "Editor unavailable",
|
|
78123
|
+
"style": "title3"
|
|
78124
|
+
}
|
|
78125
|
+
}
|
|
78126
|
+
},
|
|
78127
|
+
{
|
|
78128
|
+
"id": "",
|
|
78129
|
+
"body": {
|
|
78130
|
+
"package": "himalaya",
|
|
78131
|
+
"type": "Text",
|
|
78132
|
+
"props": {
|
|
78133
|
+
"text": "The description can’t be edited here right now. The title still saves, and the description stays as it is.",
|
|
78134
|
+
"style": "footnote",
|
|
78135
|
+
"color": "textSecondary"
|
|
78136
|
+
}
|
|
78137
|
+
}
|
|
78138
|
+
}
|
|
78139
|
+
]
|
|
78140
|
+
}
|
|
78141
|
+
}
|
|
78142
|
+
}
|
|
78143
|
+
}
|
|
78144
|
+
},
|
|
78145
|
+
"modifiers": {
|
|
78146
|
+
"hiddenPath": "$service:himiOwnerLiteEventForm.descriptionPending"
|
|
78147
|
+
}
|
|
78148
|
+
}
|
|
78149
|
+
]
|
|
78150
|
+
}
|
|
78151
|
+
},
|
|
78152
|
+
"modifiers": {
|
|
78153
|
+
"hiddenPath": "$service:himiOwnerLiteEventForm.descriptionEditorHidden"
|
|
77905
78154
|
}
|
|
77906
78155
|
}
|
|
77907
78156
|
],
|
|
@@ -78174,7 +78423,7 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
78174
78423
|
"onChange": {
|
|
78175
78424
|
"actionId": "tier5.himiOwnerLitePostForm.bodyChanged"
|
|
78176
78425
|
},
|
|
78177
|
-
"minHeight":
|
|
78426
|
+
"minHeight": 240,
|
|
78178
78427
|
"fallback": {
|
|
78179
78428
|
"id": "post_form.body_unavailable",
|
|
78180
78429
|
"body": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// drops nodes the owner never touched).
|
|
9
9
|
// Inside the platform source this import is a relative path, so node test runs resolve it; an app's
|
|
10
10
|
// copy imports "@himalaya/wix-rich-content".
|
|
11
|
-
import { parseRicosJson, RICH_CONTENT_LIMITS, type RicosDocument } from "@himalaya/wix-rich-content";
|
|
11
|
+
import { parseRicosJson, isPlainRicos, RICH_CONTENT_LIMITS, type RicosDocument } from "@himalaya/wix-rich-content";
|
|
12
12
|
|
|
13
13
|
export type EditorValue =
|
|
14
14
|
| { kind: "absent" } // leave the stored body untouched
|
|
@@ -45,12 +45,78 @@ function overLimits(doc: RicosDocument): boolean {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const TEXT_ONLY = new Set(["PARAGRAPH", "TEXT", "HEADING", "BULLETED_LIST", "ORDERED_LIST", "LIST_ITEM", "BLOCKQUOTE", "CODE_BLOCK"]);
|
|
49
|
+
/** No visible text and no non-text node (an image, a divider, an embed…): an empty body. */
|
|
50
|
+
export function isEmptyDocument(doc: RicosDocument): boolean {
|
|
51
|
+
const empty = (nodes: RicosDocument["nodes"] | undefined): boolean => (nodes ?? []).every((n) =>
|
|
52
|
+
TEXT_ONLY.has(String(n?.type)) && !String(n.textData?.text ?? "").trim() && empty(n.nodes));
|
|
53
|
+
return empty(doc.nodes);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** A Ricos JSON string checked as every viewer would: the limits first, then the shape. */
|
|
57
|
+
function checkedDocument(raw: string): EditorValue {
|
|
52
58
|
if (utf8Bytes(raw) > RICH_CONTENT_LIMITS.maxBytes) return { kind: "too_large" };
|
|
53
59
|
const doc = parseRicosJson(raw);
|
|
54
60
|
if (!doc) return { kind: "invalid" };
|
|
55
61
|
return overLimits(doc) ? { kind: "too_large" } : { kind: "doc", doc, json: raw };
|
|
56
62
|
}
|
|
63
|
+
|
|
64
|
+
/** `raw` is `values[name]`; `seededJson` is the string the form published as the editor's seed. */
|
|
65
|
+
export function editorValue(raw: unknown, seededJson: string): EditorValue {
|
|
66
|
+
if (typeof raw !== "string" || raw === "") return { kind: "absent" };
|
|
67
|
+
if (seededJson !== "" && raw === seededJson) return { kind: "unchanged" };
|
|
68
|
+
const checked = checkedDocument(raw);
|
|
69
|
+
// An empty editor over no body (a record that had none) writes nothing, rather than an empty document.
|
|
70
|
+
if (checked.kind === "doc" && seededJson === "" && isEmptyDocument(checked.doc)) return { kind: "unchanged" };
|
|
71
|
+
return checked;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── The per-field editor machinery every owner form shares (post body, event / product description,
|
|
75
|
+
// FAQ answer). Each form keeps `<key>Json` (the seed), `<key>Pending` and `<key>Dirty` in its state.
|
|
76
|
+
|
|
77
|
+
/** `<key>Pending`: until this run's load lands, the descriptor hides the editor — it seeds ONCE, so a
|
|
78
|
+
* provisional editor the owner typed into would keep that text over the real document.
|
|
79
|
+
* `<key>Dirty`: the editor's on_change fired since the field was loaded or saved. Once ready the bag
|
|
80
|
+
* ALWAYS holds a document — the engine's own re-serialization of the seed, not byte-equal to it — so
|
|
81
|
+
* only this says the owner edited the field. Every arm fires a pending on_change before it releases a
|
|
82
|
+
* Form submit, so an edit made inside the debounce window is reported before the submit reads it. */
|
|
83
|
+
export interface EditorGate { pending: boolean; dirty: boolean }
|
|
84
|
+
|
|
85
|
+
/** What a live submit does with `values[name]`: only an edit the editor reported counts. */
|
|
86
|
+
export function editorSubmitValue(raw: unknown, seededJson: string, gate: EditorGate): EditorValue {
|
|
87
|
+
return gate.pending || !gate.dirty ? { kind: "absent" } : editorValue(raw, seededJson);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A queued write's document. A replay runs in a FRESH worker with no editor, so the string is checked
|
|
91
|
+
* again (shape and limits); "absent" when the item carries none. Never "unchanged": it was an edit. */
|
|
92
|
+
export function queuedDocument(raw: unknown): EditorValue {
|
|
93
|
+
return typeof raw === "string" && raw !== "" ? checkedDocument(raw) : { kind: "absent" };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The editor's on_change: the field is now edited, and a confirmation of an earlier save is stale.
|
|
97
|
+
* No timing window: an arm fires the pending on_change BEFORE it releases a submit, so any on_change
|
|
98
|
+
* that arrives after a save carries an edit that save did not write. */
|
|
99
|
+
export function editorChanged<S extends { status: string; savedMessage: string }>(s: S): Pick<S, "status" | "savedMessage"> {
|
|
100
|
+
return { status: s.status === "saved" ? "idle" : s.status, savedMessage: "" };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The offline cache's verdict on the stored body (`<key>Protected`): rich unless KNOWN plain. From the
|
|
104
|
+
* document when the form knows it; otherwise plain only when the record was loaded as plain. A bundle
|
|
105
|
+
* rolled back past the editor reads this flag to decide whether its plain field may overwrite the body. */
|
|
106
|
+
export function cachedRichVerdict(doc: RicosDocument | null, knownPlain: boolean): "true" | "false" {
|
|
107
|
+
if (doc) return isPlainRicos(doc) ? "false" : "true";
|
|
108
|
+
return knownPlain ? "false" : "true";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Cold boot: the runtime lays this service's last persisted snapshot over its declared state, so the
|
|
112
|
+
* editor's first seed would be the document as it was when the screen last ran — and a Save after
|
|
113
|
+
* typing would write it over whatever the record holds now. Blank the hydrated seed and reset the gate
|
|
114
|
+
* before anything renders, in place (no action has run yet). `extra` resets further UI state. */
|
|
115
|
+
export function resetHydratedEditor(svc: unknown, keys: { json: string; pending: string; dirty: string }, pendingAtBoot: boolean, extra: Record<string, unknown> = {}): void {
|
|
116
|
+
const booted = (svc as { getState?: () => Record<string, unknown> | undefined }).getState?.();
|
|
117
|
+
if (!booted || typeof booted !== "object") return;
|
|
118
|
+
if (booted[keys.json]) booted[keys.json] = "";
|
|
119
|
+
booted[keys.pending] = pendingAtBoot;
|
|
120
|
+
booted[keys.dirty] = false;
|
|
121
|
+
Object.assign(booted, extra);
|
|
122
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// this file adds the read-only previews the forms show for a locked body, and the FAQ's legacy DraftJS answer.
|
|
3
3
|
// Inside the platform source this import is a relative path, so node test runs resolve it; an app's copy
|
|
4
4
|
// imports "@himalaya/wix-rich-content".
|
|
5
|
-
import { htmlIsTrivial
|
|
5
|
+
import { htmlIsTrivial } from "@himalaya/wix-rich-content";
|
|
6
6
|
|
|
7
7
|
export { htmlIsTrivial };
|
|
8
8
|
|
|
@@ -16,14 +16,6 @@ export function htmlPreviewText(html: string | null | undefined): string {
|
|
|
16
16
|
.split("\n").map((l) => l.replace(/\s+/g, " ").trim()).filter(Boolean).join("\n");
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/** True when a plain text field can round-trip this Ricos document: no document styling, and
|
|
20
|
-
* only paragraphs of undecorated text whose paragraph data is the wire default (Events v3 sends
|
|
21
|
-
* `{ textStyle: { textAlignment: "AUTO" }, indentation: 0 }` on every paragraph). Anything else —
|
|
22
|
-
* a heading, list, link, bold run, media node, alignment or indent — is rich, and so is a missing
|
|
23
|
-
* document (callers decide what an absent body means). */
|
|
24
|
-
export const ricosIsPlain = (doc: { nodes?: unknown; documentStyle?: unknown } | null | undefined): boolean =>
|
|
25
|
-
!!doc && isPlainRicos(doc);
|
|
26
|
-
|
|
27
19
|
/** Preview text for a legacy DraftJS document: its `blocks[].text` joined by a blank line, or ""
|
|
28
20
|
* when the payload is not DraftJS JSON (never a throw). */
|
|
29
21
|
export function draftjsText(raw: string | null | undefined): string {
|