@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.
- package/CHANGELOG.md +52 -0
- package/LICENSE +21 -0
- package/MODULE.md +92 -0
- package/README.md +173 -0
- package/dist/api/extensions.d.ts +8 -0
- package/dist/api/extensions.d.ts.map +1 -0
- package/dist/api/extensions.js +8 -0
- package/dist/api/extensions.js.map +1 -0
- package/dist/api/generated/schema.d.ts +234 -0
- package/dist/api/generated/schema.d.ts.map +1 -0
- package/dist/api/generated/schema.js +2 -0
- package/dist/api/generated/schema.js.map +1 -0
- package/dist/api/types.d.ts +23 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/vocabulariesApi.d.ts +14 -0
- package/dist/api/vocabulariesApi.d.ts.map +1 -0
- package/dist/api/vocabulariesApi.js +4 -0
- package/dist/api/vocabulariesApi.js.map +1 -0
- package/dist/client.d.ts +49 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +118 -0
- package/dist/client.js.map +1 -0
- package/dist/default/VocabularyTermSelect.d.ts +24 -0
- package/dist/default/VocabularyTermSelect.d.ts.map +1 -0
- package/dist/default/VocabularyTermSelect.js +75 -0
- package/dist/default/VocabularyTermSelect.js.map +1 -0
- package/dist/default/index.d.ts +16 -0
- package/dist/default/index.d.ts.map +1 -0
- package/dist/default/index.js +14 -0
- package/dist/default/index.js.map +1 -0
- package/dist/default/types.d.ts +12 -0
- package/dist/default/types.d.ts.map +1 -0
- package/dist/default/types.js +2 -0
- package/dist/default/types.js.map +1 -0
- package/dist/flows/errors.d.ts +12 -0
- package/dist/flows/errors.d.ts.map +1 -0
- package/dist/flows/errors.js +13 -0
- package/dist/flows/errors.js.map +1 -0
- package/dist/flows/registry.d.ts +22 -0
- package/dist/flows/registry.d.ts.map +1 -0
- package/dist/flows/registry.js +20 -0
- package/dist/flows/registry.js.map +1 -0
- package/dist/headless/VocabulariesProvider.d.ts +19 -0
- package/dist/headless/VocabulariesProvider.d.ts.map +1 -0
- package/dist/headless/VocabulariesProvider.js +15 -0
- package/dist/headless/VocabulariesProvider.js.map +1 -0
- package/dist/i18n/errorsMap.d.ts +10 -0
- package/dist/i18n/errorsMap.d.ts.map +1 -0
- package/dist/i18n/errorsMap.js +20 -0
- package/dist/i18n/errorsMap.js.map +1 -0
- package/dist/i18n/es.d.ts +21 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +38 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/generated/errors.es.gen.d.ts +16 -0
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.es.gen.js +58 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -0
- package/dist/i18n/generated/errors.gen.d.ts +305 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.gen.js +156 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts +16 -0
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -0
- package/dist/i18n/generated/errors.ru.gen.js +58 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -0
- package/dist/i18n/keys.d.ts +33 -0
- package/dist/i18n/keys.d.ts.map +1 -0
- package/dist/i18n/keys.js +44 -0
- package/dist/i18n/keys.js.map +1 -0
- package/dist/i18n/ru.d.ts +26 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +43 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/model/context.d.ts +11 -0
- package/dist/model/context.d.ts.map +1 -0
- package/dist/model/context.js +16 -0
- package/dist/model/context.js.map +1 -0
- package/dist/model/queryKeys.d.ts +5 -0
- package/dist/model/queryKeys.d.ts.map +1 -0
- package/dist/model/queryKeys.js +28 -0
- package/dist/model/queryKeys.js.map +1 -0
- package/dist/model/runtime.d.ts +17 -0
- package/dist/model/runtime.d.ts.map +1 -0
- package/dist/model/runtime.js +6 -0
- package/dist/model/runtime.js.map +1 -0
- package/dist/model/useTermLabels.d.ts +26 -0
- package/dist/model/useTermLabels.d.ts.map +1 -0
- package/dist/model/useTermLabels.js +58 -0
- package/dist/model/useTermLabels.js.map +1 -0
- package/dist/model/useTermSearch.d.ts +24 -0
- package/dist/model/useTermSearch.d.ts.map +1 -0
- package/dist/model/useTermSearch.js +85 -0
- package/dist/model/useTermSearch.js.map +1 -0
- package/llms.txt +79 -0
- package/manifest.json +466 -0
- package/package.json +108 -0
- package/src/analytics/generated/events.json +7 -0
- package/src/api/extensions.ts +7 -0
- package/src/api/generated/schema.ts +236 -0
- package/src/api/types.ts +27 -0
- package/src/api/vocabulariesApi.ts +17 -0
- package/src/client.ts +176 -0
- package/src/default/VocabularyTermSelect.tsx +147 -0
- package/src/default/index.ts +15 -0
- package/src/default/types.ts +11 -0
- package/src/flows/errors.ts +16 -0
- package/src/flows/registry.ts +32 -0
- package/src/headless/VocabulariesProvider.tsx +20 -0
- package/src/i18n/errorsMap.ts +31 -0
- package/src/i18n/es.ts +49 -0
- package/src/i18n/generated/errors.es.gen.ts +64 -0
- package/src/i18n/generated/errors.gen.ts +187 -0
- package/src/i18n/generated/errors.json +351 -0
- package/src/i18n/generated/errors.ru.gen.ts +64 -0
- package/src/i18n/keys.ts +53 -0
- package/src/i18n/ru.ts +54 -0
- package/src/index.ts +92 -0
- package/src/model/context.tsx +28 -0
- package/src/model/queryKeys.ts +35 -0
- package/src/model/runtime.ts +25 -0
- package/src/model/useTermLabels.ts +72 -0
- package/src/model/useTermSearch.ts +118 -0
- 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
|
+
}
|