@stapel/vocabularies-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.
Files changed (130) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +21 -0
  3. package/MODULE.md +92 -0
  4. package/README.md +173 -0
  5. package/dist/api/extensions.d.ts +8 -0
  6. package/dist/api/extensions.d.ts.map +1 -0
  7. package/dist/api/extensions.js +8 -0
  8. package/dist/api/extensions.js.map +1 -0
  9. package/dist/api/generated/schema.d.ts +234 -0
  10. package/dist/api/generated/schema.d.ts.map +1 -0
  11. package/dist/api/generated/schema.js +2 -0
  12. package/dist/api/generated/schema.js.map +1 -0
  13. package/dist/api/types.d.ts +23 -0
  14. package/dist/api/types.d.ts.map +1 -0
  15. package/dist/api/types.js +2 -0
  16. package/dist/api/types.js.map +1 -0
  17. package/dist/api/vocabulariesApi.d.ts +14 -0
  18. package/dist/api/vocabulariesApi.d.ts.map +1 -0
  19. package/dist/api/vocabulariesApi.js +4 -0
  20. package/dist/api/vocabulariesApi.js.map +1 -0
  21. package/dist/client.d.ts +49 -0
  22. package/dist/client.d.ts.map +1 -0
  23. package/dist/client.js +118 -0
  24. package/dist/client.js.map +1 -0
  25. package/dist/default/VocabularyTermSelect.d.ts +24 -0
  26. package/dist/default/VocabularyTermSelect.d.ts.map +1 -0
  27. package/dist/default/VocabularyTermSelect.js +75 -0
  28. package/dist/default/VocabularyTermSelect.js.map +1 -0
  29. package/dist/default/index.d.ts +16 -0
  30. package/dist/default/index.d.ts.map +1 -0
  31. package/dist/default/index.js +14 -0
  32. package/dist/default/index.js.map +1 -0
  33. package/dist/default/types.d.ts +12 -0
  34. package/dist/default/types.d.ts.map +1 -0
  35. package/dist/default/types.js +2 -0
  36. package/dist/default/types.js.map +1 -0
  37. package/dist/flows/errors.d.ts +12 -0
  38. package/dist/flows/errors.d.ts.map +1 -0
  39. package/dist/flows/errors.js +13 -0
  40. package/dist/flows/errors.js.map +1 -0
  41. package/dist/flows/registry.d.ts +22 -0
  42. package/dist/flows/registry.d.ts.map +1 -0
  43. package/dist/flows/registry.js +20 -0
  44. package/dist/flows/registry.js.map +1 -0
  45. package/dist/headless/VocabulariesProvider.d.ts +19 -0
  46. package/dist/headless/VocabulariesProvider.d.ts.map +1 -0
  47. package/dist/headless/VocabulariesProvider.js +15 -0
  48. package/dist/headless/VocabulariesProvider.js.map +1 -0
  49. package/dist/i18n/errorsMap.d.ts +10 -0
  50. package/dist/i18n/errorsMap.d.ts.map +1 -0
  51. package/dist/i18n/errorsMap.js +20 -0
  52. package/dist/i18n/errorsMap.js.map +1 -0
  53. package/dist/i18n/es.d.ts +21 -0
  54. package/dist/i18n/es.d.ts.map +1 -0
  55. package/dist/i18n/es.js +38 -0
  56. package/dist/i18n/es.js.map +1 -0
  57. package/dist/i18n/generated/errors.es.gen.d.ts +16 -0
  58. package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -0
  59. package/dist/i18n/generated/errors.es.gen.js +58 -0
  60. package/dist/i18n/generated/errors.es.gen.js.map +1 -0
  61. package/dist/i18n/generated/errors.gen.d.ts +305 -0
  62. package/dist/i18n/generated/errors.gen.d.ts.map +1 -0
  63. package/dist/i18n/generated/errors.gen.js +156 -0
  64. package/dist/i18n/generated/errors.gen.js.map +1 -0
  65. package/dist/i18n/generated/errors.ru.gen.d.ts +16 -0
  66. package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -0
  67. package/dist/i18n/generated/errors.ru.gen.js +58 -0
  68. package/dist/i18n/generated/errors.ru.gen.js.map +1 -0
  69. package/dist/i18n/keys.d.ts +33 -0
  70. package/dist/i18n/keys.d.ts.map +1 -0
  71. package/dist/i18n/keys.js +44 -0
  72. package/dist/i18n/keys.js.map +1 -0
  73. package/dist/i18n/ru.d.ts +26 -0
  74. package/dist/i18n/ru.d.ts.map +1 -0
  75. package/dist/i18n/ru.js +43 -0
  76. package/dist/i18n/ru.js.map +1 -0
  77. package/dist/index.d.ts +34 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +38 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/model/context.d.ts +11 -0
  82. package/dist/model/context.d.ts.map +1 -0
  83. package/dist/model/context.js +16 -0
  84. package/dist/model/context.js.map +1 -0
  85. package/dist/model/queryKeys.d.ts +5 -0
  86. package/dist/model/queryKeys.d.ts.map +1 -0
  87. package/dist/model/queryKeys.js +28 -0
  88. package/dist/model/queryKeys.js.map +1 -0
  89. package/dist/model/runtime.d.ts +17 -0
  90. package/dist/model/runtime.d.ts.map +1 -0
  91. package/dist/model/runtime.js +6 -0
  92. package/dist/model/runtime.js.map +1 -0
  93. package/dist/model/useTermLabels.d.ts +26 -0
  94. package/dist/model/useTermLabels.d.ts.map +1 -0
  95. package/dist/model/useTermLabels.js +58 -0
  96. package/dist/model/useTermLabels.js.map +1 -0
  97. package/dist/model/useTermSearch.d.ts +24 -0
  98. package/dist/model/useTermSearch.d.ts.map +1 -0
  99. package/dist/model/useTermSearch.js +85 -0
  100. package/dist/model/useTermSearch.js.map +1 -0
  101. package/llms.txt +79 -0
  102. package/manifest.json +466 -0
  103. package/package.json +108 -0
  104. package/src/analytics/generated/events.json +7 -0
  105. package/src/api/extensions.ts +7 -0
  106. package/src/api/generated/schema.ts +236 -0
  107. package/src/api/types.ts +27 -0
  108. package/src/api/vocabulariesApi.ts +17 -0
  109. package/src/client.ts +176 -0
  110. package/src/default/VocabularyTermSelect.tsx +147 -0
  111. package/src/default/index.ts +15 -0
  112. package/src/default/types.ts +11 -0
  113. package/src/flows/errors.ts +16 -0
  114. package/src/flows/registry.ts +32 -0
  115. package/src/headless/VocabulariesProvider.tsx +20 -0
  116. package/src/i18n/errorsMap.ts +31 -0
  117. package/src/i18n/es.ts +49 -0
  118. package/src/i18n/generated/errors.es.gen.ts +64 -0
  119. package/src/i18n/generated/errors.gen.ts +187 -0
  120. package/src/i18n/generated/errors.json +351 -0
  121. package/src/i18n/generated/errors.ru.gen.ts +64 -0
  122. package/src/i18n/keys.ts +53 -0
  123. package/src/i18n/ru.ts +54 -0
  124. package/src/index.ts +92 -0
  125. package/src/model/context.tsx +28 -0
  126. package/src/model/queryKeys.ts +35 -0
  127. package/src/model/runtime.ts +25 -0
  128. package/src/model/useTermLabels.ts +72 -0
  129. package/src/model/useTermSearch.ts +118 -0
  130. package/tsconfig.json +26 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `useTermSearch` — a typeahead over ONE vocabulary level.
