@stapel/listings-react 0.22.1 → 0.24.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.
Files changed (119) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/README.md +73 -6
  3. package/dist/api/generated/schema.d.ts +119 -6
  4. package/dist/api/generated/schema.d.ts.map +1 -1
  5. package/dist/api/listingsApi.d.ts +25 -0
  6. package/dist/api/listingsApi.d.ts.map +1 -1
  7. package/dist/api/listingsApi.js +1 -0
  8. package/dist/api/listingsApi.js.map +1 -1
  9. package/dist/api/types.d.ts +46 -3
  10. package/dist/api/types.d.ts.map +1 -1
  11. package/dist/api/types.js.map +1 -1
  12. package/dist/default/CardBadges.d.ts +47 -0
  13. package/dist/default/CardBadges.d.ts.map +1 -0
  14. package/dist/default/CardBadges.js +38 -0
  15. package/dist/default/CardBadges.js.map +1 -0
  16. package/dist/default/FavoritesPane.d.ts +18 -2
  17. package/dist/default/FavoritesPane.d.ts.map +1 -1
  18. package/dist/default/FavoritesPane.js +3 -3
  19. package/dist/default/FavoritesPane.js.map +1 -1
  20. package/dist/default/ListingCard.d.ts.map +1 -1
  21. package/dist/default/ListingCard.js +6 -6
  22. package/dist/default/ListingCard.js.map +1 -1
  23. package/dist/default/ListingDetailPane.d.ts.map +1 -1
  24. package/dist/default/ListingDetailPane.js +12 -19
  25. package/dist/default/ListingDetailPane.js.map +1 -1
  26. package/dist/default/ListingPhoto.d.ts.map +1 -1
  27. package/dist/default/ListingPhoto.js +12 -8
  28. package/dist/default/ListingPhoto.js.map +1 -1
  29. package/dist/default/ListingSerpCard.d.ts.map +1 -1
  30. package/dist/default/ListingSerpCard.js +3 -5
  31. package/dist/default/ListingSerpCard.js.map +1 -1
  32. package/dist/default/ListingSpecList.d.ts +74 -0
  33. package/dist/default/ListingSpecList.d.ts.map +1 -0
  34. package/dist/default/ListingSpecList.js +90 -0
  35. package/dist/default/ListingSpecList.js.map +1 -0
  36. package/dist/default/MyListingsPane.d.ts +22 -2
  37. package/dist/default/MyListingsPane.d.ts.map +1 -1
  38. package/dist/default/MyListingsPane.js +1 -1
  39. package/dist/default/MyListingsPane.js.map +1 -1
  40. package/dist/default/cardGallery.d.ts +81 -0
  41. package/dist/default/cardGallery.d.ts.map +1 -0
  42. package/dist/default/cardGallery.js +266 -0
  43. package/dist/default/cardGallery.js.map +1 -0
  44. package/dist/default/index.d.ts +8 -2
  45. package/dist/default/index.d.ts.map +1 -1
  46. package/dist/default/index.js +5 -0
  47. package/dist/default/index.js.map +1 -1
  48. package/dist/headless/ListingComposer.d.ts +16 -10
  49. package/dist/headless/ListingComposer.d.ts.map +1 -1
  50. package/dist/headless/ListingComposer.js +23 -4
  51. package/dist/headless/ListingComposer.js.map +1 -1
  52. package/dist/i18n/es.d.ts.map +1 -1
  53. package/dist/i18n/es.js +1 -0
  54. package/dist/i18n/es.js.map +1 -1
  55. package/dist/i18n/generated/errors.es.gen.d.ts +1 -1
  56. package/dist/i18n/generated/errors.es.gen.js +1 -1
  57. package/dist/i18n/generated/errors.gen.d.ts +6 -0
  58. package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
  59. package/dist/i18n/generated/errors.gen.js +3 -0
  60. package/dist/i18n/generated/errors.gen.js.map +1 -1
  61. package/dist/i18n/generated/errors.ru.gen.d.ts +1 -1
  62. package/dist/i18n/generated/errors.ru.gen.js +1 -1
  63. package/dist/i18n/ru.d.ts.map +1 -1
  64. package/dist/i18n/ru.js +3 -0
  65. package/dist/i18n/ru.js.map +1 -1
  66. package/dist/index.d.ts +4 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +4 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/model/cardBadges.d.ts +134 -0
  71. package/dist/model/cardBadges.d.ts.map +1 -0
  72. package/dist/model/cardBadges.js +131 -0
  73. package/dist/model/cardBadges.js.map +1 -0
  74. package/dist/model/featureText.d.ts +63 -0
  75. package/dist/model/featureText.d.ts.map +1 -0
  76. package/dist/model/featureText.js +133 -0
  77. package/dist/model/featureText.js.map +1 -0
  78. package/dist/model/features.d.ts.map +1 -1
  79. package/dist/model/features.js +59 -0
  80. package/dist/model/features.js.map +1 -1
  81. package/dist/model/queries.d.ts +15 -1
  82. package/dist/model/queries.d.ts.map +1 -1
  83. package/dist/model/queries.js +20 -0
  84. package/dist/model/queries.js.map +1 -1
  85. package/dist/model/queryKeys.d.ts +4 -0
  86. package/dist/model/queryKeys.d.ts.map +1 -1
  87. package/dist/model/queryKeys.js +1 -0
  88. package/dist/model/queryKeys.js.map +1 -1
  89. package/llms.txt +6 -2
  90. package/manifest.json +57 -1
  91. package/nav-manifest.json +1 -1
  92. package/package.json +5 -5
  93. package/src/analytics/generated/events.json +1 -1
  94. package/src/api/generated/schema.ts +119 -6
  95. package/src/api/listingsApi.ts +30 -0
  96. package/src/api/types.ts +55 -5
  97. package/src/default/CardBadges.tsx +105 -0
  98. package/src/default/FavoritesPane.tsx +20 -5
  99. package/src/default/ListingCard.tsx +7 -21
  100. package/src/default/ListingDetailPane.tsx +13 -37
  101. package/src/default/ListingPhoto.tsx +54 -26
  102. package/src/default/ListingSerpCard.tsx +10 -28
  103. package/src/default/ListingSpecList.tsx +195 -0
  104. package/src/default/MyListingsPane.tsx +23 -5
  105. package/src/default/cardGallery.ts +287 -0
  106. package/src/default/index.ts +24 -1
  107. package/src/headless/ListingComposer.tsx +42 -17
  108. package/src/i18n/es.ts +3 -0
  109. package/src/i18n/generated/errors.es.gen.ts +1 -1
  110. package/src/i18n/generated/errors.gen.ts +3 -0
  111. package/src/i18n/generated/errors.json +9 -0
  112. package/src/i18n/generated/errors.ru.gen.ts +1 -1
  113. package/src/i18n/ru.ts +5 -0
  114. package/src/index.ts +16 -0
  115. package/src/model/cardBadges.ts +237 -0
  116. package/src/model/featureText.ts +199 -0
  117. package/src/model/features.ts +60 -0
  118. package/src/model/queries.ts +25 -0
  119. package/src/model/queryKeys.ts +5 -0
