@stapel/listings-react 0.7.0 → 0.8.1

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 (61) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/dist/api/generated/schema.d.ts +92 -2
  3. package/dist/api/generated/schema.d.ts.map +1 -1
  4. package/dist/default/ListingCard.d.ts +56 -0
  5. package/dist/default/ListingCard.d.ts.map +1 -1
  6. package/dist/default/ListingCard.js +92 -29
  7. package/dist/default/ListingCard.js.map +1 -1
  8. package/dist/default/ListingComposerPage.d.ts +21 -7
  9. package/dist/default/ListingComposerPage.d.ts.map +1 -1
  10. package/dist/default/ListingComposerPage.js.map +1 -1
  11. package/dist/headless/Favorites.d.ts.map +1 -1
  12. package/dist/headless/Favorites.js +19 -7
  13. package/dist/headless/Favorites.js.map +1 -1
  14. package/dist/headless/ListingDetail.d.ts.map +1 -1
  15. package/dist/headless/ListingDetail.js +7 -5
  16. package/dist/headless/ListingDetail.js.map +1 -1
  17. package/dist/headless/useMandateGate.d.ts +33 -2
  18. package/dist/headless/useMandateGate.d.ts.map +1 -1
  19. package/dist/headless/useMandateGate.js +42 -4
  20. package/dist/headless/useMandateGate.js.map +1 -1
  21. package/dist/i18n/es.d.ts.map +1 -1
  22. package/dist/i18n/es.js +2 -1
  23. package/dist/i18n/es.js.map +1 -1
  24. package/dist/i18n/generated/errors.es.gen.d.ts +1 -1
  25. package/dist/i18n/generated/errors.es.gen.js +1 -1
  26. package/dist/i18n/generated/errors.gen.d.ts +6 -0
  27. package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
  28. package/dist/i18n/generated/errors.gen.js +3 -0
  29. package/dist/i18n/generated/errors.gen.js.map +1 -1
  30. package/dist/i18n/generated/errors.ru.gen.d.ts +1 -1
  31. package/dist/i18n/generated/errors.ru.gen.js +1 -1
  32. package/dist/i18n/keys.d.ts +11 -1
  33. package/dist/i18n/keys.d.ts.map +1 -1
  34. package/dist/i18n/keys.js +12 -2
  35. package/dist/i18n/keys.js.map +1 -1
  36. package/dist/i18n/ru.d.ts.map +1 -1
  37. package/dist/i18n/ru.js +2 -1
  38. package/dist/i18n/ru.js.map +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/llms.txt +3 -3
  44. package/manifest.json +30 -21
  45. package/nav-manifest.json +1 -1
  46. package/package.json +8 -8
  47. package/src/analytics/generated/events.json +1 -1
  48. package/src/api/generated/schema.ts +92 -2
  49. package/src/default/ListingCard.tsx +233 -108
  50. package/src/default/ListingComposerPage.tsx +21 -7
  51. package/src/headless/Favorites.tsx +26 -7
  52. package/src/headless/ListingDetail.tsx +12 -5
  53. package/src/headless/useMandateGate.ts +49 -5
  54. package/src/i18n/es.ts +3 -1
  55. package/src/i18n/generated/errors.es.gen.ts +1 -1
  56. package/src/i18n/generated/errors.gen.ts +3 -0
  57. package/src/i18n/generated/errors.json +7 -0
  58. package/src/i18n/generated/errors.ru.gen.ts +1 -1
  59. package/src/i18n/keys.ts +12 -2
  60. package/src/i18n/ru.ts +3 -1
  61. package/src/index.ts +5 -1
package/manifest.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.7.0",
4
+ "version": "0.8.1",
5
5
  "backend": {
6
6
  "module": "stapel-listings",
7
- "contract": ">=0.7 <0.8"
7
+ "contract": ">=0.9 <0.10"
8
8
  },