3
+ *
4
+ * The level is the wrong size to hold (529 phone vendors is fine, 14 962
5
+ * models is not), so the options ARE the answer to the current query and the
6
+ * hook's whole job is to make sure the answer on screen belongs to the query
7
+ * on screen:
8
+ *
9
+ * - a keystroke DEBOUNCES (250 ms by default) — one request per pause, not
10
+ * per character;
11
+ * - a new request ABORTS the one before it, and a resolved-but-superseded
12
+ * answer is dropped, because the network does not promise order;
13
+ * - opening is not typing: the first page is fetched immediately (a spinner
14
+ * that starts a quarter second after the click reads as a dead control),
15
+ * ONCE per (vocabulary, level, parent) — antd reports the dropdown as
16
+ * opening on every keystroke, so a naive `open()` is a request storm nobody
17
+ * can see in a screenshot;
18
+ * - a parent CHANGE empties the list: what is listed are the previous
19
+ * parent's children and must not stay pickable.
20
+ *
21
+ * The client is a PARAMETER, not a context read: this hook is one half of the
22
+ * seam `@stapel/attributes-react` declares, and a host wires the client at its
23
+ * composition root. Passing `null` is a supported state (the control draws its
24
+ * unavailable notice) rather than a crash.
25
+ */
26
+ import { useCallback, useEffect, useRef, useState } from "react";
27
+ /** The pause after the last keystroke before a query goes to the server. Long
28
+ * enough that typing a word is one request, short enough that it still feels
29
+ * like the control answered. Mirrors the ref editors in attributes-react. */
30
+ export const TERM_SEARCH_DEBOUNCE_MS = 250;
31
+ export function useTermSearch(client, options) {
32
+ const { vocabulary, level, parent, debounceMs = TERM_SEARCH_DEBOUNCE_MS } = options;
33
+ const [terms, setTerms] = useState([]);
34
+ const [loading, setLoading] = useState(false);
35
+ const inFlight = useRef(undefined);
36
+ const timer = useRef(undefined);
37
+ const asked = useRef(false);
38
+ const run = useCallback((query) => {
39
+ if (client === null || vocabulary.length === 0 || level.length === 0)
40
+ return;
41
+ inFlight.current?.abort();
42
+ const controller = new AbortController();
43
+ inFlight.current = controller;
44
+ setLoading(true);
45
+ client
46
+ .search(vocabulary, level, query, parent, controller.signal)
47
+ .then((found) => {
48
+ if (controller.signal.aborted)
49
+ return;
50
+ setTerms(found);
51
+ setLoading(false);
52
+ })
53
+ .catch(() => {
54
+ // A superseded request is not a failure and must not clear the list
55
+ // the CURRENT request is about to fill.
56
+ if (controller.signal.aborted)
57
+ return;
58
+ setTerms([]);
59
+ setLoading(false);
60
+ });
61
+ }, [client, vocabulary, level, parent]);
62
+ useEffect(() => {
63
+ asked.current = false;
64
+ setTerms([]);
65
+ }, [client, vocabulary, level, parent]);
66
+ useEffect(() => () => {
67
+ if (timer.current !== undefined)
68
+ clearTimeout(timer.current);
69
+ inFlight.current?.abort();
70
+ }, []);
71
+ const search = useCallback((query) => {
72
+ asked.current = true;
73
+ if (timer.current !== undefined)
74
+ clearTimeout(timer.current);
75
+ timer.current = setTimeout(() => run(query), debounceMs);
76
+ }, [run, debounceMs]);
77
+ const open = useCallback(() => {
78
+ if (asked.current)
79
+ return;
80
+ asked.current = true;
81
+ run("");
82
+ }, [run]);
83
+ return { terms, loading, search, open };
84
+ }
85
+ //# sourceMappingURL=useTermSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTermSearch.js","sourceRoot":"","sources":["../../src/model/useTermSearch.ts"],"names":[],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,79 @@
1
+ # @stapel/vocabularies-react 0.1.0
2
+
3
+ Headless React flow pair for stapel-vocabularies (contract >=0.1 <0.2) — business + state, zero visual opinion.
4
+ Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
5
+ verification-403 interception, i18n engine, analytics facade, TanStack Query layer.
6
+
7
+ ## The one right way (do this, the rest is a review/lint smell)
8
+ - No raw fetch/axios. The client is injected via <VocabulariesProvider>/StapelConfigProvider;
9
+ every hook and flow already carries auth, refresh, and the error envelope.
10
+ - Render errors, never try/catch them: a flow's state carries FlowError{code,params};
11
+ render `t(code, params)` and branch on `explainVocabulariesError(code)` remediation.
12
+ - Server state = the use* hooks (query layer); keys come only from vocabulariesQueryKeys.
13
+ - User strings = i18n keys (registerVocabulariesI18n); never string literals.
14
+ - Sign-in UI = a headless flow component; copy it (shadcn-style) to restyle.
15
+
16
+ ## Layers
17
+ api (typed client) · model (hooks, session) · flows (machines) · headless · i18n
18
+
19
+ ## Documented flows (flows.json — canonical id, steps, endpoints)
20
+
21
+ ## Operations (typed; use the named op, never a path string)
22
+ Request/response schema names are in manifest.json + the generated types.
23
+ Paths are relative to `/vocabularies/api/v1/`.
24
+ - vocabularies_api_v1_vocabularies_list: GET /vocabularies/
25
+ - vocabularies_api_v1_vocabularies_retrieve: GET /vocabularies/{slug}/
26
+ - vocabularies_api_v1_vocabularies_terms_resolve_retrieve: GET /vocabularies/{slug}/terms/resolve/
27
+ - vocabularies_api_v1_vocabularies_terms_retrieve: GET /vocabularies/{slug}/terms/
28
+
29
+ ## Query hooks (server state; keys come only from the key factory)
30
+ - useTermLabels (query) → —
31
+
32
+ ## Errors (render t(code, params); UX from remediation)
33
+ 45 keys (full catalog: manifest.json §errors). By remediation: fix_input 17 · retry 15 · verify 5 · wait_and_retry 5 · contact_support 2 · reauthenticate 1.
34
+ Param-bearing keys (interpolation slots matter):
35
+ - error.400.field.blank [400] → fix_input {field}
36
+ - error.400.field.does_not_exist [400] → fix_input {field}
37
+ - error.400.field.invalid [400] → fix_input {field}
38
+ - error.400.field.invalid_choice [400] → fix_input {field}
39
+ - error.400.field.max_length [400] → fix_input {field,max_length}
40
+ - error.400.field.max_value [400] → fix_input {field,max_value}
41
+ - error.400.field.min_length [400] → fix_input {field,min_length}
42
+ - error.400.field.min_value [400] → fix_input {field,min_value}
43
+ - error.400.field.null [400] → fix_input {field}
44
+ - error.400.field.required [400] → fix_input {field}
45
+ - error.400.field.unique [400] → fix_input {field}
46
+ - error.400.vocabularies_bad_parent [400] → fix_input {parent,level}
47
+ - error.404.vocabularies_level_not_found [404] → retry {vocabulary,level}
48
+ - error.429.rate_limit [429] → wait_and_retry {retry_after_minutes}
49
+
50
+ ## Analytics events (typed; defineEvent → events.json, drift-gated)
51
+ - (no app defineEvent() in this pair — its analytic events are the
52
+ auto-instrumented flow funnels below)
53
+
54
+ ## Flow funnels (auto-instrumented: flow.<id>.<step> {phase})
55
+
56
+ ```tsx
57
+ // Typed event + tracked() click (the one right way; §3.1).
58
+ const planSelected = defineEvent({
59
+ name: "pricing.plan.selected",
60
+ description: "User picked a plan",
61
+ props: { plan: prop.oneOf(["free", "pro", "team"], "Plan code") },
62
+ });
63
+ const { tracked } = useTracked();
64
+ <Button onClick={tracked(planSelected, { plan }, startCheckout)} />
65
+ // A click that STEPS a flow machine is already instrumented — mark it
66
+ // data-analytics="flow" instead; tracked() on top double-counts (§3.2).
67
+ ```
68
+
69
+ ## Demos (defineDemo → manifest.demos; compiled, linted, rendered examples)
70
+ - vocabularies.provider → <VocabulariesProvider> [default] demo/Vocabularies.demo.tsx
71
+ - vocabularies.term-select → <VocabularyTermSelect> [default|phone|narrowed|multiple|unavailable] demo/VocabularyTermSelect.demo.tsx
72
+ Each source file is the canonical usage snippet (open the default variant).
73
+
74
+ ## Snippets
75
+ ```tsx
76
+ // Error rendering + remediation branch (one pattern for every pair).
77
+ const r = explainVocabulariesError(err.code); // 'wait_and_retry' | 'verify' | ...
78
+ return <Alert action={r}>{t(err.code, err.params)}</Alert>;
79
+ ```
package/manifest.json ADDED
@@ -0,0 +1,466 @@
1
+ {
2
+ "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
+ "package": "@stapel/vocabularies-react",
4
+ "version": "0.1.0",
5
+ "backend": {
6
+ "module": "stapel-vocabularies",
7
+ "contract": ">=0.1 <0.2"
8
+ },
9
+ "layers": [
10
+ "api",
11
+ "model",
12
+ "flows",
13
+ "headless",
14
+ "i18n"
15
+ ],
16
+ "flows": {},
17
+ "machines": [],
18
+ "operations": {
19
+ "vocabularies_api_v1_vocabularies_list": {
20
+ "method": "GET",
21
+ "path": "/vocabularies/api/v1/vocabularies/",
22
+ "tag": "vocabularies",
23
+ "request": null,
24
+ "response": null
25
+ },
26
+ "vocabularies_api_v1_vocabularies_retrieve": {
27
+ "method": "GET",
28
+ "path": "/vocabularies/api/v1/vocabularies/{slug}/",
29
+ "tag": "vocabularies",
30
+ "request": null,
31
+ "response": "Vocabulary"
32
+ },
33
+ "vocabularies_api_v1_vocabularies_terms_resolve_retrieve": {
34
+ "method": "GET",
35
+ "path": "/vocabularies/api/v1/vocabularies/{slug}/terms/resolve/",
36
+ "tag": "vocabularies",
37
+ "request": null,
38
+ "response": null
39
+ },
40
+ "vocabularies_api_v1_vocabularies_terms_retrieve": {
41
+ "method": "GET",
42
+ "path": "/vocabularies/api/v1/vocabularies/{slug}/terms/",
43
+ "tag": "vocabularies",
44
+ "request": null,
45
+ "response": "TermPage"
46
+ }
47
+ },
48
+ "hooks": {
49
+ "useTermLabels": {
50
+ "kind": "query",
51
+ "queryKey": [
52
+ "vocabularies",
53
+ "termLabels",
54
+ "{vocabulary}",
55
+ "{level}",
56
+ "{…}"
57
+ ]
58
+ }
59
+ },
60
+ "errors": {
61
+ "error.400.bad_request": {
62
+ "status": 400,
63
+ "params": [],
64
+ "remediation": "fix_input"
65
+ },
66
+ "error.400.captcha_invalid": {
67
+ "status": 400,
68
+ "params": [],
69
+ "remediation": "retry"
70
+ },
71
+ "error.400.captcha_required": {
72
+ "status": 400,
73
+ "params": [],
74
+ "remediation": "retry"
75
+ },
76
+ "error.400.expected_list": {
77
+ "status": 400,
78
+ "params": [],
79
+ "remediation": "fix_input"
80
+ },
81
+ "error.400.field.blank": {
82
+ "status": 400,
83
+ "params": [
84
+ "field"
85
+ ],
86
+ "remediation": "fix_input"
87
+ },
88
+ "error.400.field.does_not_exist": {
89
+ "status": 400,
90
+ "params": [
91
+ "field"
92
+ ],
93
+ "remediation": "fix_input"
94
+ },
95
+ "error.400.field.invalid": {
96
+ "status": 400,
97
+ "params": [
98
+ "field"
99
+ ],
100
+ "remediation": "fix_input"
101
+ },
102
+ "error.400.field.invalid_choice": {
103
+ "status": 400,
104
+ "params": [
105
+ "field"
106
+ ],
107
+ "remediation": "fix_input"
108
+ },
109
+ "error.400.field.max_length": {
110
+ "status": 400,
111
+ "params": [
112
+ "field",
113
+ "max_length"
114
+ ],
115
+ "remediation": "fix_input"
116
+ },
117
+ "error.400.field.max_value": {
118
+ "status": 400,
119
+ "params": [
120
+ "field",
121
+ "max_value"
122
+ ],
123
+ "remediation": "fix_input"
124
+ },
125
+ "error.400.field.min_length": {
126
+ "status": 400,
127
+ "params": [
128
+ "field",
129
+ "min_length"
130
+ ],
131
+ "remediation": "fix_input"
132
+ },
133
+ "error.400.field.min_value": {
134
+ "status": 400,
135
+ "params": [
136
+ "field",
137
+ "min_value"
138
+ ],
139
+ "remediation": "fix_input"
140
+ },
141
+ "error.400.field.null": {
142
+ "status": 400,
143
+ "params": [
144
+ "field"
145
+ ],
146
+ "remediation": "fix_input"
147
+ },
148
+ "error.400.field.required": {
149
+ "status": 400,
150
+ "params": [
151
+ "field"
152
+ ],
153
+ "remediation": "fix_input"
154
+ },
155
+ "error.400.field.unique": {
156
+ "status": 400,
157
+ "params": [
158
+ "field"
159
+ ],
160
+ "remediation": "fix_input"
161
+ },
162
+ "error.400.invalid_ad_id": {
163
+ "status": 400,
164
+ "params": [],
165
+ "remediation": "fix_input"
166
+ },
167
+ "error.400.validation_error": {
168
+ "status": 400,
169
+ "params": [],
170
+ "remediation": "fix_input"
171
+ },
172
+ "error.400.verification_failed": {
173
+ "status": 400,
174
+ "params": [],
175
+ "remediation": "verify"
176
+ },
177
+ "error.400.verification_invalid_factor": {
178
+ "status": 400,
179
+ "params": [],
180
+ "remediation": "verify"
181
+ },
182
+ "error.400.vocabularies_bad_parent": {
183
+ "status": 400,
184
+ "params": [
185
+ "parent",
186
+ "level"
187
+ ],
188
+ "remediation": "fix_input"
189
+ },
190
+ "error.401.unauthorized": {
191
+ "status": 401,
192
+ "params": [],
193
+ "remediation": "reauthenticate"
194
+ },
195
+ "error.402.payment_required": {
196
+ "status": 402,
197
+ "params": [],
198
+ "remediation": "retry"
199
+ },
200
+ "error.403.forbidden": {
201
+ "status": 403,
202
+ "params": [],
203
+ "remediation": "retry"
204
+ },
205
+ "error.403.network_blocked": {
206
+ "status": 403,
207
+ "params": [],
208
+ "remediation": "contact_support"
209
+ },
210
+ "error.403.verification_enrollment_required": {
211
+ "status": 403,
212
+ "params": [],
213
+ "remediation": "verify"
214
+ },
215
+ "error.403.verification_required": {
216
+ "status": 403,
217
+ "params": [],
218
+ "remediation": "verify"
219
+ },
220
+ "error.404.ad_not_found": {
221
+ "status": 404,
222
+ "params": [],
223
+ "remediation": "retry"
224
+ },
225
+ "error.404.not_found": {
226
+ "status": 404,
227
+ "params": [],
228
+ "remediation": "retry"
229
+ },
230
+ "error.404.verification_challenge_not_found": {
231
+ "status": 404,
232
+ "params": [],
233
+ "remediation": "verify"
234
+ },
235
+ "error.404.vocabularies_level_not_found": {
236
+ "status": 404,
237
+ "params": [
238
+ "vocabulary",
239
+ "level"
240
+ ],
241
+ "remediation": "retry"
242
+ },
243
+ "error.404.vocabularies_vocabulary_not_found": {
244
+ "status": 404,
245
+ "params": [],
246
+ "remediation": "retry"
247
+ },
248
+ "error.405.method_not_allowed": {
249
+ "status": 405,
250
+ "params": [],
251
+ "remediation": "retry"
252
+ },
253
+ "error.406.not_acceptable": {
254
+ "status": 406,
255
+ "params": [],
256
+ "remediation": "retry"
257
+ },
258
+ "error.408.request_timeout": {
259
+ "status": 408,
260
+ "params": [],
261
+ "remediation": "retry"
262
+ },
263
+ "error.409.conflict": {
264
+ "status": 409,
265
+ "params": [],
266
+ "remediation": "fix_input"
267
+ },
268
+ "error.410.gone": {
269
+ "status": 410,
270
+ "params": [],
271
+ "remediation": "retry"
272
+ },
273
+ "error.413.payload_too_large": {
274
+ "status": 413,
275
+ "params": [],
276
+ "remediation": "retry"
277
+ },
278
+ "error.415.unsupported_media_type": {
279
+ "status": 415,
280
+ "params": [],
281
+ "remediation": "retry"
282
+ },
283
+ "error.422.unprocessable_entity": {
284
+ "status": 422,
285
+ "params": [],
286
+ "remediation": "wait_and_retry"
287
+ },
288
+ "error.423.locked": {
289
+ "status": 423,
290
+ "params": [],
291
+ "remediation": "wait_and_retry"
292
+ },
293
+ "error.423.verification_locked": {
294
+ "status": 423,
295
+ "params": [],
296
+ "remediation": "wait_and_retry"
297
+ },
298
+ "error.429.rate_limit": {
299
+ "status": 429,
300
+ "params": [
301
+ "retry_after_minutes"
302
+ ],
303
+ "remediation": "wait_and_retry"
304
+ },
305
+ "error.429.too_many_requests": {
306
+ "status": 429,
307
+ "params": [],
308
+ "remediation": "wait_and_retry"
309
+ },
310
+ "error.500.internal": {
311
+ "status": 500,
312
+ "params": [],
313
+ "remediation": "contact_support"
314
+ },
315
+ "error.503.mandate_unavailable": {
316
+ "status": 503,
317
+ "params": [],
318
+ "remediation": "retry"
319
+ }
320
+ },
321
+ "events": {
322
+ "defined": [],
323
+ "flows": []
324
+ },
325
+ "demos": [
326
+ {
327
+ "id": "vocabularies.provider",
328
+ "title": "Vocabularies provider",
329
+ "description": "The headless vocabularies root wires the runtime, i18n engine, and query client into React context. Replace with per-flow demos as you add headless components.",
330
+ "component": "VocabulariesProvider",
331
+ "tokens": [
332
+ "surface-raised"
333
+ ],
334
+ "variants": [
335
+ "default"
336
+ ],
337
+ "source": "demo/Vocabularies.demo.tsx"
338
+ },
339
+ {
340
+ "id": "vocabularies.term-select",
341
+ "title": "Vocabulary term select (default skin)",
342
+ "description": "One vocabulary level as a typeahead: the options are the answer to the current query (debounced, superseding), and a code the control already holds is resolved to its label and kept pickable even when the current page does not contain it.",
343
+ "component": "VocabularyTermSelect",
344
+ "variants": [
345
+ "default",
346
+ "phone",
347
+ "narrowed",
348
+ "multiple",
349
+ "unavailable"
350
+ ],
351
+ "source": "demo/VocabularyTermSelect.demo.tsx"
352
+ }
353
+ ],
354
+ "i18nKeys": [
355
+ "error.400.bad_request",
356
+ "error.400.captcha_invalid",
357
+ "error.400.captcha_required",
358
+ "error.400.expected_list",
359
+ "error.400.field.blank",
360
+ "error.400.field.does_not_exist",
361
+ "error.400.field.invalid",
362
+ "error.400.field.invalid_choice",
363
+ "error.400.field.max_length",
364
+ "error.400.field.max_value",
365
+ "error.400.field.min_length",
366
+ "error.400.field.min_value",
367
+ "error.400.field.null",
368
+ "error.400.field.required",
369
+ "error.400.field.unique",
370
+ "error.400.invalid_ad_id",
371
+ "error.400.validation_error",
372
+ "error.400.verification_failed",
373
+ "error.400.verification_invalid_factor",
374
+ "error.400.vocabularies_bad_parent",
375
+ "error.401.unauthorized",
376
+ "error.402.payment_required",
377
+ "error.403.forbidden",
378
+ "error.403.network_blocked",
379
+ "error.403.verification_enrollment_required",
380
+ "error.403.verification_required",
381
+ "error.404.ad_not_found",
382
+ "error.404.not_found",
383
+ "error.404.verification_challenge_not_found",
384
+ "error.404.vocabularies_level_not_found",
385
+ "error.404.vocabularies_vocabulary_not_found",
386
+ "error.405.method_not_allowed",
387
+ "error.406.not_acceptable",
388
+ "error.408.request_timeout",
389
+ "error.409.conflict",
390
+ "error.410.gone",
391
+ "error.413.payload_too_large",
392
+ "error.415.unsupported_media_type",
393
+ "error.422.unprocessable_entity",
394
+ "error.423.locked",
395
+ "error.423.verification_locked",
396
+ "error.429.rate_limit",
397
+ "error.429.too_many_requests",
398
+ "error.500.internal",
399
+ "error.503.mandate_unavailable",
400
+ "vocabularies.error.unknown",
401
+ "vocabularies.termSelect.noMatches",
402
+ "vocabularies.termSelect.placeholder",
403
+ "vocabularies.termSelect.unavailable",
404
+ "vocabularies.termSelect.unavailable.title"
405
+ ],
406
+ "exports": {
407
+ "runtime": [
408
+ "DEFAULT_TERM_LIMIT",
409
+ "RESOLVE_BATCH",
410
+ "TERM_SEARCH_DEBOUNCE_MS",
411
+ "VOCABULARIES_ERRORS",
412
+ "VOCABULARIES_ERROR_CODES",
413
+ "VOCABULARIES_FLOWS",
414
+ "VOCABULARIES_I18N_KEYS",
415
+ "VocabulariesProvider",
416
+ "VocabulariesRuntimeContext",
417
+ "createFlowMachine",
418
+ "createVocabulariesApi",
419
+ "createVocabulariesRuntime",
420
+ "createVocabularyClient",
421
+ "explainVocabulariesError",
422
+ "flowEndpoints",
423
+ "isErrorCode",
424
+ "registerVocabulariesI18n",
425
+ "termLabel",
426
+ "toFlowError",
427
+ "useFlow",
428
+ "useTermLabels",
429
+ "useTermSearch",
430
+ "useVocabulariesAnalytics",
431
+ "useVocabulariesApi",
432
+ "useVocabulariesRuntime",
433
+ "vocabulariesErrorBundleEn",
434
+ "vocabulariesI18nBundleEn",
435
+ "vocabulariesQueryKeys"
436
+ ],
437
+ "types": [
438
+ "CreateVocabulariesRuntimeOptions",
439
+ "CreateVocabularyClientOptions",
440
+ "FlowEndpoint",
441
+ "FlowError",
442
+ "FlowMachine",
443
+ "FlowMachineOptions",
444
+ "FlowStateBase",
445
+ "Level",
446
+ "Remediation",
447
+ "Schemas",
448
+ "Term",
449
+ "TermLabels",
450
+ "TermLabelsOptions",
451
+ "TermPage",
452
+ "TermSearchOptions",
453
+ "TermSearchState",
454
+ "VocabulariesApi",
455
+ "VocabulariesErrorCode",
456
+ "VocabulariesErrorSpec",
457
+ "VocabulariesFlowId",
458
+ "VocabulariesFlowSpec",
459
+ "VocabulariesI18nKey",
460
+ "VocabulariesRuntime",
461
+ "Vocabulary",
462
+ "VocabularyClient",
463
+ "VocabularyTerm"
464
+ ]
465
+ }
466
+ }