@@ -0,0 +1,133 @@
1
+ import { featureConfig, featureType, formatFeatureValue } from "@stapel/attributes-react";
2
+ /** The engine's own defaults (`types/int/type.py`, `types/float/type.py`). */
3
+ const DEFAULT_DIGITS = {
4
+ int: 1,
5
+ float: 2,
6
+ };
7
+ function str(value) {
8
+ return typeof value === "string" ? value : "";
9
+ }
10
+ /**
11
+ * A config string the engine declares to be a translation key, resolved.
12
+ *
13
+ * `prefix`/`postfix`/`postfix1000` are collected by upstream's
14
+ * `get_translation_keys` unconditionally, so they go through the host's
15
+ * catalogue exactly as `formatFeatureValue` sends them — a Russian storefront
16
+ * was reading "L" and "each" off its own spec table before that landed, and
17
+ * this path must not reintroduce it.
18
+ */
19
+ function translated(options, raw) {
20
+ const text = str(raw);
21
+ if (text.length === 0)
22
+ return "";
23
+ const t = options?.t;
24
+ if (t === undefined)
25
+ return text;
26
+ const resolved = t(text);
27
+ return resolved.length > 0 ? resolved : text;
28
+ }
29
+ /**
30
+ * The unit a numeric feature is measured in, as the reader sees it — or `""`.
31
+ *
32
+ * `postfix1000` when the engine's own thousand switch applies, `postfix`
33
+ * otherwise, so the unit and the number can never disagree about scale.
34
+ */
35
+ export function featureUnit(feature, dto, options) {
36
+ const type = featureType(feature);
37
+ if (type !== "int" && type !== "float")
38
+ return "";
39
+ const config = featureConfig(feature);
40
+ const parsed = Number(dto?.value);
41
+ const big = str(config["postfix1000"]).length > 0 && Number.isFinite(parsed) && Math.abs(parsed) >= 1000;
42
+ return translated(options, config[big ? "postfix1000" : "postfix"]);
43
+ }
44
+ /**
45
+ * `Intl.NumberFormat` for one value, or `undefined` when the runtime has no
46
+ * `Intl` for this locale to offer.
47
+ *
48
+ * A bad BCP-47 tag throws `RangeError`, and a spec table that renders nothing
49
+ * because a host passed `"en_US"` would be a worse outcome than an ungrouped
50
+ * number — so the caller falls back rather than the page failing.
51
+ */
52
+ function grouped(value, digits, locale) {
53
+ try {
54
+ return new Intl.NumberFormat(locale, {
55
+ minimumFractionDigits: digits,
56
+ maximumFractionDigits: digits,
57
+ }).format(value);
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
62
+ }
63
+ /**
64
+ * The one numeric row, typeset — see the module header for what each piece
65
+ * is repairing.
66
+ *
67
+ * Returns `undefined` for a value that is not a number, so the caller falls
68
+ * back to the shared formatter and an unreadable row keeps saying so.
69
+ */
70
+ function formatNumeric(feature, dto, kind, options) {
71
+ // `Number(null)` is 0 and `Number("")` is 0, so a blank row would render as
72
+ // a confident zero. The shared formatter's own `isBlank` gate is upstream of
73
+ // this branch and must be restated here rather than assumed.
74
+ const raw = dto.value;
75
+ if (raw === null || raw === undefined || raw === "")
76
+ return undefined;
77
+ const parsed = typeof raw === "number" ? raw : Number(raw);
78
+ if (!Number.isFinite(parsed))
79
+ return undefined;
80
+ const config = featureConfig(feature);
81
+ const precision = config["precision"];
82
+ const digits = typeof precision === "number" && precision >= 0 ? precision : DEFAULT_DIGITS[kind];
83
+ const prefix = translated(options, config["prefix"]);
84
+ const postfix1000 = str(config["postfix1000"]);
85
+ // The engine switches unit AND scale at exactly a thousand
86
+ // (`format_value`: `value / 1000`, trailing zeros stripped, `postfix1000`
87
+ // as the unit). Grouping a scaled number is harmless and keeps one code
88
+ // path; the trailing-zero strip is the engine's, done on the plain digits
89
+ // before the locale ever sees them, because "1.50" and "1,5" are the same
90
+ // decision made in two places.
91
+ if (postfix1000.length > 0 && Math.abs(parsed) >= 1000) {
92
+ const scaled = Number((parsed / 1000).toFixed(digits));
93
+ const body = grouped(scaled, decimalsOf(scaled, digits), options?.locale) ?? String(scaled);
94
+ return join(prefix, body, translated(options, postfix1000));
95
+ }
96
+ // `precision` drives ONLY the scaled branch of an int — the engine's plain
97
+ // branch is `str(value)`, and an integer never grows a decimal tail
98
+ // whatever the config says (D26: a live category shipped `precision: 1` on
99
+ // a year field and the card read "2024.0").
100
+ const value = kind === "int" ? Math.trunc(parsed) : parsed;
101
+ const fraction = kind === "int" ? 0 : digits;
102
+ const body = grouped(value, fraction, options?.locale) ?? value.toFixed(fraction);
103
+ return join(prefix, body, translated(options, config["postfix"]));
104
+ }
105
+ /** How many decimals a scaled value actually has, capped at the configured
106
+ * precision — the engine's `.rstrip('0').rstrip('.')`, expressed as a count
107
+ * so `Intl` can do the rendering. */
108
+ function decimalsOf(value, cap) {
109
+ const tail = value.toFixed(cap).split(".")[1] ?? "";
110
+ return tail.replace(/0+$/, "").length;
111
+ }
112
+ /** `prefix` + body + unit, with the single space the engine puts between a
113
+ * number and its unit and no space at all where there is no unit. */
114
+ function join(prefix, body, unit) {
115
+ return unit.length > 0 ? `${prefix}${body} ${unit}` : `${prefix}${body}`;
116
+ }
117
+ /**
118
+ * A stored value as a spec row prints it: `formatFeatureValue` for every type
119
+ * but the two numeric ones, which are typeset here instead.
120
+ *
121
+ * Signature-compatible with `formatFeatureValue` on purpose — a surface
122
+ * swaps one for the other and nothing else changes.
123
+ */
124
+ export function formatSpecValue(feature, dto, options) {
125
+ const type = featureType(feature);
126
+ if (dto !== undefined && (type === "int" || type === "float")) {
127
+ const typeset = formatNumeric(feature, dto, type, options);
128
+ if (typeset !== undefined)
129
+ return typeset;
130
+ }
131
+ return formatFeatureValue(feature, dto, options);
132
+ }
133
+ //# sourceMappingURL=featureText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureText.js","sourceRoot":"","sources":["../../src/model/featureText.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AA0F7E;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACnD;AAiID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,iBAAiB,EACtB,MAAM,GAAE,iBAAsB,GAC7B,kBAAkB,GAAG,SAAS,CAEhC;AAoED;;;mCAGmC;AACnC,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,EACrD,MAAM,GAAE,iBAAsB,GAC7B,SAAS,kBAAkB,EAAE,CAQ/B;AAED,qEAAqE;AACrE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GACpD,MAAM,CAER;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GACpD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAO3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,EACrD,MAAM,GAAE,iBAAsB,GAC7B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAM3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAE7E"}
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AA0F7E;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACnD;AA2LD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,iBAAiB,EACtB,MAAM,GAAE,iBAAsB,GAC7B,kBAAkB,GAAG,SAAS,CAEhC;AAsED;;;mCAGmC;AACnC,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,EACrD,MAAM,GAAE,iBAAsB,GAC7B,SAAS,kBAAkB,EAAE,CAQ/B;AAED,qEAAqE;AACrE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GACpD,MAAM,CAER;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GACpD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAO3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,EACrD,MAAM,GAAE,iBAAsB,GAC7B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAM3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAE7E"}
@@ -186,6 +186,62 @@ function selectOptions(dao, config, categoryDef) {
186
186
  return undefined;
187
187
  return [...table].map(([value, label]) => ({ value, label }));
188
188
  }
189
+ /**
190
+ * The config keys that carry a value's UNIT, in the order they belong to.
191
+ *
192
+ * There is no generic `unit` key anywhere in this contract — the unit of an
193
+ * `int`/`float` is its `postfix` (free text on the type's config, with
194
+ * `postfix1000` as the abbreviated unit the engine switches to at a
195
+ * thousand), and `convertible_unit` states its own with `unitType`/`unit_m`/
196
+ * `unit_i`. `prefix` rides along because it is the same fact on the other
197
+ * side of the number (a currency mark, a «~»).
198
+ *
199
+ * `precision` is deliberately NOT here. `dto_to_dao` writes it on every
200
+ * numeric row (defaulted, never absent), so it could only ever be adopted
201
+ * onto a row from some older server — where the stored value has already
202
+ * been ROUNDED to the precision it was written with, and re-rendering it at
203
+ * today's would print decimals the record does not contain.
204
+ */
205
+ const UNIT_KEYS = [
206
+ "prefix",
207
+ "postfix",
208
+ "postfix1000",
209
+ "unitType",
210
+ "unit_m",
211
+ "unit_i",
212
+ ];
213
+ /**
214
+ * The unit the CATEGORY declares, for a stored row that carries none.
215
+ *
216
+ * Measured on the live listing page: "Power 173", "Mileage 20000" — bare
217
+ * numbers, in a deployment whose detail page holds the category's own feature
218
+ * defs and passes them in for exactly this kind of repair. `dto_to_dao`
219
+ * copies `postfix` at WRITE time, so a listing published before its category
220
+ * gained a unit keeps printing without one for the rest of its life, and so
221
+ * does every row written by a server that predates the key.
222
+ *
223
+ * Same rule as the option table two functions up, and for the same reason:
224
+ * the stored row wins wherever it said anything, because it is what the
225
+ * listing was published with, and the category fills only the silence. An
226
+ * empty string counts as silence — `dto_to_dao` writes `postfix=None` as
227
+ * absent, but a catalogue that once held `""` should not out-rank a
228
+ * catalogue that now holds "km".
229
+ */
230
+ function adoptedUnits(config, categoryDef) {
231
+ const declared = categoryDef?.config;
232
+ if (declared === undefined)
233
+ return undefined;
234
+ const out = {};
235
+ for (const key of UNIT_KEYS) {
236
+ const stored = config[key];
237
+ if (typeof stored === "string" && stored.length > 0)
238
+ continue;
239
+ const value = declared[key];
240
+ if (typeof value === "string" && value.length > 0)
241
+ out[key] = value;
242
+ }
243
+ return Object.keys(out).length === 0 ? undefined : out;
244
+ }
189
245
  /**
190
246
  * The category's option TREE, adopted whole for a `hierarchical_select` that
191
247
  * stored none — see {@link TREE_VALUED}.
@@ -225,6 +281,9 @@ function featureView(dao, defs) {
225
281
  const options = selectOptions(dao, config, categoryDef) ?? adoptedTree(dao, config, categoryDef);
226
282
  if (options !== undefined)
227
283
  config["options"] = options;
284
+ const units = adoptedUnits(config, categoryDef);
285
+ if (units !== undefined)
286
+ Object.assign(config, units);
228
287
  const visibility = storedVisibility(dao.visibility);
229
288
  const feature = {
230
289
  slug: dao.slug,
@@ -1 +1 @@
1
- {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"AAmGA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGxE;;;;;;;;;;GAUG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,+EAA+E;IAC/E,EAAE;IACF,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,qEAAqE;IACrE,+CAA+C;IAC/C,EAAE;IACF,sEAAsE;IACtE,sEAAsE;IACtE,yEAAyE;IACzE,oEAAoE;IACpE,YAAY;IACZ,UAAU;IACV,SAAS;IACT,cAAc;CACf,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAErD,4EAA4E;AAC5E,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC5F,OAAO,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;AAClE,CAAC;AAED;;6DAE6D;AAC7D,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1F,OAAO,KAA0C,CAAC;AACpD,CAAC;AA0BD,SAAS,YAAY,CAAC,MAAyB;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACrC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,wEAAwE;QACxE,qEAAqE;QACrE,4CAA4C;QAC5C,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChF,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CACrB,GAAsB,EACtB,IAA8B;IAE9B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AAED,mEAAmE;AACnE,SAAS,eAAe,CAAC,GAA2B;IAClD,MAAM,GAAG,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAA0B,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,+EAA+E;AAC/E,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,MAAM,GAAG,KAA6C,CAAC;IAC7D,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACpF,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;KACjG,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,aAAa,CACpB,GAAsB,EACtB,MAAyC,EACzC,WAAmC;IAEnC,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACnF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,GAAG,GAAuB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACtD,CAAC,CAAE,GAAG,CAAC,KAA4B;QACnC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChB,MAAM,QAAQ,GAAY,GAAG,CAAC,MAAM,CAAC;IACrC,MAAM,MAAM,GACV,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;QACvD,CAAC,CAAE,QAA+B;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,YAAY;IACZ,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IACD,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO;QACtC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;aACtE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,SAAS,GAAsB;IACnC,QAAQ;IACR,SAAS;IACT,aAAa;IACb,UAAU;IACV,QAAQ;IACR,QAAQ;CACT,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,YAAY,CACnB,MAAyC,EACzC,WAAmC;IAEnC,MAAM,QAAQ,GAAG,WAAW,EAAE,MAAM,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC9D,MAAM,KAAK,GAAI,QAA8C,CAAC,GAAG,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAClB,GAAsB,EACtB,MAAyC,EACzC,WAAmC;IAEnC,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACjF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,OAAO,eAAe,CAAC,WAAW,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAsB,EACtB,SAA4B,EAAE;IAE9B,OAAO,WAAW,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,0EAA0E;AAC1E,SAAS,WAAW,CAClB,GAAsB,EACtB,IAA8B;IAE9B,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5E,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC9C,CAAC;IACD,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GACX,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACnF,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC;IACvD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEtD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,OAAO,GAAe;QAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM;QACN,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,qEAAqE;QACrE,0EAA0E;QAC1E,wEAAwE;QACxE,mEAAmE;QACnE,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,yEAAyE;QACzE,qEAAqE;QACrE,2BAA2B;QAC3B,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAC;IAEF,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,2EAA2E;IAC3E,wEAAwE;IACxE,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,kCAAkC;IAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAoB;YAC5B,IAAI,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YAClD,wEAAwE;YACxE,kEAAkE;YAClE,wEAAwE;YACxE,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI;YAC7B,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxD,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QACjD,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;QACtC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED;;;mCAGmC;AACnC,MAAM,UAAU,mBAAmB,CACjC,IAAqD,EACrD,SAA4B,EAAE;IAE9B,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CACpC,IAAqD;IAErD,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAChE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAqD;IAErD,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS;QACtE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAqD,EACrD,SAA4B,EAAE;IAE9B,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAsC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import type { UseQueryResult } from "@tanstack/react-query";
2
2
  import type { StapelApiError } from "@stapel/core";
3
3
  import type { ValidationBatchResult } from "@stapel/attributes-react";
4
- import type { ListingDetail, ListingEngagementBatch, ListingPageParams, ListingStatusInfo, MyCounters, PaginatedListingCards } from "../api/types.js";
4
+ import type { ListingDetail, ListingDraft, ListingEngagementBatch, ListingPageParams, ListingStatusInfo, MyCounters, PaginatedListingCards } from "../api/types.js";
5
5
  /**
6
6
  * Read hooks over the listings API (frontend-standard §2). Keys are
7
7
  * namespaced (see `listingsQueryKeys`).
@@ -31,6 +31,20 @@ import type { ListingDetail, ListingEngagementBatch, ListingPageParams, ListingS
31
31
  export declare function useListing(id: number | undefined, options?: {
32
32
  readonly enabled?: boolean;
33
33
  }): UseQueryResult<ListingDetail, StapelApiError>;
34
+ /**
35
+ * The draft twin, read back (`GET /{pk}/draft/`, stapel-listings 0.21.1) —
36
+ * what `useListingComposer` seeds a reopened listing from.
37
+ *
38
+ * `retry: false` for the same reason as {@link useListing}: a 404 here is
39
+ * either "no draft was ever saved" or "this build predates the route", and
40
+ * three retries only delay the moment the composer can fall back to the
41
+ * detail seed. It is a separate query from `useListing` (own cache key),
42
+ * because a host that only reads the detail must not pay for this round
43
+ * trip, and a write to one must not evict the other.
44
+ */
45
+ export declare function useListingDraft(id: number | undefined, options?: {
46
+ readonly enabled?: boolean;
47
+ }): UseQueryResult<ListingDraft, StapelApiError>;
34
48
  /**
35
49
  * The status probe — both axes plus `is_deleted`, for ANY listing id.
36
50
  *
@@ -1 +1 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAKzB;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CAQ/C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAQnD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CASvD;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,CAS7C;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAUvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAUvD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAUxD"}
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAKzB;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CAQ/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,YAAY,EAAE,cAAc,CAAC,CAQ9C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAQnD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CASvD;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,CAS7C;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAUvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAUvD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC,cAAc,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAUxD"}
@@ -38,6 +38,26 @@ export function useListing(id, options) {
38
38
  retry: false,
39
39
  });
40
40
  }
41
+ /**
42
+ * The draft twin, read back (`GET /{pk}/draft/`, stapel-listings 0.21.1) —
43
+ * what `useListingComposer` seeds a reopened listing from.
44
+ *
45
+ * `retry: false` for the same reason as {@link useListing}: a 404 here is
46
+ * either "no draft was ever saved" or "this build predates the route", and
47
+ * three retries only delay the moment the composer can fall back to the
48
+ * detail seed. It is a separate query from `useListing` (own cache key),
49
+ * because a host that only reads the detail must not pay for this round
50
+ * trip, and a write to one must not evict the other.
51
+ */
52
+ export function useListingDraft(id, options) {
53
+ const api = useListingsApi();
54
+ return useQuery({
55
+ queryKey: listingsQueryKeys.draft(id ?? -1),
56
+ queryFn: ({ signal }) => api.draft(id, { signal }),
57
+ enabled: (options?.enabled ?? true) && id !== undefined,
58
+ retry: false,
59
+ });
60
+ }
41
61
  /**
42
62
  * The status probe — both axes plus `is_deleted`, for ANY listing id.
43
63
  *
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,10 @@ export declare const listingsQueryKeys: {
33
33
  allMine(): readonly ["listings", "my", "listings"];
34
34
  /** `GET /{pk}/validate-draft/` — the dry run of a publish. */
35
35
  validateDraft(id: number): readonly ["listings", "validate-draft", number];
36
+ /** `GET /{pk}/draft/` — the draft twin read back (stapel-listings 0.21.1).
37
+ * A separate entry from `detail`: the two answer different questions about
38
+ * the same id and a write to one must not evict the other's cache. */
39
+ draft(id: number): readonly ["listings", "draft", number];
36
40
  /** Every favourites PAGE, for an invalidation after a toggle — the cursor
37
41
  * is not known at the write, so the prefix is what a write can target. */
38
42
  allFavorites(): readonly ["listings", "my", "favorites"];
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.d.ts","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;wBAEwB;AACxB,wBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAMlE;AAID,eAAO,MAAM,iBAAiB,EAAE;IAC9B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,+BAA+B;IAC/B,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1E,2BAA2B;IAC3B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D;;0EAEsE;IACtE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,oCAAoC;IACpC,UAAU,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACtD,gDAAgD;IAChD,WAAW,CACT,IAAI,EAAE,cAAc,GACnB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IAC5D,mEAAmE;IACnE,IAAI,CACF,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,cAAc,GACnB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IACnE;;sCAEkC;IAClC,YAAY,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACpE,+DAA+D;IAC/D,OAAO,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACnD,8DAA8D;IAC9D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC3E;8EAC0E;IAC1E,YAAY,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACzD,8CAA8C;IAC9C,QAAQ,IAAI,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;CAejF,CAAC"}
1
+ {"version":3,"file":"queryKeys.d.ts","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;wBAEwB;AACxB,wBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAMlE;AAID,eAAO,MAAM,iBAAiB,EAAE;IAC9B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,+BAA+B;IAC/B,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1E,2BAA2B;IAC3B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D;;0EAEsE;IACtE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,oCAAoC;IACpC,UAAU,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACtD,gDAAgD;IAChD,WAAW,CACT,IAAI,EAAE,cAAc,GACnB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IAC5D,mEAAmE;IACnE,IAAI,CACF,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,cAAc,GACnB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IACnE;;sCAEkC;IAClC,YAAY,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACpE,+DAA+D;IAC/D,OAAO,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACnD,8DAA8D;IAC9D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC3E;;0EAEsE;IACtE,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1D;8EAC0E;IAC1E,YAAY,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACzD,8CAA8C;IAC9C,QAAQ,IAAI,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;CAgBjF,CAAC"}
@@ -34,6 +34,7 @@ export const listingsQueryKeys = {
34
34
  mineUntabbed: () => [ROOT, "my", "listings", "untabbed"],
35
35
  allMine: () => [ROOT, "my", "listings"],
36
36
  validateDraft: (id) => [ROOT, "validate-draft", id],
37
+ draft: (id) => [ROOT, "draft", id],
37
38
  allFavorites: () => [ROOT, "my", "favorites"],
38
39
  allLists: () => [ROOT, "list"],
39
40
  engagement: (ids) => [ROOT, "engagement", engagementIds(ids).join(",")],
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAUhD;;wBAEwB;AACxB,MAAM,UAAU,OAAO,CAAC,MAA0B;IAChD,OAAO;QACL,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;QAC9B,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI;QACpC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG,UAAmB,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GA8C1B;IACF,GAAG,EAAE,CAAC,IAAI,CAAC;IACX,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IACpC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IACpC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC;IACtD,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC;IACxD,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC;IACxD,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;IACvC,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC;IACnD,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC;IAC7C,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;CACxE,CAAC"}
1
+ {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAUhD;;wBAEwB;AACxB,MAAM,UAAU,OAAO,CAAC,MAA0B;IAChD,OAAO;QACL,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;QAC9B,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI;QACpC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG,UAAmB,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAkD1B;IACF,GAAG,EAAE,CAAC,IAAI,CAAC;IACX,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IACpC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IACpC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC;IACtD,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC;IACxD,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC;IACxD,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;IACvC,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC;IACnD,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC;IAC7C,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;CACxE,CAAC"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/listings-react 0.22.1
1
+ # @stapel/listings-react 0.24.0
2
2
 
3
3
  Headless React flow pair for stapel-listings (contract >=0.21 <0.22) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
@@ -25,6 +25,7 @@ Paths are relative to `/listings/api/v1/`.
25
25
  - listings_api_v1_listings_complete_create: POST /listings/{id}/complete/
26
26
  - listings_api_v1_listings_create: POST /listings/
27
27
  - listings_api_v1_listings_destroy: DELETE /listings/{id}/
28
+ - listings_api_v1_listings_draft_retrieve: GET /listings/{id}/draft/
28
29
  - listings_api_v1_listings_engagement_retrieve: GET /listings/engagement/
29
30
  - listings_api_v1_listings_favorite_create: POST /listings/{id}/favorite/
30
31
  - listings_api_v1_listings_list: GET /listings/
@@ -49,6 +50,7 @@ Paths are relative to `/listings/api/v1/`.
49
50
  - useFavoriteListing (mutation) → favorite+unfavorite
50
51
  - useListing (query) → retrieve
51
52
  - useListingCards (query) → list
53
+ - useListingDraft (query) → draft
52
54
  - useListingEngagement (query) → engagement
53
55
  - useListingStatus (query) → status
54
56
  - useMyCounters (query) → myCounters
@@ -59,7 +61,7 @@ Paths are relative to `/listings/api/v1/`.
59
61
  - useValidateDraft (query) → validateDraft
60
62
 
61
63
  ## Errors (render t(code, params); UX from remediation)
62
- 68 keys (full catalog: manifest.json §errors). By remediation: fix_input 39 · retry 16 · verify 5 · wait_and_retry 5 · contact_support 2 · reauthenticate 1.
64
+ 69 keys (full catalog: manifest.json §errors). By remediation: fix_input 40 · retry 16 · verify 5 · wait_and_retry 5 · contact_support 2 · reauthenticate 1.
63
65
  Param-bearing keys (interpolation slots matter):
64
66
  - error.400.description_too_long [400] → fix_input {max_length}
65
67
  - error.400.description_too_short [400] → fix_input {min_length}
@@ -85,6 +87,7 @@ Param-bearing keys (interpolation slots matter):
85
87
  - error.400.field.null [400] → fix_input {field}
86
88
  - error.400.field.required [400] → fix_input {field}
87
89
  - error.400.field.unique [400] → fix_input {field}
90
+ - error.400.listing_draft_meta_too_large [400] → fix_input {max_bytes}
88
91
  - error.400.listing_feature_not_allowed [400] → fix_input {feature}
89
92
  - error.400.listing_invalid_status_filter [400] → fix_input {status}
90
93
  - error.409.invalid_listing_transition [409] → fix_input {from_status}
@@ -120,6 +123,7 @@ const { tracked } = useTracked();
120
123
  - listings.parts → <ListingStatusBlock> [default|tags|notes|media|door] demo/ListingParts.demo.tsx
121
124
  - listings.photo-strip → <ListingPhotoStrip> [default|single|no photos] demo/ListingPhotoStrip.demo.tsx
122
125
  - listings.serp-card → <ListingSerpCard> [default|trend|visitor|desktop row|bare] demo/ListingSerpCard.demo.tsx
126
+ - listings.spec-parts → <CardBadges> [contract|legacy|specs|specs-split] demo/ListingSpecParts.demo.tsx
123
127
  Each source file is the canonical usage snippet (open the default variant).
124
128
 
125
129
  ## Snippets
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
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.22.1",
4
+ "version": "0.24.0",
5
5
  "backend": {
6
6
  "module": "stapel-listings",
7
7
  "contract": ">=0.21 <0.22"
@@ -44,6 +44,13 @@
44
44
  "request": null,
45
45
  "response": "DeleteResponse"
46
46
  },
47
+ "listings_api_v1_listings_draft_retrieve": {
48
+ "method": "GET",
49
+ "path": "/listings/api/v1/listings/{id}/draft/",
50
+ "tag": "listings",
51
+ "request": null,
52
+ "response": "ListingDraft"
53
+ },
47
54
  "listings_api_v1_listings_engagement_retrieve": {
48
55
  "method": "GET",
49
56
  "path": "/listings/api/v1/listings/engagement/",
@@ -225,6 +232,15 @@
225
232
  "{page}"
226
233
  ]
227
234
  },
235
+ "useListingDraft": {
236
+ "kind": "query",
237
+ "operation": "draft",
238
+ "queryKey": [
239
+ "listings",
240
+ "draft",
241
+ "{id}"
242
+ ]
243
+ },
228
244
  "useListingEngagement": {
229
245
  "kind": "query",
230
246
  "operation": "engagement",
@@ -492,6 +508,13 @@
492
508
  "params": [],
493
509
  "remediation": "fix_input"
494
510
  },
511
+ "error.400.listing_draft_meta_too_large": {
512
+ "status": 400,
513
+ "params": [
514
+ "max_bytes"
515
+ ],
516
+ "remediation": "fix_input"
517
+ },
495
518
  "error.400.listing_feature_not_allowed": {
496
519
  "status": 400,
497
520
  "params": [
@@ -890,6 +913,27 @@
890
913
  "bare"
891
914
  ],
892
915
  "source": "demo/ListingSerpCard.demo.tsx"
916
+ },
917
+ {
918
+ "id": "listings.spec-parts",
919
+ "title": "Badges and specs",
920
+ "description": "A badge says which question it answers, and a spec sheet is a definition list rather than a table. Both are drawn by the SERVER's decision about presentation, not by a client-side heuristic: the right badge for a value depends on the category — '3 rooms' wants its name, 'Brick' is a boolean whose name IS the badge, and '20 000 km' wants its unit and no name at all.",
921
+ "component": "CardBadges",
922
+ "covers": [
923
+ "CardSpecLine",
924
+ "ListingSpecColumns",
925
+ "ListingSpecList"
926
+ ],
927
+ "tokens": [
928
+ "text-subtle"
929
+ ],
930
+ "variants": [
931
+ "contract",
932
+ "legacy",
933
+ "specs",
934
+ "specs-split"
935
+ ],
936
+ "source": "demo/ListingSpecParts.demo.tsx"
893
937
  }
894
938
  ],
895
939
  "i18nKeys": [
@@ -924,6 +968,7 @@
924
968
  "error.400.field.unique",
925
969
  "error.400.image_required",
926
970
  "error.400.invalid_ad_id",
971
+ "error.400.listing_draft_meta_too_large",
927
972
  "error.400.listing_feature_not_allowed",
928
973
  "error.400.listing_invalid_status_filter",
929
974
  "error.400.listing_location_required",
@@ -1144,8 +1189,12 @@
1144
1189
  "PRICE_FIELD",
1145
1190
  "TITLE_FIELD",
1146
1191
  "asFeatureDaoList",
1192
+ "badgePresentation",
1193
+ "badgeValueText",
1147
1194
  "canDelete",
1148
1195
  "canTransition",
1196
+ "cardBadgeText",
1197
+ "cardBadgeTexts",
1149
1198
  "createDraftBody",
1150
1199
  "createListingsApi",
1151
1200
  "createListingsRuntime",
@@ -1161,10 +1210,13 @@
1161
1210
  "explainListingsError",
1162
1211
  "failedResults",
1163
1212
  "featureFromDao",
1213
+ "featureUnit",
1164
1214
  "featureValuesForDisplay",
1165
1215
  "featuresDtoFromDaoList",
1166
1216
  "featuresFromDaoList",
1167
1217
  "flowEndpoints",
1218
+ "formatSpecValue",
1219
+ "hasCardBadgeContract",
1168
1220
  "isBatchValid",
1169
1221
  "isListingViewed",
1170
1222
  "isPubliclyVisible",
@@ -1205,6 +1257,7 @@
1205
1257
  "useListingCards",
1206
1258
  "useListingComposer",
1207
1259
  "useListingDetail",
1260
+ "useListingDraft",
1208
1261
  "useListingEngagement",
1209
1262
  "useListingEngagementOverlay",
1210
1263
  "useListingEngagementScope",
@@ -1223,6 +1276,9 @@
1223
1276
  "withEngagement"
1224
1277
  ],
1225
1278
  "types": [
1279
+ "CardBadgeContract",
1280
+ "CardBadgePresentation",
1281
+ "CardBadgeRow",
1226
1282
  "ComposeStage",
1227
1283
  "CreateListingsRuntimeOptions",
1228
1284
  "DeleteResponse",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/listings-react",
3
- "version": "0.22.1",
3
+ "version": "0.24.0",
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.22.1",
3
+ "version": "0.24.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": {
@@ -48,14 +48,14 @@
48
48
  ],
49
49
  "size-limit": [
50
50
  {
51
- "name": "index — the headless pair (client + status axes + draft model + hooks): no antd. Raised 11 -> 12 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. Raised 11.5 -> 12 KB for envelopeFieldErrors and its API-field -> control table: a save-draft/create 400 names its field in the envelope rather than in a publish batch, and without the table the refusal had nowhere to land — which is how one over-precise coordinate painted two unreadable banners and left every control clean. Thirty-six bytes of routing table is what a legible refusal costs. Raised 12 -> 13 KB for two seams the mobile wave needed in the HEADLESS half: the category-feature copy source in model/features.ts (the option table a stored select does not carry, so a published listing prints \"Second-hand\" and not \"b-u\"), and firstUnsatisfied (the field a \"10 required details are still empty\" count actually points at, in the order the form asks). Both are model, not skin: a headless host renders its own controls and needs the same two answers. Raised 13 -> 14 KB (measured 12.91) for the engagement overlay: a batch read, its normalized key, and the scope that runs it once for a page and hands every card its own entry. It is a whole new READ rather than a flag — and it is the read that makes the viewed/saved state visible at all on a feed and a SERP, which come from the search index and carry no per-viewer field. Landing at 12.91 of 13 would have been a budget passed by rounding",
51
+ "name": "index — the headless pair (client + status axes + draft model + hooks): no antd. Raised 11 -> 12 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. Raised 11.5 -> 12 KB for envelopeFieldErrors and its API-field -> control table: a save-draft/create 400 names its field in the envelope rather than in a publish batch, and without the table the refusal had nowhere to land — which is how one over-precise coordinate painted two unreadable banners and left every control clean. Thirty-six bytes of routing table is what a legible refusal costs. Raised 12 -> 13 KB for two seams the mobile wave needed in the HEADLESS half: the category-feature copy source in model/features.ts (the option table a stored select does not carry, so a published listing prints \"Second-hand\" and not \"b-u\"), and firstUnsatisfied (the field a \"10 required details are still empty\" count actually points at, in the order the form asks). Both are model, not skin: a headless host renders its own controls and needs the same two answers. Raised 13 -> 14 KB (measured 12.91) for the engagement overlay: a batch read, its normalized key, and the scope that runs it once for a page and hands every card its own entry. It is a whole new READ rather than a flag — and it is the read that makes the viewed/saved state visible at all on a feed and a SERP, which come from the search index and carry no per-viewer field. Landing at 12.91 of 13 would have been a budget passed by rounding. Raised 14 -> 15 KB (measured 14.39) for the two model modules the listing-page wave added to the HEADLESS half: model/featureText.ts, which typesets a numeric value instead of stringifying it (its unit resolved from the definition, its digits through Intl.NumberFormat — the live page read 'Power 173' and 'Mileage 20000'), and model/cardBadges.ts, the card badge contract's four presentations plus the detector that falls back to the old rendering on an older backend. Both are answers a headless host needs as much as the skin does: a container drawing its own spec rows has the same value and the same missing unit.",
52
52
  "path": "dist/index.js",
53
- "limit": "14 KB"
53
+ "limit": "15 KB"
54
54
  },
55
55
  {
56
- "name": "default — the antd skin (three cards, detail, composer, dashboard, the named slots and the delete confirmation) must stay out of the main bundle. Raised 17 -> 19 KB for the mobile wave: <ListingSerpCard> (photo strip + price-first block + action rail), <ListingFeedCard> and <FeedGrid> are two more card surfaces on the same shared target/favourite/photo parts, not three copies of one Raised 19 -> 20 KB for the desktop wave of the detail page: layout=\"split\" is a second ASSEMBLY of the money page (the sticky buy column, the two-column spec table, the widened measure) over the same parts, and GateReasonPopover is the blocked heart's third volume — the reason and the door disclosed on interaction, with the visually-hidden copy that keeps the refusal in the accessibility tree. Both are geometry and wiring, not new widgets. Raised 20 -> 21 KB (measured 20.22) for the engagement wave, which is four small things and no new component: the disclosure became a controlled open/close so a pointer that hovers and then clicks does not shut the only explanation the control has; the heart draws a filled accent when saved and states a failed save through the shared ErrorAlert; an already-seen card dims through one rule in the sheet all three cards already hoist; and the listing page gained a view-count row. 216 bytes is what a control that reports its own outcome costs. Raised 21 -> 22 KB for the seller's board becoming a door in both directions: the transition route and useTransitionListing, OWNER_TRANSITIONS/ownerMoves as the fallback mirror, ListingActionsBag.moves drawn in a stable order, listingHref/linkComponent on the cabinet pane, the refusal that stops quoting the wire, and the row that fits a phone. Measured on a clean tree, this package's src reverted to the previous commit with dependencies held constant: 20.82 -> 21.60 KB. The old ceiling had 180 B of room and the work needs 780; none of it is copy, and a fourth axis of owner state is not a rounding error",
56
+ "name": "default — the antd skin (three cards, detail, composer, dashboard, the named slots and the delete confirmation) must stay out of the main bundle. Raised 17 -> 19 KB for the mobile wave: <ListingSerpCard> (photo strip + price-first block + action rail), <ListingFeedCard> and <FeedGrid> are two more card surfaces on the same shared target/favourite/photo parts, not three copies of one Raised 19 -> 20 KB for the desktop wave of the detail page: layout=\"split\" is a second ASSEMBLY of the money page (the sticky buy column, the two-column spec table, the widened measure) over the same parts, and GateReasonPopover is the blocked heart's third volume — the reason and the door disclosed on interaction, with the visually-hidden copy that keeps the refusal in the accessibility tree. Both are geometry and wiring, not new widgets. Raised 20 -> 21 KB (measured 20.22) for the engagement wave, which is four small things and no new component: the disclosure became a controlled open/close so a pointer that hovers and then clicks does not shut the only explanation the control has; the heart draws a filled accent when saved and states a failed save through the shared ErrorAlert; an already-seen card dims through one rule in the sheet all three cards already hoist; and the listing page gained a view-count row. 216 bytes is what a control that reports its own outcome costs. Raised 21 -> 22 KB for the seller's board becoming a door in both directions: the transition route and useTransitionListing, OWNER_TRANSITIONS/ownerMoves as the fallback mirror, ListingActionsBag.moves drawn in a stable order, listingHref/linkComponent on the cabinet pane, the refusal that stops quoting the wire, and the row that fits a phone. Measured on a clean tree, this package's src reverted to the previous commit with dependencies held constant: 20.82 -> 21.60 KB. The old ceiling had 180 B of room and the work needs 780; none of it is copy, and a fourth axis of owner state is not a rounding error. Raised 22 -> 25 KB (measured 23.94) for the three surfaces of the same wave: <ListingSpecList>/<ListingSpecColumns>, which is a REPLACEMENT of antd's <Descriptions> with a paragraph row (an inline muted label and the value in one text flow, so a long answer wraps at the measure instead of stacking inside a third-of-a-page cell) and therefore carries its own hoisted sheet; <CardBadges>/<CardSpecLine>, one badge renderer for all three card surfaces with the pre-contract path kept whole beside it; and cardGallery.ts, the hover-scrub and swipe gestures — a segment map, a horizontal-intent threshold, the pointer-capability gate and the touch-action rule that leaves the page's vertical scroll to the browser. A gallery a card did not have and a spec list rebuilt from a table are not a rounding error.",
57
57
  "path": "dist/default/index.js",
58
- "limit": "22 KB"
58
+ "limit": "25 KB"
59
59
  },
60
60
  {
61
61
  "name": "i18n/ru — the Russian bundle is opt-in, not carried by the main entry",