9
9
  "layers": [
10
10
  "api",
@@ -19,119 +19,119 @@
19
19
  "listings_api_v1_listings_archive_create": {
20
20
  "method": "POST",
21
21
  "path": "/listings/api/v1/listings/{id}/archive/",
22
- "tag": "Listings",
22
+ "tag": "listings",
23
23
  "request": null,
24
24
  "response": "ListingActionResponse"
25
25
  },
26
26
  "listings_api_v1_listings_complete_create": {
27
27
  "method": "POST",
28
28
  "path": "/listings/api/v1/listings/{id}/complete/",
29
- "tag": "Listings",
29
+ "tag": "listings",
30
30
  "request": null,
31
31
  "response": "ListingActionResponse"
32
32
  },
33
33
  "listings_api_v1_listings_create": {
34
34
  "method": "POST",
35
35
  "path": "/listings/api/v1/listings/",
36
- "tag": "Listings",
36
+ "tag": "listings",
37
37
  "request": "ListingDraft",
38
38
  "response": "ListingDraft"
39
39
  },
40
40
  "listings_api_v1_listings_destroy": {
41
41
  "method": "DELETE",
42
42
  "path": "/listings/api/v1/listings/{id}/",
43
- "tag": "Listings",
43
+ "tag": "listings",
44
44
  "request": null,
45
45
  "response": "DeleteResponse"
46
46
  },
47
47
  "listings_api_v1_listings_favorite_create": {
48
48
  "method": "POST",
49
49
  "path": "/listings/api/v1/listings/{id}/favorite/",
50
- "tag": "Listings",
50
+ "tag": "listings",
51
51
  "request": null,
52
52
  "response": "FavoriteToggleResponse"
53
53
  },
54
54
  "listings_api_v1_listings_list": {
55
55
  "method": "GET",
56
56
  "path": "/listings/api/v1/listings/",
57
- "tag": "Listings",
57
+ "tag": "listings",
58
58
  "request": null,
59
59
  "response": "PaginatedListingCardList"
60
60
  },
61
61
  "listings_api_v1_listings_my_counters_retrieve": {
62
62
  "method": "GET",
63
63
  "path": "/listings/api/v1/listings/my/counters/",
64
- "tag": "Listings",
64
+ "tag": "listings",
65
65
  "request": null,
66
66
  "response": "MyCountersResponse"
67
67
  },
68
68
  "listings_api_v1_listings_my_favorites_list": {
69
69
  "method": "GET",
70
70
  "path": "/listings/api/v1/listings/my/favorites/",
71
- "tag": "Listings",
71
+ "tag": "listings",
72
72
  "request": null,
73
73
  "response": "PaginatedListingCardList"
74
74
  },
75
75
  "listings_api_v1_listings_my_listings_list": {
76
76
  "method": "GET",
77
77
  "path": "/listings/api/v1/listings/my/listings/",
78
- "tag": "Listings",
78
+ "tag": "listings",
79
79
  "request": null,
80
80
  "response": "PaginatedMyListingCardList"
81
81
  },
82
82
  "listings_api_v1_listings_partial_update": {
83
83
  "method": "PATCH",
84
84
  "path": "/listings/api/v1/listings/{id}/",
85
- "tag": "Listings",
85
+ "tag": "listings",
86
86
  "request": "PatchedListingDraft",
87
87
  "response": "ListingDraft"
88
88
  },
89
89
  "listings_api_v1_listings_publish_create": {
90
90
  "method": "POST",
91
91
  "path": "/listings/api/v1/listings/{id}/publish/",
92
- "tag": "Listings",
92
+ "tag": "listings",
93
93
  "request": null,
94
94
  "response": "PublishResponse"
95
95
  },
96
96
  "listings_api_v1_listings_retrieve": {
97
97
  "method": "GET",
98
98
  "path": "/listings/api/v1/listings/{id}/",
99
- "tag": "Listings",
99
+ "tag": "listings",
100
100
  "request": null,
101
101
  "response": "ListingDetail"
102
102
  },
103
103
  "listings_api_v1_listings_save_draft_create": {
104
104
  "method": "POST",
105
105
  "path": "/listings/api/v1/listings/{id}/save-draft/",
106
- "tag": "Listings",
106
+ "tag": "listings",
107
107
  "request": null,
108
108
  "response": "ListingDraft"
109
109
  },
110
110
  "listings_api_v1_listings_status_retrieve": {
111
111
  "method": "GET",
112
112
  "path": "/listings/api/v1/listings/{id}/status/",
113
- "tag": "Listings",
113
+ "tag": "listings",
114
114
  "request": null,
115
115
  "response": "ListingStatus"
116
116
  },
117
117
  "listings_api_v1_listings_unfavorite_create": {
118
118
  "method": "POST",
119
119
  "path": "/listings/api/v1/listings/{id}/unfavorite/",
120
- "tag": "Listings",
120
+ "tag": "listings",
121
121
  "request": null,
122
122
  "response": "FavoriteToggleResponse"
123
123
  },
124
124
  "listings_api_v1_listings_update": {
125
125
  "method": "PUT",
126
126
  "path": "/listings/api/v1/listings/{id}/",
127
- "tag": "Listings",
127
+ "tag": "listings",
128
128
  "request": "ListingDraft",
129
129
  "response": "ListingDraft"
130
130
  },
131
131
  "listings_api_v1_listings_validate_draft_retrieve": {
132
132
  "method": "GET",
133
133
  "path": "/listings/api/v1/listings/{id}/validate-draft/",
134
- "tag": "Listings",
134
+ "tag": "listings",
135
135
  "request": null,
136
136
  "response": "ValidationBatchResult"
137
137
  }
@@ -507,6 +507,11 @@
507
507
  "params": [],
508
508
  "remediation": "retry"
509
509
  },
