@stapel/listings-react 0.1.0 → 0.2.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 +65 -0
- package/LICENSE +21 -0
- package/dist/api/types.d.ts +1 -1
- package/dist/api/types.js +1 -1
- package/dist/i18n/ru.d.ts +1 -1
- package/dist/i18n/ru.js +1 -1
- package/llms.txt +1 -1
- package/manifest.json +1 -1
- package/nav-manifest.json +1 -1
- package/package.json +16 -16
- package/src/analytics/generated/events.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1 +1,66 @@
|
|
|
1
1
|
# @stapel/listings-react
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fcc9f1e: Two axes, both on screen — the storefront's long pole
|
|
8
|
+
|
|
9
|
+
`@stapel/listings-react` is the pair for stapel-listings: the listing page, the
|
|
10
|
+
submission flow, the seller's dashboard, and favourites.
|
|
11
|
+
|
|
12
|
+
The module has two independent state axes and 0.5.0 made them genuinely
|
|
13
|
+
diverge. `status` decides whether anyone can see a listing and nothing else
|
|
14
|
+
does; `moderation_status` decides nothing about that. Editing a LIVE listing
|
|
15
|
+
keeps `status: published` and moves only the moderation axis, so "published,
|
|
16
|
+
and we are reviewing your changes" is a real state — one a dashboard that
|
|
17
|
+
derived either field from the other could not say, because it would either
|
|
18
|
+
hide a listing buyers are reading or never tell its owner their edit is being
|
|
19
|
+
screened. `model/status.ts` produces both halves of the sentence from both
|
|
20
|
+
fields, once; the 9 × 4 table is asserted.
|
|
21
|
+
|
|
22
|
+
A publish refusal is per-field and arrives in an unusual envelope: an invalid
|
|
23
|
+
draft comes back as a BARE `ValidationBatchResult`, while a promotion that
|
|
24
|
+
fails afterwards comes back as the ordinary one. `publishRefusal` branches on
|
|
25
|
+
the body rather than the status, and `featureErrorsBySlug` adds the `field`
|
|
26
|
+
the fleet's routing convention reads — so "this box is wrong" never degrades
|
|
27
|
+
into "something is wrong".
|
|
28
|
+
|
|
29
|
+
Three contracts meet on the composer and none of them is an import. L2 pairs do
|
|
30
|
+
not import each other, so the gallery arrives as a two-member structural bag
|
|
31
|
+
(`@stapel/cdn-react`'s `refs` IS `images_draft`; its `settled` is the submit
|
|
32
|
+
gate), the category schema as a plain `FeatureDef[]`, and a stored CDN
|
|
33
|
+
reference through a host-supplied resolver — because no contract in this fleet
|
|
34
|
+
resolves a stranger's reference, and inventing `${cdnBase}/${ref}` would be
|
|
35
|
+
writing a contract nobody agreed to. `@stapel/attributes-react` is a real
|
|
36
|
+
dependency; it is L0, and it owns the editors, the mirror and the formatter.
|
|
37
|
+
|
|
38
|
+
Four things the pair says out loud rather than papering over:
|
|
39
|
+
|
|
40
|
+
- **there is no owner-scoped list endpoint.** `GET /listings/` answers
|
|
41
|
+
`published()` and takes no owner parameter, so a seller's drafts are
|
|
42
|
+
unreachable. The counters are real and are shown; the rows come from an
|
|
43
|
+
injected source, and with none the dashboard reports a NAMED failure instead
|
|
44
|
+
of an empty grid;
|
|
45
|
+
- **no read returns the `*_draft` twin**, so an abandoned draft reopens empty
|
|
46
|
+
and the composer says so. Editing a live listing is unaffected — the
|
|
47
|
+
published half IS the listing;
|
|
48
|
+
- **`PUT`/`PATCH` skip the ownership check** that every other owner operation
|
|
49
|
+
in the module performs, so they are absent from `ListingsApi`;
|
|
50
|
+
`save-draft` does the same write with the check;
|
|
51
|
+
- **`GET /{pk}/` has no `published()` filter**, so a draft answers 200 to
|
|
52
|
+
anyone with the id. The pane reports it instead of dressing a draft up as a
|
|
53
|
+
shop page.
|
|
54
|
+
|
|
55
|
+
Also here: the card another pair renders (badges formatted from the stored DAO
|
|
56
|
+
projection, so a grid of forty costs one query and no category read); a soft
|
|
57
|
+
delete that reads as "this listing was removed" rather than as a typo, using
|
|
58
|
+
the AllowAny status probe that still answers for it; favourites (owner verdict
|
|
59
|
+
F7) with the heart blocked-and-explained for a visitor rather than hidden; and
|
|
60
|
+
ru/es carrying the UI copy, not only the error keys, because the storefront is
|
|
61
|
+
ru-first and a half-translated submission form is visible immediately.
|
|
62
|
+
|
|
63
|
+
Generated against stapel-listings **0.6.1** — the release that fixed
|
|
64
|
+
`FeatureDto`/`FeatureDao`'s `discriminator.mapping` from one bogus `"null"`
|
|
65
|
+
entry to the ten type slugs, which is what makes the generated union usable as
|
|
66
|
+
the wire type at all.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stapel contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/api/types.d.ts
CHANGED
|
@@ -146,7 +146,7 @@ export interface ListingPageParams {
|
|
|
146
146
|
/**
|
|
147
147
|
* The currency a composer starts a new listing in.
|
|
148
148
|
*
|
|
149
|
-
* RUB by owner verdict F6 (
|
|
149
|
+
* RUB by owner verdict F6 (storefront spec, the owner's
|
|
150
150
|
* fork verdicts of 2026-08-22), and a default rather than a constant: `currency` is
|
|
151
151
|
* a free `maxLength: 8` string on the wire (stapel-listings has no currency
|
|
152
152
|
* enum — the vocabulary lives in stapel-currencies), so a deployment that
|
package/dist/api/types.js
CHANGED
|
@@ -27,7 +27,7 @@ export const MODERATION_STATUSES = [
|
|
|
27
27
|
/**
|
|
28
28
|
* The currency a composer starts a new listing in.
|
|
29
29
|
*
|
|
30
|
-
* RUB by owner verdict F6 (
|
|
30
|
+
* RUB by owner verdict F6 (storefront spec, the owner's
|
|
31
31
|
* fork verdicts of 2026-08-22), and a default rather than a constant: `currency` is
|
|
32
32
|
* a free `maxLength: 8` string on the wire (stapel-listings has no currency
|
|
33
33
|
* enum — the vocabulary lives in stapel-currencies), so a deployment that
|
package/dist/i18n/ru.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { listingsErrorBundleRu } from "./generated/errors.ru.gen.js";
|
|
|
6
6
|
* register it never carry these strings (the main entry does not import this
|
|
7
7
|
* module — gated by size-limit + the bundle-purity test).
|
|
8
8
|
*
|
|
9
|
-
* This is the storefront's DEFAULT language (
|
|
9
|
+
* This is the storefront's DEFAULT language (storefront spec verdict F1:
|
|
10
10
|
* ru-first), which is why the UI copy is here in full and not only the error
|
|
11
11
|
* keys: a seller filling in a listing is the surface where a half-translated
|
|
12
12
|
* form is most obvious.
|
package/dist/i18n/ru.js
CHANGED
|
@@ -6,7 +6,7 @@ export { listingsErrorBundleRu } from "./generated/errors.ru.gen.js";
|
|
|
6
6
|
* register it never carry these strings (the main entry does not import this
|
|
7
7
|
* module — gated by size-limit + the bundle-purity test).
|
|
8
8
|
*
|
|
9
|
-
* This is the storefront's DEFAULT language (
|
|
9
|
+
* This is the storefront's DEFAULT language (storefront spec verdict F1:
|
|
10
10
|
* ru-first), which is why the UI copy is here in full and not only the error
|
|
11
11
|
* keys: a seller filling in a listing is the surface where a half-translated
|
|
12
12
|
* form is most obvious.
|
package/llms.txt
CHANGED
package/manifest.json
CHANGED
package/nav-manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/listings-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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": {
|
|
@@ -46,13 +46,6 @@
|
|
|
46
46
|
"nav-manifest.json",
|
|
47
47
|
"llms.txt"
|
|
48
48
|
],
|
|
49
|
-
"scripts": {
|
|
50
|
-
"build": "tsc -p tsconfig.json",
|
|
51
|
-
"test": "tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts",
|
|
52
|
-
"lint": "eslint .",
|
|
53
|
-
"size": "size-limit",
|
|
54
|
-
"test:pack": "vitest run test/prodBundlePurity.test.ts"
|
|
55
|
-
},
|
|
56
49
|
"size-limit": [
|
|
57
50
|
{
|
|
58
51
|
"name": "index — the headless pair (client + status axes + draft model + hooks): no antd",
|
|
@@ -94,12 +87,6 @@
|
|
|
94
87
|
},
|
|
95
88
|
"devDependencies": {
|
|
96
89
|
"@size-limit/preset-small-lib": "^11.2.0",
|
|
97
|
-
"@stapel/attributes-react": "workspace:^",
|
|
98
|
-
"@stapel/core": "workspace:^",
|
|
99
|
-
"@stapel/image": "workspace:^",
|
|
100
|
-
"@stapel/showcase": "workspace:^",
|
|
101
|
-
"@stapel/tokens": "workspace:^",
|
|
102
|
-
"@stapel/tokens-antd": "workspace:^",
|
|
103
90
|
"@tanstack/react-query": "^5.81.0",
|
|
104
91
|
"@testing-library/react": "^16.3.0",
|
|
105
92
|
"@types/react": "^19.1.0",
|
|
@@ -110,12 +97,25 @@
|
|
|
110
97
|
"react-dom": "^19.1.0",
|
|
111
98
|
"size-limit": "^11.2.0",
|
|
112
99
|
"typescript": "^5.8.3",
|
|
113
|
-
"vitest": "^3.2.4"
|
|
100
|
+
"vitest": "^3.2.4",
|
|
101
|
+
"@stapel/attributes-react": "^0.2.0",
|
|
102
|
+
"@stapel/core": "^0.15.0",
|
|
103
|
+
"@stapel/image": "^0.2.0",
|
|
104
|
+
"@stapel/showcase": "^0.2.0",
|
|
105
|
+
"@stapel/tokens": "^0.5.0",
|
|
106
|
+
"@stapel/tokens-antd": "^0.5.0"
|
|
114
107
|
},
|
|
115
108
|
"engines": {
|
|
116
109
|
"node": ">=22"
|
|
117
110
|
},
|
|
118
111
|
"publishConfig": {
|
|
119
112
|
"access": "public"
|
|
113
|
+
},
|
|
114
|
+
"scripts": {
|
|
115
|
+
"build": "tsc -p tsconfig.json",
|
|
116
|
+
"test": "tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts",
|
|
117
|
+
"lint": "eslint .",
|
|
118
|
+
"size": "size-limit",
|
|
119
|
+
"test:pack": "vitest run test/prodBundlePurity.test.ts"
|
|
120
120
|
}
|
|
121
|
-
}
|
|
121
|
+
}
|