@stapel/reviews-react 0.1.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/CHANGELOG.md +1 -0
- package/MODULE.md +151 -0
- package/README.md +207 -0
- package/dist/api/generated/schema.d.ts +360 -0
- package/dist/api/generated/schema.d.ts.map +1 -0
- package/dist/api/generated/schema.js +2 -0
- package/dist/api/generated/schema.js.map +1 -0
- package/dist/api/reviewsApi.d.ts +89 -0
- package/dist/api/reviewsApi.d.ts.map +1 -0
- package/dist/api/reviewsApi.js +51 -0
- package/dist/api/reviewsApi.js.map +1 -0
- package/dist/api/types.d.ts +127 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/default/ErrorAlert.d.ts +9 -0
- package/dist/default/ErrorAlert.d.ts.map +1 -0
- package/dist/default/ErrorAlert.js +27 -0
- package/dist/default/ErrorAlert.js.map +1 -0
- package/dist/default/RatingBadge.d.ts +17 -0
- package/dist/default/RatingBadge.d.ts.map +1 -0
- package/dist/default/RatingBadge.js +23 -0
- package/dist/default/RatingBadge.js.map +1 -0
- package/dist/default/ReviewFormCard.d.ts +25 -0
- package/dist/default/ReviewFormCard.d.ts.map +1 -0
- package/dist/default/ReviewFormCard.js +42 -0
- package/dist/default/ReviewFormCard.js.map +1 -0
- package/dist/default/ReviewListPanel.d.ts +29 -0
- package/dist/default/ReviewListPanel.d.ts.map +1 -0
- package/dist/default/ReviewListPanel.js +47 -0
- package/dist/default/ReviewListPanel.js.map +1 -0
- package/dist/default/ReviewsPanel.d.ts +33 -0
- package/dist/default/ReviewsPanel.d.ts.map +1 -0
- package/dist/default/ReviewsPanel.js +17 -0
- package/dist/default/ReviewsPanel.js.map +1 -0
- package/dist/default/index.d.ts +31 -0
- package/dist/default/index.d.ts.map +1 -0
- package/dist/default/index.js +25 -0
- package/dist/default/index.js.map +1 -0
- package/dist/default/theme.d.ts +24 -0
- package/dist/default/theme.d.ts.map +1 -0
- package/dist/default/theme.js +39 -0
- package/dist/default/theme.js.map +1 -0
- package/dist/default/types.d.ts +12 -0
- package/dist/default/types.d.ts.map +1 -0
- package/dist/default/types.js +2 -0
- package/dist/default/types.js.map +1 -0
- package/dist/headless/ReviewAggregate.d.ts +63 -0
- package/dist/headless/ReviewAggregate.d.ts.map +1 -0
- package/dist/headless/ReviewAggregate.js +55 -0
- package/dist/headless/ReviewAggregate.js.map +1 -0
- package/dist/headless/ReviewForm.d.ts +83 -0
- package/dist/headless/ReviewForm.d.ts.map +1 -0
- package/dist/headless/ReviewForm.js +75 -0
- package/dist/headless/ReviewForm.js.map +1 -0
- package/dist/headless/ReviewList.d.ts +47 -0
- package/dist/headless/ReviewList.d.ts.map +1 -0
- package/dist/headless/ReviewList.js +51 -0
- package/dist/headless/ReviewList.js.map +1 -0
- package/dist/headless/ReviewsProvider.d.ts +19 -0
- package/dist/headless/ReviewsProvider.d.ts.map +1 -0
- package/dist/headless/ReviewsProvider.js +15 -0
- package/dist/headless/ReviewsProvider.js.map +1 -0
- package/dist/i18n/errorsMap.d.ts +12 -0
- package/dist/i18n/errorsMap.d.ts.map +1 -0
- package/dist/i18n/errorsMap.js +22 -0
- package/dist/i18n/errorsMap.js.map +1 -0
- package/dist/i18n/es.d.ts +19 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +66 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/generated/errors.es.gen.d.ts +16 -0
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.es.gen.js +58 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -0
- package/dist/i18n/generated/errors.gen.d.ts +341 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.gen.js +174 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts +16 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.js +58 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -0
- package/dist/i18n/keys.d.ts +59 -0
- package/dist/i18n/keys.d.ts.map +1 -0
- package/dist/i18n/keys.js +115 -0
- package/dist/i18n/keys.js.map +1 -0
- package/dist/i18n/ru.d.ts +22 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +70 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/model/context.d.ts +11 -0
- package/dist/model/context.d.ts.map +1 -0
- package/dist/model/context.js +16 -0
- package/dist/model/context.js.map +1 -0
- package/dist/model/list.d.ts +52 -0
- package/dist/model/list.d.ts.map +1 -0
- package/dist/model/list.js +60 -0
- package/dist/model/list.js.map +1 -0
- package/dist/model/mutations.d.ts +32 -0
- package/dist/model/mutations.d.ts.map +1 -0
- package/dist/model/mutations.js +44 -0
- package/dist/model/mutations.js.map +1 -0
- package/dist/model/queries.d.ts +65 -0
- package/dist/model/queries.d.ts.map +1 -0
- package/dist/model/queries.js +80 -0
- package/dist/model/queries.js.map +1 -0
- package/dist/model/queryKeys.d.ts +27 -0
- package/dist/model/queryKeys.d.ts.map +1 -0
- package/dist/model/queryKeys.js +14 -0
- package/dist/model/queryKeys.js.map +1 -0
- package/dist/model/rating.d.ts +57 -0
- package/dist/model/rating.d.ts.map +1 -0
- package/dist/model/rating.js +47 -0
- package/dist/model/rating.js.map +1 -0
- package/dist/model/refusals.d.ts +51 -0
- package/dist/model/refusals.d.ts.map +1 -0
- package/dist/model/refusals.js +103 -0
- package/dist/model/refusals.js.map +1 -0
- package/dist/model/runtime.d.ts +44 -0
- package/dist/model/runtime.d.ts.map +1 -0
- package/dist/model/runtime.js +15 -0
- package/dist/model/runtime.js.map +1 -0
- package/llms.txt +80 -0
- package/manifest.json +577 -0
- package/package.json +115 -0
- package/src/analytics/generated/events.json +7 -0
- package/src/api/generated/schema.ts +362 -0
- package/src/api/reviewsApi.ts +170 -0
- package/src/api/types.ts +140 -0
- package/src/default/ErrorAlert.tsx +46 -0
- package/src/default/RatingBadge.tsx +81 -0
- package/src/default/ReviewFormCard.tsx +139 -0
- package/src/default/ReviewListPanel.tsx +204 -0
- package/src/default/ReviewsPanel.tsx +74 -0
- package/src/default/index.ts +30 -0
- package/src/default/theme.tsx +66 -0
- package/src/default/types.ts +12 -0
- package/src/headless/ReviewAggregate.tsx +94 -0
- package/src/headless/ReviewForm.tsx +163 -0
- package/src/headless/ReviewList.tsx +99 -0
- package/src/headless/ReviewsProvider.tsx +20 -0
- package/src/i18n/errorsMap.ts +33 -0
- package/src/i18n/es.ts +81 -0
- package/src/i18n/generated/errors.es.gen.ts +64 -0
- package/src/i18n/generated/errors.gen.ts +205 -0
- package/src/i18n/generated/errors.json +387 -0
- package/src/i18n/generated/errors.ru.gen.ts +64 -0
- package/src/i18n/keys.ts +133 -0
- package/src/i18n/ru.ts +85 -0
- package/src/index.ts +161 -0
- package/src/model/context.tsx +28 -0
- package/src/model/list.ts +74 -0
- package/src/model/mutations.ts +62 -0
- package/src/model/queries.ts +122 -0
- package/src/model/queryKeys.ts +45 -0
- package/src/model/rating.ts +101 -0
- package/src/model/refusals.ts +114 -0
- package/src/model/runtime.ts +61 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
export interface paths {
|
|
2
|
+
"/reviews/api/v1/reviews": {
|
|
3
|
+
parameters: {
|
|
4
|
+
query?: never;
|
|
5
|
+
header?: never;
|
|
6
|
+
path?: never;
|
|
7
|
+
cookie?: never;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @description List a target's reviews (anchor-paginated, published-only for
|
|
11
|
+
* non-moderators), or create a review.
|
|
12
|
+
*
|
|
13
|
+
* ``GET`` is anonymously readable (storefront F5 verdict,
|
|
14
|
+
* darom-storefront-design.md §13.8 note 2) — published-only filtering
|
|
15
|
+
* already guarantees a guest sees nothing a moderator would need to hide.
|
|
16
|
+
* ``POST`` still requires a real identity (there is an author to attribute
|
|
17
|
+
* the review to), so the class gate is DRF's own
|
|
18
|
+
* ``IsAuthenticatedOrReadOnly`` (mirrors ``ListingViewSet`` in
|
|
19
|
+
* stapel-listings — the fleet's other read-open/write-authenticated view in
|
|
20
|
+
* a single class) rather than a per-method override.
|
|
21
|
+
*
|
|
22
|
+
* **Permissions:** `IsAuthenticatedOrReadOnly`
|
|
23
|
+
*/
|
|
24
|
+
get: operations["reviews_api_v1_reviews_retrieve"];
|
|
25
|
+
put?: never;
|
|
26
|
+
/**
|
|
27
|
+
* @description List a target's reviews (anchor-paginated, published-only for
|
|
28
|
+
* non-moderators), or create a review.
|
|
29
|
+
*
|
|
30
|
+
* ``GET`` is anonymously readable (storefront F5 verdict,
|
|
31
|
+
* darom-storefront-design.md §13.8 note 2) — published-only filtering
|
|
32
|
+
* already guarantees a guest sees nothing a moderator would need to hide.
|
|
33
|
+
* ``POST`` still requires a real identity (there is an author to attribute
|
|
34
|
+
* the review to), so the class gate is DRF's own
|
|
35
|
+
* ``IsAuthenticatedOrReadOnly`` (mirrors ``ListingViewSet`` in
|
|
36
|
+
* stapel-listings — the fleet's other read-open/write-authenticated view in
|
|
37
|
+
* a single class) rather than a per-method override.
|
|
38
|
+
*
|
|
39
|
+
* **Permissions:** `IsAuthenticatedOrReadOnly`
|
|
40
|
+
*/
|
|
41
|
+
post: operations["reviews_api_v1_reviews_create"];
|
|
42
|
+
delete?: never;
|
|
43
|
+
options?: never;
|
|
44
|
+
head?: never;
|
|
45
|
+
patch?: never;
|
|
46
|
+
trace?: never;
|
|
47
|
+
};
|
|
48
|
+
"/reviews/api/v1/reviews/{review_id}/moderate": {
|
|
49
|
+
parameters: {
|
|
50
|
+
query?: never;
|
|
51
|
+
header?: never;
|
|
52
|
+
path?: never;
|
|
53
|
+
cookie?: never;
|
|
54
|
+
};
|
|
55
|
+
get?: never;
|
|
56
|
+
put?: never;
|
|
57
|
+
/**
|
|
58
|
+
* @description Hide or publish a review (moderation; owner/moderator-only via the
|
|
59
|
+
* target type's can_moderate callback).
|
|
60
|
+
*
|
|
61
|
+
* **Permissions:** `IsAuthenticated`
|
|
62
|
+
*/
|
|
63
|
+
post: operations["reviews_api_v1_reviews_moderate_create"];
|
|
64
|
+
delete?: never;
|
|
65
|
+
options?: never;
|
|
66
|
+
head?: never;
|
|
67
|
+
patch?: never;
|
|
68
|
+
trace?: never;
|
|
69
|
+
};
|
|
70
|
+
"/reviews/api/v1/reviews/{review_id}/response": {
|
|
71
|
+
parameters: {
|
|
72
|
+
query?: never;
|
|
73
|
+
header?: never;
|
|
74
|
+
path?: never;
|
|
75
|
+
cookie?: never;
|
|
76
|
+
};
|
|
77
|
+
get?: never;
|
|
78
|
+
put?: never;
|
|
79
|
+
/**
|
|
80
|
+
* @description Attach the target owner's single reply to a review (owner-only via the
|
|
81
|
+
* target type's can_moderate callback; gated by the allow_response policy).
|
|
82
|
+
*
|
|
83
|
+
* **Permissions:** `IsAuthenticated`
|
|
84
|
+
*/
|
|
85
|
+
post: operations["reviews_api_v1_reviews_response_create"];
|
|
86
|
+
delete?: never;
|
|
87
|
+
options?: never;
|
|
88
|
+
head?: never;
|
|
89
|
+
patch?: never;
|
|
90
|
+
trace?: never;
|
|
91
|
+
};
|
|
92
|
+
"/reviews/api/v1/reviews/aggregate": {
|
|
93
|
+
parameters: {
|
|
94
|
+
query?: never;
|
|
95
|
+
header?: never;
|
|
96
|
+
path?: never;
|
|
97
|
+
cookie?: never;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* @description The module-owned rating aggregate (avg/count over published reviews)
|
|
101
|
+
* for a target.
|
|
102
|
+
*
|
|
103
|
+
* Anonymously readable for the same reason as the list's ``GET``
|
|
104
|
+
* (storefront F5 verdict, darom-storefront-design.md §13.8 note 2): the
|
|
105
|
+
* aggregate is computed over published reviews only, so a guest learns
|
|
106
|
+
* nothing a moderator would need withheld.
|
|
107
|
+
*
|
|
108
|
+
* **Permissions:** `AllowAny`
|
|
109
|
+
*/
|
|
110
|
+
get: operations["reviews_api_v1_reviews_aggregate_retrieve"];
|
|
111
|
+
put?: never;
|
|
112
|
+
post?: never;
|
|
113
|
+
delete?: never;
|
|
114
|
+
options?: never;
|
|
115
|
+
head?: never;
|
|
116
|
+
patch?: never;
|
|
117
|
+
trace?: never;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export type webhooks = Record<string, never>;
|
|
121
|
+
export interface components {
|
|
122
|
+
schemas: {
|
|
123
|
+
/** @description Rating aggregate for a target over published reviews. */
|
|
124
|
+
AggregateResponse: {
|
|
125
|
+
/** @description The host-registered target-type key */
|
|
126
|
+
target_type: string;
|
|
127
|
+
/** @description Opaque host-owned target identifier */
|
|
128
|
+
target_key: string;
|
|
129
|
+
/**
|
|
130
|
+
* Format: double
|
|
131
|
+
* @description Mean rating (0.0 when count is 0)
|
|
132
|
+
*/
|
|
133
|
+
avg: number;
|
|
134
|
+
/** @description Number of published reviews */
|
|
135
|
+
count: number;
|
|
136
|
+
};
|
|
137
|
+
/** @description Moderate a review. */
|
|
138
|
+
ModerateRequest: {
|
|
139
|
+
/** @description hide or publish */
|
|
140
|
+
action: string;
|
|
141
|
+
/** @description Optional moderation reason (carried in the emitted fact) */
|
|
142
|
+
reason?: string;
|
|
143
|
+
};
|
|
144
|
+
/** @description Attach the target owner's reply to a review. */
|
|
145
|
+
RespondRequest: {
|
|
146
|
+
/** @description Reply text */
|
|
147
|
+
body?: string;
|
|
148
|
+
};
|
|
149
|
+
/** @description A target owner's reply to a review. */
|
|
150
|
+
ResponseResponse: {
|
|
151
|
+
/** @description The responder's user id (the target owner) */
|
|
152
|
+
author_id: string;
|
|
153
|
+
/** @description Reply text */
|
|
154
|
+
body: string;
|
|
155
|
+
/**
|
|
156
|
+
* Format: date-time
|
|
157
|
+
* @description When the reply was written
|
|
158
|
+
*/
|
|
159
|
+
created_at: string;
|
|
160
|
+
};
|
|
161
|
+
/** @description Create a review. */
|
|
162
|
+
ReviewCreateRequest: {
|
|
163
|
+
/** @description The host-registered target-type key */
|
|
164
|
+
target_type: string;
|
|
165
|
+
/** @description Opaque host-owned target identifier */
|
|
166
|
+
target_key: string;
|
|
167
|
+
/** @description Numeric rating (RATING_MIN..RATING_MAX) */
|
|
168
|
+
rating: number;
|
|
169
|
+
/** @description Optional review body */
|
|
170
|
+
body?: string;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* @description The envelope ``GET /reviews`` actually returns — ``AnchorPagination``'s
|
|
174
|
+
* keys (``stapel_core.django.api.pagination.AnchorPagination.
|
|
175
|
+
* get_paginated_response``/``get_paginated_response_schema``) wrapping
|
|
176
|
+
* ``items``. Schema-only: ``ReviewListCreateView`` is a bare ``APIView``
|
|
177
|
+
* (views.py), so drf-spectacular's pagination auto-introspection — which
|
|
178
|
+
* only fires for ``GenericAPIView.pagination_class`` — never sees
|
|
179
|
+
* ``ReviewAnchorPagination``, and the envelope has to be declared by hand
|
|
180
|
+
* or spectacular renders the response as a bare array
|
|
181
|
+
* (darom-storefront-design.md §13.8 note 3).
|
|
182
|
+
*/
|
|
183
|
+
ReviewPage: {
|
|
184
|
+
items: components["schemas"]["ReviewResponse"][];
|
|
185
|
+
next_anchor: string | null;
|
|
186
|
+
prev_anchor: string | null;
|
|
187
|
+
has_next: boolean;
|
|
188
|
+
has_prev: boolean;
|
|
189
|
+
count: number;
|
|
190
|
+
};
|
|
191
|
+
/** @description A review of an opaque target. */
|
|
192
|
+
ReviewResponse: {
|
|
193
|
+
/** @description Review id (UUID) */
|
|
194
|
+
id: string;
|
|
195
|
+
/** @description The host-registered target-type key */
|
|
196
|
+
target_type: string;
|
|
197
|
+
/** @description Opaque host-owned target identifier */
|
|
198
|
+
target_key: string;
|
|
199
|
+
/** @description Reviewer's user id */
|
|
200
|
+
author_id: string;
|
|
201
|
+
/** @description Numeric rating (RATING_MIN..RATING_MAX) */
|
|
202
|
+
rating: number;
|
|
203
|
+
/** @description Free-text review body */
|
|
204
|
+
body: string;
|
|
205
|
+
/** @description pending/published/hidden */
|
|
206
|
+
status: string;
|
|
207
|
+
/**
|
|
208
|
+
* Format: date-time
|
|
209
|
+
* @description Creation time
|
|
210
|
+
*/
|
|
211
|
+
created_at: string;
|
|
212
|
+
/** @description The owner's reply, if any */
|
|
213
|
+
response?: components["schemas"]["ResponseResponse"] | null;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
responses: never;
|
|
217
|
+
parameters: never;
|
|
218
|
+
requestBodies: never;
|
|
219
|
+
headers: never;
|
|
220
|
+
pathItems: never;
|
|
221
|
+
}
|
|
222
|
+
export type $defs = Record<string, never>;
|
|
223
|
+
export interface operations {
|
|
224
|
+
reviews_api_v1_reviews_retrieve: {
|
|
225
|
+
parameters: {
|
|
226
|
+
query: {
|
|
227
|
+
/** @description Opaque cursor: a `next_anchor`/`prev_anchor` from a previous page (the review's `created_at`). Omit for the first page. */
|
|
228
|
+
anchor?: string;
|
|
229
|
+
/** @description Which side of `anchor` to page toward. Default `next`. */
|
|
230
|
+
direction?: "center" | "next" | "prev";
|
|
231
|
+
/** @description Omit for published-only. `all` additionally asks for pending/hidden reviews, but is honored only for a moderator/owner of the target (the type's can_moderate callback) — a non-moderator asking for `all` is silently narrowed to published, never an error. */
|
|
232
|
+
include?: string;
|
|
233
|
+
/** @description Page size, default 20, max 100. */
|
|
234
|
+
limit?: number;
|
|
235
|
+
/** @description Opaque host-owned target identifier. */
|
|
236
|
+
target_key: string;
|
|
237
|
+
/** @description Host-registered target-type key (registry.py). */
|
|
238
|
+
target_type: string;
|
|
239
|
+
};
|
|
240
|
+
header?: never;
|
|
241
|
+
path?: never;
|
|
242
|
+
cookie?: never;
|
|
243
|
+
};
|
|
244
|
+
requestBody?: never;
|
|
245
|
+
responses: {
|
|
246
|
+
200: {
|
|
247
|
+
headers: {
|
|
248
|
+
[name: string]: unknown;
|
|
249
|
+
};
|
|
250
|
+
content: {
|
|
251
|
+
"application/json": components["schemas"]["ReviewPage"];
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
reviews_api_v1_reviews_create: {
|
|
257
|
+
parameters: {
|
|
258
|
+
query?: never;
|
|
259
|
+
header?: never;
|
|
260
|
+
path?: never;
|
|
261
|
+
cookie?: never;
|
|
262
|
+
};
|
|
263
|
+
requestBody: {
|
|
264
|
+
content: {
|
|
265
|
+
"application/json": components["schemas"]["ReviewCreateRequest"];
|
|
266
|
+
"application/x-www-form-urlencoded": components["schemas"]["ReviewCreateRequest"];
|
|
267
|
+
"multipart/form-data": components["schemas"]["ReviewCreateRequest"];
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
responses: {
|
|
271
|
+
201: {
|
|
272
|
+
headers: {
|
|
273
|
+
[name: string]: unknown;
|
|
274
|
+
};
|
|
275
|
+
content: {
|
|
276
|
+
"application/json": components["schemas"]["ReviewResponse"];
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
reviews_api_v1_reviews_moderate_create: {
|
|
282
|
+
parameters: {
|
|
283
|
+
query?: never;
|
|
284
|
+
header?: never;
|
|
285
|
+
path: {
|
|
286
|
+
review_id: string;
|
|
287
|
+
};
|
|
288
|
+
cookie?: never;
|
|
289
|
+
};
|
|
290
|
+
requestBody: {
|
|
291
|
+
content: {
|
|
292
|
+
"application/json": components["schemas"]["ModerateRequest"];
|
|
293
|
+
"application/x-www-form-urlencoded": components["schemas"]["ModerateRequest"];
|
|
294
|
+
"multipart/form-data": components["schemas"]["ModerateRequest"];
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
responses: {
|
|
298
|
+
200: {
|
|
299
|
+
headers: {
|
|
300
|
+
[name: string]: unknown;
|
|
301
|
+
};
|
|
302
|
+
content: {
|
|
303
|
+
"application/json": components["schemas"]["ReviewResponse"];
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
reviews_api_v1_reviews_response_create: {
|
|
309
|
+
parameters: {
|
|
310
|
+
query?: never;
|
|
311
|
+
header?: never;
|
|
312
|
+
path: {
|
|
313
|
+
review_id: string;
|
|
314
|
+
};
|
|
315
|
+
cookie?: never;
|
|
316
|
+
};
|
|
317
|
+
requestBody?: {
|
|
318
|
+
content: {
|
|
319
|
+
"application/json": components["schemas"]["RespondRequest"];
|
|
320
|
+
"application/x-www-form-urlencoded": components["schemas"]["RespondRequest"];
|
|
321
|
+
"multipart/form-data": components["schemas"]["RespondRequest"];
|
|
322
|
+
};
|
|
323
|
+
};
|
|
324
|
+
responses: {
|
|
325
|
+
201: {
|
|
326
|
+
headers: {
|
|
327
|
+
[name: string]: unknown;
|
|
328
|
+
};
|
|
329
|
+
content: {
|
|
330
|
+
"application/json": components["schemas"]["ReviewResponse"];
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
reviews_api_v1_reviews_aggregate_retrieve: {
|
|
336
|
+
parameters: {
|
|
337
|
+
query: {
|
|
338
|
+
/** @description Opaque host-owned target identifier. */
|
|
339
|
+
target_key: string;
|
|
340
|
+
/** @description Host-registered target-type key (registry.py). */
|
|
341
|
+
target_type: string;
|
|
342
|
+
};
|
|
343
|
+
header?: never;
|
|
344
|
+
path?: never;
|
|
345
|
+
cookie?: never;
|
|
346
|
+
};
|
|
347
|
+
requestBody?: never;
|
|
348
|
+
responses: {
|
|
349
|
+
200: {
|
|
350
|
+
headers: {
|
|
351
|
+
[name: string]: unknown;
|
|
352
|
+
};
|
|
353
|
+
content: {
|
|
354
|
+
"application/json": components["schemas"]["AggregateResponse"];
|
|
355
|
+
};
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/api/generated/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/api/generated/schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { StapelClient } from "@stapel/core";
|
|
2
|
+
import type { Review, ReviewAggregate, ReviewListParams, ReviewPage, ReviewTarget } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The pair's typed operation surface — one method per stapel-reviews endpoint
|
|
5
|
+
* a buyer's or a seller's browser may call, bound to the injected
|
|
6
|
+
* {@link StapelClient} (the per-module override seam of frontend-standard
|
|
7
|
+
* §7.2). Paths are relative to the runtime's `baseUrl` (`/reviews/api/v1`).
|
|
8
|
+
*
|
|
9
|
+
* ── The two reads are ANONYMOUS; the write is not ─────────────────────────
|
|
10
|
+
*
|
|
11
|
+
* Since stapel-reviews 0.3.0: `ReviewListCreateView` is
|
|
12
|
+
* `IsAuthenticatedOrReadOnly` (GET open, POST still needs a real identity —
|
|
13
|
+
* there is an author to attribute the review to) and `AggregateView` is
|
|
14
|
+
* `AllowAny`. Both declare `stapel_anonymous_access = ANONYMOUS_ALLOWED` and
|
|
15
|
+
* both are throttled from the module's own settings namespace
|
|
16
|
+
* (`LIST_THROTTLE` 120/min, `AGGREGATE_THROTTLE` 300/min), not the project's
|
|
17
|
+
* `DEFAULT_THROTTLE_RATES`.
|
|
18
|
+
*
|
|
19
|
+
* Nothing new became visible: both endpoints were already published-only for
|
|
20
|
+
* a non-moderator. What changed for this pair is that a guest on a public
|
|
21
|
+
* listing page now READS the reviews instead of being told to sign in — so
|
|
22
|
+
* `signInRequired` is gone from the two read bags and survives only on the
|
|
23
|
+
* write, where a 401 is still the honest answer.
|
|
24
|
+
*
|
|
25
|
+
* ── The two operations that are NOT here, and why ─────────────────────────
|
|
26
|
+
*
|
|
27
|
+
* `POST /reviews/{id}/moderate` (hide/publish) and `POST /reviews/{id}/response`
|
|
28
|
+
* (the target owner's single reply) are both gated on the target type's
|
|
29
|
+
* `can_moderate` callback, which is **fail-closed**: a type that names no
|
|
30
|
+
* callback denies everyone (`registry.check_can_moderate`). They belong to a
|
|
31
|
+
* seller console and a moderator console, and this pair ships neither
|
|
32
|
+
* (storefront spec §4.4: the owner's reply is DISPLAYED in the MVP and the
|
|
33
|
+
* button to write one does not exist, rather than existing switched off).
|
|
34
|
+
*
|
|
35
|
+
* Both stay in the generated schema and therefore in `manifest.json`, which
|
|
36
|
+
* lists the whole contract — nothing is hidden; they are simply not this
|
|
37
|
+
* pair's surface. Adding them later is additive and needs no change here.
|
|
38
|
+
*
|
|
39
|
+
* These operations will be GENERATED from schema.json operationIds by gen-api
|
|
40
|
+
* v2; until then they are hand-authored here (the ONE legal home of path
|
|
41
|
+
* strings — `stapel/no-string-paths` §2.3 carve-out).
|
|
42
|
+
*/
|
|
43
|
+
export interface ReviewsApi {
|
|
44
|
+
readonly client: StapelClient;
|
|
45
|
+
/**
|
|
46
|
+
* A page of a target's reviews, newest first. Anonymous callers welcome.
|
|
47
|
+
*
|
|
48
|
+
* Answers core's `AnchorPagination` envelope — declared as
|
|
49
|
+
* `components/ReviewPage` since 0.3.0, so the shape is generated rather
|
|
50
|
+
* than mirrored here. Anchors are `created_at` timestamps.
|
|
51
|
+
*/
|
|
52
|
+
reviews(params: ReviewListParams, options?: {
|
|
53
|
+
readonly signal?: AbortSignal;
|
|
54
|
+
}): Promise<ReviewPage>;
|
|
55
|
+
/**
|
|
56
|
+
* The module-owned rating aggregate for ONE target — mean and count over
|
|
57
|
+
* published reviews. `AllowAny`.
|
|
58
|
+
*
|
|
59
|
+
* There is no batch form on the HTTP surface: `reviews.aggregates_by_keys`
|
|
60
|
+
* is a comm Function for server-side projections, not an endpoint. A
|
|
61
|
+
* storefront that needs a rating per card gets it from the listing rows its
|
|
62
|
+
* own module serves (fed by the composite's projection), not by firing one
|
|
63
|
+
* of these per card.
|
|
64
|
+
*/
|
|
65
|
+
aggregate(target: ReviewTarget, options?: {
|
|
66
|
+
readonly signal?: AbortSignal;
|
|
67
|
+
}): Promise<ReviewAggregate>;
|
|
68
|
+
/**
|
|
69
|
+
* Write a review of a target. The one operation here that needs a real
|
|
70
|
+
* identity (`IsAuthenticatedOrReadOnly` refuses an anonymous POST).
|
|
71
|
+
*
|
|
72
|
+
* Refusals worth knowing by name, because their STATUS is not what a reader
|
|
73
|
+
* expects: "you have already reviewed this" is
|
|
74
|
+
* `error.400.reviews_duplicate_review` — a **400**, while the module's only
|
|
75
|
+
* 409 (`error.409.reviews_already_responded`) is about the owner's reply.
|
|
76
|
+
* Branching on the status code would therefore catch the wrong refusal;
|
|
77
|
+
* `model/submit.ts` branches on the code.
|
|
78
|
+
*/
|
|
79
|
+
createReview(body: {
|
|
80
|
+
readonly targetType: string;
|
|
81
|
+
readonly targetKey: string;
|
|
82
|
+
readonly rating: number;
|
|
83
|
+
readonly body?: string;
|
|
84
|
+
}, options?: {
|
|
85
|
+
readonly signal?: AbortSignal;
|
|
86
|
+
}): Promise<Review>;
|
|
87
|
+
}
|
|
88
|
+
export declare function createReviewsApi(client: StapelClient): ReviewsApi;
|
|
89
|
+
//# sourceMappingURL=reviewsApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewsApi.d.ts","sourceRoot":"","sources":["../../src/api/reviewsApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,cAAc,CAAC;AACvE,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,YAAY,EACb,MAAM,YAAY,CAAC;AAuBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B;;;;;;OAMG;IACH,OAAO,CACL,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvB;;;;;;;;;OASG;IACH,SAAS,CACP,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAAC;IAE5B;;;;;;;;;;OAUG;IACH,YAAY,CACV,IAAI,EAAE;QACJ,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;KACxB,EACD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAOD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA0CjE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF rule for cookie-authenticated browser clients (mirrors auth-react and
|
|
3
|
+
* chat-react): the simplest SPA rule is to always send
|
|
4
|
+
* `X-Requested-With: XMLHttpRequest` on mutating requests. Header-token
|
|
5
|
+
* clients ignore it, so it is harmless there and every mutation carries it.
|
|
6
|
+
*/
|
|
7
|
+
const CSRF_HEADERS = {
|
|
8
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
9
|
+
};
|
|
10
|
+
function mutating(options) {
|
|
11
|
+
return { ...options, headers: { ...CSRF_HEADERS, ...options?.headers } };
|
|
12
|
+
}
|
|
13
|
+
/** The target pair, as the two endpoints that read it spell it. */
|
|
14
|
+
function targetQuery(target) {
|
|
15
|
+
return { target_type: target.targetType, target_key: target.targetKey };
|
|
16
|
+
}
|
|
17
|
+
const signalOf = (options) => options?.signal !== undefined ? { signal: options.signal } : {};
|
|
18
|
+
export function createReviewsApi(client) {
|
|
19
|
+
return {
|
|
20
|
+
client,
|
|
21
|
+
reviews: (params, options) => client.get("/reviews", {
|
|
22
|
+
query: {
|
|
23
|
+
...targetQuery(params),
|
|
24
|
+
...(params.include !== undefined ? { include: params.include } : {}),
|
|
25
|
+
...(params.anchor !== undefined ? { anchor: params.anchor } : {}),
|
|
26
|
+
...(params.direction !== undefined
|
|
27
|
+
? { direction: params.direction }
|
|
28
|
+
: {}),
|
|
29
|
+
...(params.limit !== undefined ? { limit: params.limit } : {}),
|
|
30
|
+
},
|
|
31
|
+
...signalOf(options),
|
|
32
|
+
}),
|
|
33
|
+
aggregate: (target, options) => client.get("/reviews/aggregate", {
|
|
34
|
+
query: targetQuery(target),
|
|
35
|
+
...signalOf(options),
|
|
36
|
+
}),
|
|
37
|
+
createReview: (body, options) => client.post("/reviews", {
|
|
38
|
+
target_type: body.targetType,
|
|
39
|
+
target_key: body.targetKey,
|
|
40
|
+
rating: body.rating,
|
|
41
|
+
// The body defaults to `""` in the request DTO
|
|
42
|
+
// (`dto.ReviewCreateRequest.body: str = ""`) — a rating with no
|
|
43
|
+
// words is a complete review here. Send the field only when there
|
|
44
|
+
// is text, so an empty textarea is not spelled two ways.
|
|
45
|
+
...(body.body !== undefined && body.body.length > 0
|
|
46
|
+
? { body: body.body }
|
|
47
|
+
: {}),
|
|
48
|
+
}, mutating(signalOf(options))),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=reviewsApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewsApi.js","sourceRoot":"","sources":["../../src/api/reviewsApi.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,MAAM,YAAY,GAA2B;IAC3C,kBAAkB,EAAE,gBAAgB;CACrC,CAAC;AAEF,SAAS,QAAQ,CACf,OAAuD;IAEvD,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;AAC3E,CAAC;AAED,mEAAmE;AACnE,SAAS,WAAW,CAAC,MAAoB;IACvC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AAC1E,CAAC;AA8FD,MAAM,QAAQ,GAAG,CAAC,OAEjB,EAA4B,EAAE,CAC7B,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAElE,MAAM,UAAU,gBAAgB,CAAC,MAAoB;IACnD,OAAO;QACL,MAAM;QAEN,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAC3B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE;YACrB,KAAK,EAAE;gBACL,GAAG,WAAW,CAAC,MAAM,CAAC;gBACtB,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS;oBAChC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE;oBACjC,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D;YACD,GAAG,QAAQ,CAAC,OAAO,CAAC;SACrB,CAAC;QAEJ,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAC7B,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE;YAC/B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;YAC1B,GAAG,QAAQ,CAAC,OAAO,CAAC;SACrB,CAAC;QAEJ,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAC9B,MAAM,CAAC,IAAI,CACT,UAAU,EACV;YACE,WAAW,EAAE,IAAI,CAAC,UAAU;YAC5B,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,+CAA+C;YAC/C,gEAAgE;YAChE,kEAAkE;YAClE,yDAAyD;YACzD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;gBACjD,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;gBACrB,CAAC,CAAC,EAAE,CAAC;SACR,EACD,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAC5B;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pair's public wire types — projected from the GENERATED schema
|
|
3
|
+
* (`api/generated/schema.ts`, emitted by `pnpm gen:api` from stapel-reviews'
|
|
4
|
+
* own `docs/schema.json`), never re-typed by hand.
|
|
5
|
+
*
|
|
6
|
+
* **Two hand-written shapes lived here against the 0.2.2 pin and are gone.**
|
|
7
|
+
* `ReviewPage` and the list's `anchor`/`limit`/`direction` parameters were
|
|
8
|
+
* declared by this file because `ReviewListCreateView` is a bare `APIView`
|
|
9
|
+
* that instantiates its paginator inside `get()`: drf-spectacular's pagination
|
|
10
|
+
* introspection only fires for `GenericAPIView.pagination_class`, so the
|
|
11
|
+
* schema declared `200: ReviewResponse[]` and knew nothing of the three query
|
|
12
|
+
* parameters. **stapel-reviews 0.3.0 declares both** — `components/ReviewPage`
|
|
13
|
+
* and the parameters, `direction` with an enum — so the copies were deleted
|
|
14
|
+
* and everything below comes from codegen. The upstream ask that produced this
|
|
15
|
+
* is recorded in `contract-pins.json`.
|
|
16
|
+
*
|
|
17
|
+
* Two corrections remain, and both are widenings of what the wire can say
|
|
18
|
+
* rather than shapes the schema is missing:
|
|
19
|
+
*
|
|
20
|
+
* 1. **`status` is a bare `string` on the wire** and a three-member lifecycle
|
|
21
|
+
* in the model (`ReviewStatus`). {@link ReviewStatus} names the three
|
|
22
|
+
* WITHOUT narrowing a parsed value: a fourth state added upstream must
|
|
23
|
+
* render as an unknown state, not crash a switch.
|
|
24
|
+
* 2. **`avg` is `0.0` when `count` is `0`.** The type cannot express that, so
|
|
25
|
+
* {@link RatingAggregate} exists as the shape both this module's own
|
|
26
|
+
* aggregate endpoint AND the shop composite's `shop.listing_review_summary`
|
|
27
|
+
* projection answer with — and `model/rating.ts` is the one place allowed
|
|
28
|
+
* to decide what a zero means.
|
|
29
|
+
*/
|
|
30
|
+
import type { components, operations } from "./generated/schema.js";
|
|
31
|
+
/** Every component schema stapel-reviews declares. */
|
|
32
|
+
export type Schemas = components["schemas"];
|
|
33
|
+
/** One review of an opaque target, with the owner's reply when there is one. */
|
|
34
|
+
export type Review = Schemas["ReviewResponse"];
|
|
35
|
+
/** The target owner's single reply to a review. */
|
|
36
|
+
export type ReviewOwnerResponse = Schemas["ResponseResponse"];
|
|
37
|
+
/** `POST /reviews` request body. */
|
|
38
|
+
export type ReviewCreateRequest = Schemas["ReviewCreateRequest"];
|
|
39
|
+
/**
|
|
40
|
+
* `GET /reviews/aggregate` 200 body — the module-owned aggregate for ONE
|
|
41
|
+
* target, carrying the target it is about.
|
|
42
|
+
*/
|
|
43
|
+
export type ReviewAggregate = Schemas["AggregateResponse"];
|
|
44
|
+
/**
|
|
45
|
+
* The 200 body of `GET /reviews` — core's `AnchorPagination` envelope,
|
|
46
|
+
* generated since 0.3.0 (see this module's header).
|
|
47
|
+
*
|
|
48
|
+
* `count` is the number of rows in THIS page, not the total; the total number
|
|
49
|
+
* of published reviews is the aggregate's `count`, which is a different number
|
|
50
|
+
* computed a different way.
|
|
51
|
+
*/
|
|
52
|
+
export type ReviewPage = Schemas["ReviewPage"];
|
|
53
|
+
/** The generated query surface of `GET /reviews`. */
|
|
54
|
+
type ReviewListQuery = NonNullable<operations["reviews_api_v1_reviews_retrieve"]["parameters"]["query"]>;
|
|
55
|
+
/**
|
|
56
|
+
* A review's visibility, as `models.ReviewStatus` spells it.
|
|
57
|
+
*
|
|
58
|
+
* - `published` — visible to everyone and counted in the aggregate.
|
|
59
|
+
* - `pending` — created under PRE-moderation; invisible until a moderator
|
|
60
|
+
* publishes it, **including to its own author**, who therefore cannot see
|
|
61
|
+
* the review they just wrote in the published-only list.
|
|
62
|
+
* - `hidden` — moderated out; invisible and excluded from the aggregate.
|
|
63
|
+
*
|
|
64
|
+
* Only reachable in a list response when the caller asked for `include=all`
|
|
65
|
+
* AND the target type's `can_moderate` callback said yes; a non-moderator's
|
|
66
|
+
* `include=all` is silently narrowed to published (`views.py`).
|
|
67
|
+
*/
|
|
68
|
+
export type ReviewStatus = "pending" | "published" | "hidden";
|
|
69
|
+
/**
|
|
70
|
+
* The two halves of the module's opaque address. There is no foreign key
|
|
71
|
+
* anywhere in stapel-reviews: `target_type` is a key the HOST registered in
|
|
72
|
+
* `STAPEL_REVIEWS["TARGET_TYPES"]` (the built-in registry is EMPTY) and
|
|
73
|
+
* `target_key` is a host-owned string the module stores, groups by, and never
|
|
74
|
+
* parses.
|
|
75
|
+
*
|
|
76
|
+
* This package therefore ships no target-type constants — not even
|
|
77
|
+
* `"listing"`. The catalogue shop composite registers that name in its own
|
|
78
|
+
* preset (`stapel_shop/preset.py`), a different deployment registers
|
|
79
|
+
* `"seller"` or `"course"`, and a library that guessed would be wrong for
|
|
80
|
+
* every host but one.
|
|
81
|
+
*/
|
|
82
|
+
export interface ReviewTarget {
|
|
83
|
+
readonly targetType: string;
|
|
84
|
+
readonly targetKey: string;
|
|
85
|
+
}
|
|
86
|
+
/** The rating roll-up itself, without the target it belongs to.
|
|
87
|
+
*
|
|
88
|
+
* Deliberately the same two field names the composite's projection uses
|
|
89
|
+
* (`shop.listing_review_summary` → `{avg, count}`, `stapel_shop/models.py`):
|
|
90
|
+
* a seller-level rating is computed by the composite and handed to this
|
|
91
|
+
* pair's display as data, because stapel-reviews can only aggregate ONE
|
|
92
|
+
* `(target_type, target_key)` at a time and has no roll-up endpoint. Same
|
|
93
|
+
* shape in, same rendering out — see {@link ratingSummary}. */
|
|
94
|
+
export interface RatingAggregate {
|
|
95
|
+
/** Mean rating over PUBLISHED reviews. `0` when `count` is `0` — which is
|
|
96
|
+
* "nobody has rated this", never "everyone rated it zero". */
|
|
97
|
+
readonly avg: number;
|
|
98
|
+
/** Number of published reviews. */
|
|
99
|
+
readonly count: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Anchor-pagination direction — the enum the schema now carries. The review
|
|
103
|
+
* list is ordered `-created_at`, so:
|
|
104
|
+
*
|
|
105
|
+
* - `next` (default) — reviews OLDER than the anchor (the load-more direction),
|
|
106
|
+
* - `prev` — reviews NEWER than the anchor,
|
|
107
|
+
* - `center` — a window around the anchor.
|
|
108
|
+
*/
|
|
109
|
+
export type ReviewAnchorDirection = NonNullable<ReviewListQuery["direction"]>;
|
|
110
|
+
/**
|
|
111
|
+
* Query for `GET /reviews`: the generated parameters, with only the target
|
|
112
|
+
* pair renamed to this package's camelCase {@link ReviewTarget}. Nothing here
|
|
113
|
+
* is hand-typed any more — `include`, `anchor`, `limit` and `direction` are
|
|
114
|
+
* exactly what the contract declares.
|
|
115
|
+
*
|
|
116
|
+
* `target_type`/`target_key` are required by the view (a missing one is
|
|
117
|
+
* `error.400.reviews_unknown_target_type`, not an empty list). `anchor` is a
|
|
118
|
+
* `created_at` ISO timestamp and exclusive. `include` is typed `string`
|
|
119
|
+
* because the schema declares no enum for it: the view acts on the literal
|
|
120
|
+
* `"all"` and treats anything else as published-only, silently — which is why
|
|
121
|
+
* the hook option that offers it (`UseReviewListOptions.include`) narrows to
|
|
122
|
+
* the one value the server actually reads.
|
|
123
|
+
*/
|
|
124
|
+
export interface ReviewListParams extends ReviewTarget, Omit<ReviewListQuery, "target_type" | "target_key"> {
|
|
125
|
+
}
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,sDAAsD;AACtD,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;AAE5C,gFAAgF;AAChF,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/C,mDAAmD;AACnD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAE9D,oCAAoC;AACpC,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE/C,qDAAqD;AACrD,KAAK,eAAe,GAAG,WAAW,CAChC,UAAU,CAAC,iCAAiC,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CACrE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;+DAO+D;AAC/D,MAAM,WAAW,eAAe;IAC9B;kEAC8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBACf,SAAQ,YAAY,EAClB,IAAI,CAAC,eAAe,EAAE,aAAa,GAAG,YAAY,CAAC;CAAG"}
|