510
+ "error.403.listing_anonymous_not_allowed": {
511
+ "status": 403,
512
+ "params": [],
513
+ "remediation": "retry"
514
+ },
510
515
  "error.403.listing_not_owner": {
511
516
  "status": 403,
512
517
  "params": [],
@@ -705,7 +710,8 @@
705
710
  "description": "The plainest place to see the load-state discipline: 'you have not saved anything yet' and 'we could not load your favourites' are two arms, not one. Merging them is the substitution that turned a 5xx into an empty result page on 2026-08-09. A visitor makes no request at all and is shown ONE state — the reason plus the door — where the pane used to render a blocked notice with a spinner turning underneath it. The pager renders only when there is a page to go to.",
706
711
  "component": "FavoritesPane",
707
712
  "covers": [
708
- "Favorites"
713
+ "Favorites",
714
+ "LISTINGS_ELEVATION_ACTIONS"
709
715
  ],
710
716
  "tokens": [
711
717
  "surface-raised"
@@ -803,6 +809,7 @@
803
809
  "error.401.unauthorized",
804
810
  "error.402.payment_required",
805
811
  "error.403.forbidden",
812
+ "error.403.listing_anonymous_not_allowed",
806
813
  "error.403.listing_not_owner",
807
814
  "error.403.network_blocked",
808
815
  "error.403.verification_enrollment_required",
@@ -838,10 +845,10 @@
838
845
  "listings.card.favorite_add",
839
846
  "listings.card.favorite_remove",
840
847
  "listings.card.no_photo",
841
- "listings.card.open",
842
848
  "listings.card.photo_unavailable",
843
849
  "listings.card.price_absent",
844
850
  "listings.card.sign_in",
851
+ "listings.card.untitled",
845
852
  "listings.compose.auto_republish",
846
853
  "listings.compose.blocked.busy",
847
854
  "listings.compose.blocked.details_unavailable",
@@ -965,6 +972,7 @@
965
972
  "EMPTY_LOCATION",
966
973
  "Favorites",
967
974
  "IMAGES_FIELD",
975
+ "LISTINGS_ELEVATION_ACTIONS",
968
976
  "LISTINGS_ERRORS",
969
977
  "LISTINGS_ERROR_CODES",
970
978
  "LISTINGS_FLOWS",
@@ -1030,6 +1038,7 @@
1030
1038
  "useCompleteListing",
1031
1039
  "useCreateDraft",
1032
1040
  "useDeleteListing",
1041
+ "useElevatableMandateGate",
1033
1042
  "useFavoriteListing",
1034
1043
  "useFavoriteToggle",
1035
1044
  "useFavorites",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/listings-react",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "entries": [
5
5
  {
6
6
  "id": "listings.detail",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/listings-react",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Headless React pair for stapel-listings: a typed client over the draft twin, the composer that turns a category schema into a submittable listing, and the owner's dashboard. Two independent axes are rendered as two — lifecycle `status` decides visibility and `moderation_status` decides nothing about it, so an edit to a live listing stays live and says 'under review' instead of vanishing. Feature values are drawn and mirrored by @stapel/attributes-react; photos arrive as an injected upload bag whose `refs` ARE `images_draft` and whose `settled` gates the submit; a publish refusal is routed onto the control that caused it by slug. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -48,9 +48,9 @@
48
48
  ],
49
49
  "size-limit": [
50
50
  {
51
- "name": "index — the headless pair (client + status axes + draft model + hooks): no antd",
51
+ "name": "index — the headless pair (client + status axes + draft model + hooks): no antd. Raised 11 -> 11.5 KB for the elevation gate (useElevatableMandateGate + core's useElevation): the anonymous arm can now mint an identity for a named action instead of refusing, and that is a state hook the gate did not previously carry",
52
52
  "path": "dist/index.js",
53
- "limit": "11 KB"
53
+ "limit": "11.5 KB"
54
54
  },
55
55
  {
56
56
  "name": "default — the antd skin (card, detail, composer, dashboard, the four named slots and the delete confirmation) must stay out of the main bundle",
@@ -70,7 +70,7 @@
70
70
  ],
71
71
  "peerDependencies": {
72
72
  "@stapel/attributes-react": ">=0.1.0",
73
- "@stapel/core": ">=0.18.1 <1.0.0",
73
+ "@stapel/core": ">=0.19.0 <1.0.0",
74
74
  "@stapel/currencies-react": ">=0.2.0",
75
75
  "@stapel/image": ">=0.2.0",
76
76
  "@stapel/tokens-antd": ">=0.7.0",
@@ -103,12 +103,12 @@
103
103
  "typescript": "^5.8.3",
104
104
  "vitest": "^3.2.4",
105
105
  "@stapel/attributes-react": "^0.3.1",
106
- "@stapel/core": "^0.18.1",
106
+ "@stapel/core": "^0.20.0",
107
107
  "@stapel/currencies-react": "^0.2.0",
108
- "@stapel/image": "^0.4.1",
108
+ "@stapel/image": "^0.4.2",
109
109
  "@stapel/showcase": "^0.3.0",
110
- "@stapel/tokens": "^0.5.1",
111
- "@stapel/tokens-antd": "^0.7.0"
110
+ "@stapel/tokens": "^0.6.0",
111
+ "@stapel/tokens-antd": "^0.8.0"
112
112
  },
113
113
  "engines": {
114
114
  "node": ">=22"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.7.0",
4
+ "version": "0.8.1",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
@@ -12,12 +12,21 @@ export interface paths {
12
12
  /**
13
13
  * @description Listings CRUD plus owner lifecycle actions and favorites.
14
14
  *
15
+ * Read and write live in one class, so the guest wall
16
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
17
+ * is applied per ACTION and never as a class permission: an anonymous
18
+ * session must keep browsing and keep its favorites, and only the
19
+ * authorship actions — ``create``, ``update``/``partial_update``,
20
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
21
+ * seller.
22
+ *
15
23
  * **Permissions:** `IsAuthenticatedOrReadOnly`
16
24
  */
17
25
  get: operations["listings_api_v1_listings_list"];
18
26
  put?: never;
19
27
  /**
20
- * @description Listings CRUD plus owner lifecycle actions and favorites.
28
+ * @description Open a draft the first act of becoming a seller, so the guest
29
+ * wall stands here and not only at ``publish``.
21
30
  *
22
31
  * **Permissions:** `IsAuthenticatedOrReadOnly`
23
32
  */
@@ -38,6 +47,14 @@ export interface paths {
38
47
  /**
39
48
  * @description Listings CRUD plus owner lifecycle actions and favorites.
40
49
  *
50
+ * Read and write live in one class, so the guest wall
51
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
52
+ * is applied per ACTION and never as a class permission: an anonymous
53
+ * session must keep browsing and keep its favorites, and only the
54
+ * authorship actions — ``create``, ``update``/``partial_update``,
55
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
56
+ * seller.
57
+ *
41
58
  * **Permissions:** `IsAuthenticatedOrReadOnly`
42
59
  */
43
60
  get: operations["listings_api_v1_listings_retrieve"];
@@ -53,6 +70,14 @@ export interface paths {
53
70
  /**
54
71
  * @description Listings CRUD plus owner lifecycle actions and favorites.
55
72
  *
73
+ * Read and write live in one class, so the guest wall
74
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
75
+ * is applied per ACTION and never as a class permission: an anonymous
76
+ * session must keep browsing and keep its favorites, and only the
77
+ * authorship actions — ``create``, ``update``/``partial_update``,
78
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
79
+ * seller.
80
+ *
56
81
  * **Permissions:** `IsAuthenticatedOrReadOnly`
57
82
  */
58
83
  delete: operations["listings_api_v1_listings_destroy"];
@@ -61,6 +86,14 @@ export interface paths {
61
86
  /**
62
87
  * @description Listings CRUD plus owner lifecycle actions and favorites.
63
88
  *
89
+ * Read and write live in one class, so the guest wall
90
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
91
+ * is applied per ACTION and never as a class permission: an anonymous
92
+ * session must keep browsing and keep its favorites, and only the
93
+ * authorship actions — ``create``, ``update``/``partial_update``,
94
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
95
+ * seller.
96
+ *
64
97
  * **Permissions:** `IsAuthenticatedOrReadOnly`
65
98
  */
66
99
  patch: operations["listings_api_v1_listings_partial_update"];
@@ -78,6 +111,14 @@ export interface paths {
78
111
  /**
79
112
  * @description Listings CRUD plus owner lifecycle actions and favorites.
80
113
  *
114
+ * Read and write live in one class, so the guest wall
115
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
116
+ * is applied per ACTION and never as a class permission: an anonymous
117
+ * session must keep browsing and keep its favorites, and only the
118
+ * authorship actions — ``create``, ``update``/``partial_update``,
119
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
120
+ * seller.
121
+ *
81
122
  * **Permissions:** `IsAuthenticated`
82
123
  */
83
124
  post: operations["listings_api_v1_listings_archive_create"];
@@ -120,6 +161,14 @@ export interface paths {
120
161
  /**
121
162
  * @description Listings CRUD plus owner lifecycle actions and favorites.
122
163
  *
164
+ * Read and write live in one class, so the guest wall
165
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
166
+ * is applied per ACTION and never as a class permission: an anonymous
167
+ * session must keep browsing and keep its favorites, and only the
168
+ * authorship actions — ``create``, ``update``/``partial_update``,
169
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
170
+ * seller.
171
+ *
123
172
  * **Permissions:** `IsAuthenticated`
124
173
  */
125
174
  post: operations["listings_api_v1_listings_favorite_create"];
@@ -139,7 +188,8 @@ export interface paths {
139
188
  get?: never;
140
189
  put?: never;
141
190
  /**
142
- * @description Listings CRUD plus owner lifecycle actions and favorites.
191
+ * @description Put a listing in front of buyers — the act the wall is named for:
192
+ * a seller nobody can reach again is not a seller.
143
193
  *
144
194
  * **Permissions:** `IsAuthenticated`
145
195
  */
@@ -181,6 +231,14 @@ export interface paths {
181
231
  /**
182
232
  * @description Listings CRUD plus owner lifecycle actions and favorites.
183
233
  *
234
+ * Read and write live in one class, so the guest wall
235
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
236
+ * is applied per ACTION and never as a class permission: an anonymous
237
+ * session must keep browsing and keep its favorites, and only the
238
+ * authorship actions — ``create``, ``update``/``partial_update``,
239
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
240
+ * seller.
241
+ *
184
242
  * **Permissions:** `AllowAny`
185
243
  */
186
244
  get: operations["listings_api_v1_listings_status_retrieve"];
@@ -204,6 +262,14 @@ export interface paths {
204
262
  /**
205
263
  * @description Listings CRUD plus owner lifecycle actions and favorites.
206
264
  *
265
+ * Read and write live in one class, so the guest wall
266
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
267
+ * is applied per ACTION and never as a class permission: an anonymous
268
+ * session must keep browsing and keep its favorites, and only the
269
+ * authorship actions — ``create``, ``update``/``partial_update``,
270
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
271
+ * seller.
272
+ *
207
273
  * **Permissions:** `IsAuthenticated`
208
274
  */
209
275
  post: operations["listings_api_v1_listings_unfavorite_create"];
@@ -223,6 +289,14 @@ export interface paths {
223
289
  /**
224
290
  * @description Listings CRUD plus owner lifecycle actions and favorites.
225
291
  *
292
+ * Read and write live in one class, so the guest wall
293
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
294
+ * is applied per ACTION and never as a class permission: an anonymous
295
+ * session must keep browsing and keep its favorites, and only the
296
+ * authorship actions — ``create``, ``update``/``partial_update``,
297
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
298
+ * seller.
299
+ *
226
300
  * **Permissions:** `IsAuthenticated`
227
301
  */
228
302
  get: operations["listings_api_v1_listings_validate_draft_retrieve"];
@@ -244,6 +318,14 @@ export interface paths {
244
318
  /**
245
319
  * @description Listings CRUD plus owner lifecycle actions and favorites.
246
320
  *
321
+ * Read and write live in one class, so the guest wall
322
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
323
+ * is applied per ACTION and never as a class permission: an anonymous
324
+ * session must keep browsing and keep its favorites, and only the
325
+ * authorship actions — ``create``, ``update``/``partial_update``,
326
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
327
+ * seller.
328
+ *
247
329
  * **Permissions:** `IsAuthenticated`
248
330
  */
249
331
  get: operations["listings_api_v1_listings_my_counters_retrieve"];
@@ -265,6 +347,14 @@ export interface paths {
265
347
  /**
266
348
  * @description Listings CRUD plus owner lifecycle actions and favorites.
267
349
  *
350
+ * Read and write live in one class, so the guest wall
351
+ * (:func:`anonymous_write_refusal`, the ``ALLOW_ANONYMOUS_WRITES`` switch)
352
+ * is applied per ACTION and never as a class permission: an anonymous
353
+ * session must keep browsing and keep its favorites, and only the
354
+ * authorship actions — ``create``, ``update``/``partial_update``,
355
+ * ``save-draft``, ``publish`` — are the ones that turn a caller into a
356
+ * seller.
357
+ *
268
358
  * **Permissions:** `IsAuthenticated`
269
359
  */
270
360
  get: operations["listings_api_v1_listings_my_favorites_list"];