@stapel/attributes-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/README.md +123 -0
- package/dist/default/FeatureBadges.d.ts +33 -0
- package/dist/default/FeatureBadges.d.ts.map +1 -0
- package/dist/default/FeatureBadges.js +56 -0
- package/dist/default/FeatureBadges.js.map +1 -0
- package/dist/default/FeatureFields.d.ts +52 -0
- package/dist/default/FeatureFields.d.ts.map +1 -0
- package/dist/default/FeatureFields.js +60 -0
- package/dist/default/FeatureFields.js.map +1 -0
- package/dist/default/editors.d.ts +24 -0
- package/dist/default/editors.d.ts.map +1 -0
- package/dist/default/editors.js +354 -0
- package/dist/default/editors.js.map +1 -0
- package/dist/default/index.d.ts +27 -0
- package/dist/default/index.d.ts.map +1 -0
- package/dist/default/index.js +25 -0
- package/dist/default/index.js.map +1 -0
- package/dist/dto.d.ts +40 -0
- package/dist/dto.d.ts.map +1 -0
- package/dist/dto.js +64 -0
- package/dist/dto.js.map +1 -0
- package/dist/errors.d.ts +57 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +98 -0
- package/dist/errors.js.map +1 -0
- package/dist/format.d.ts +46 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +159 -0
- package/dist/format.js.map +1 -0
- package/dist/i18n/es.d.ts +13 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +36 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/keys.d.ts +56 -0
- package/dist/i18n/keys.d.ts.map +1 -0
- package/dist/i18n/keys.js +80 -0
- package/dist/i18n/keys.js.map +1 -0
- package/dist/i18n/ru.d.ts +19 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +42 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +122 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +82 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +88 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +410 -0
- package/dist/validate.js.map +1 -0
- package/manifest.json +96 -0
- package/package.json +107 -0
- package/src/default/FeatureBadges.tsx +123 -0
- package/src/default/FeatureFields.tsx +140 -0
- package/src/default/editors.tsx +578 -0
- package/src/default/index.ts +34 -0
- package/src/dto.ts +78 -0
- package/src/errors.ts +127 -0
- package/src/format.ts +210 -0
- package/src/i18n/es.ts +41 -0
- package/src/i18n/keys.ts +89 -0
- package/src/i18n/ru.ts +48 -0
- package/src/index.ts +98 -0
- package/src/registry.ts +167 -0
- package/src/types.ts +166 -0
- package/src/validate.ts +507 -0
- package/tsconfig.json +26 -0
package/dist/errors.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every `ValidationErrorCode` the engine defines, sorted.
|
|
3
|
+
*
|
|
4
|
+
* Pinned byte-for-byte against `stapel-attributes/tests/golden/
|
|
5
|
+
* error_codes.json` — the corpus the engine generates from its own enum and
|
|
6
|
+
* asserts from both Python and TypeScript. A code added upstream and not here
|
|
7
|
+
* turns `test/contract.test.ts` red.
|
|
8
|
+
*/
|
|
9
|
+
export const VALIDATION_ERROR_CODES = [
|
|
10
|
+
"above_maximum",
|
|
11
|
+
"below_minimum",
|
|
12
|
+
"description_too_long",
|
|
13
|
+
"description_too_short",
|
|
14
|
+
"duplicate_slug",
|
|
15
|
+
"empty_options",
|
|
16
|
+
"invalid_config",
|
|
17
|
+
"invalid_format",
|
|
18
|
+
"invalid_type",
|
|
19
|
+
"mandatory_missing",
|
|
20
|
+
"min_greater_than_max",
|
|
21
|
+
"not_allowed",
|
|
22
|
+
"not_in_options",
|
|
23
|
+
"unknown_feature",
|
|
24
|
+
"unknown_feature_type",
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* `ValidationErrorCode` → localizable key, mirroring
|
|
28
|
+
* `stapel_attributes.errors.ERROR_CODE_TO_KEY` exactly — including the three
|
|
29
|
+
* codes that deliberately collapse onto one key (`duplicate_slug` reports as
|
|
30
|
+
* an unknown type; `min_greater_than_max` and `empty_options` are both
|
|
31
|
+
* invalid config). Collapsing them differently here would make the client
|
|
32
|
+
* claim a distinction the server does not draw.
|
|
33
|
+
*/
|
|
34
|
+
export const ERROR_CODE_TO_KEY = {
|
|
35
|
+
below_minimum: "error.400.feature_below_minimum",
|
|
36
|
+
above_maximum: "error.400.feature_above_maximum",
|
|
37
|
+
not_in_options: "error.400.feature_not_in_options",
|
|
38
|
+
invalid_type: "error.400.feature_invalid_type",
|
|
39
|
+
invalid_format: "error.400.feature_invalid_format",
|
|
40
|
+
mandatory_missing: "error.400.feature_mandatory_missing",
|
|
41
|
+
duplicate_slug: "error.400.feature_unknown_type",
|
|
42
|
+
unknown_feature_type: "error.400.feature_unknown_type",
|
|
43
|
+
not_allowed: "error.400.feature_not_allowed",
|
|
44
|
+
unknown_feature: "error.400.feature_unknown",
|
|
45
|
+
invalid_config: "error.400.feature_invalid_config",
|
|
46
|
+
min_greater_than_max: "error.400.feature_invalid_config",
|
|
47
|
+
empty_options: "error.400.feature_invalid_config",
|
|
48
|
+
description_too_short: "error.400.description_too_short",
|
|
49
|
+
description_too_long: "error.400.description_too_long",
|
|
50
|
+
};
|
|
51
|
+
/** The key a result should render from: what the server said, else the one
|
|
52
|
+
* its code maps to. The server sends `localizable_error` already — this only
|
|
53
|
+
* covers the mirror's rows and a server that ever omits it. */
|
|
54
|
+
export function resultErrorKey(result) {
|
|
55
|
+
if (typeof result.localizable_error === "string" && result.localizable_error.length > 0) {
|
|
56
|
+
return result.localizable_error;
|
|
57
|
+
}
|
|
58
|
+
return result.error ? ERROR_CODE_TO_KEY[result.error] : undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A batch verdict, split into per-control refusals keyed by feature slug.
|
|
62
|
+
*
|
|
63
|
+
* `params.field` is added on the way out. The engine's own params are
|
|
64
|
+
* `{feature, slug}` (`validation.py`) and the fleet's `useFieldError`
|
|
65
|
+
* convention routes on `field` — so without this a perfectly well-formed
|
|
66
|
+
* server refusal lands in a page-level banner instead of under the control
|
|
67
|
+
* whose value caused it, which is the difference between "something is wrong"
|
|
68
|
+
* and "this box is wrong".
|
|
69
|
+
*
|
|
70
|
+
* `ref_value` rides along in params too: `error.400.feature_below_minimum`
|
|
71
|
+
* interpolates the limit, and the limit is what `ref_value` carries.
|
|
72
|
+
*/
|
|
73
|
+
export function featureErrorsBySlug(batch) {
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const result of batch.results) {
|
|
76
|
+
if (result.status !== "validation_failed")
|
|
77
|
+
continue;
|
|
78
|
+
const code = resultErrorKey(result);
|
|
79
|
+
if (code === undefined)
|
|
80
|
+
continue;
|
|
81
|
+
out[result.slug] = {
|
|
82
|
+
code,
|
|
83
|
+
params: {
|
|
84
|
+
...(result.params ?? {}),
|
|
85
|
+
field: result.slug,
|
|
86
|
+
slug: result.slug,
|
|
87
|
+
...(result.ref_value === undefined || result.ref_value === null
|
|
88
|
+
? {}
|
|
89
|
+
: { ref_value: result.ref_value }),
|
|
90
|
+
},
|
|
91
|
+
status: 400,
|
|
92
|
+
message: result.message ?? undefined,
|
|
93
|
+
language: undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAyBA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,eAAe;IACf,eAAe;IACf,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,sBAAsB;IACtB,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,sBAAsB;CACvB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAkD;IAC9E,aAAa,EAAE,iCAAiC;IAChD,aAAa,EAAE,iCAAiC;IAChD,cAAc,EAAE,kCAAkC;IAClD,YAAY,EAAE,gCAAgC;IAC9C,cAAc,EAAE,kCAAkC;IAClD,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,gCAAgC;IAChD,oBAAoB,EAAE,gCAAgC;IACtD,WAAW,EAAE,+BAA+B;IAC5C,eAAe,EAAE,2BAA2B;IAC5C,cAAc,EAAE,kCAAkC;IAClD,oBAAoB,EAAE,kCAAkC;IACxD,aAAa,EAAE,kCAAkC;IACjD,qBAAqB,EAAE,iCAAiC;IACxD,oBAAoB,EAAE,gCAAgC;CACvD,CAAC;AAEF;;+DAE+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,MAA+B;IAE/B,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,QAAQ,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxF,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAA4B;IAE5B,MAAM,GAAG,GAA8B,EAAE,CAAC;IAC1C,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB;YAAE,SAAS;QACpD,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;YACjB,IAAI;YACJ,MAAM,EAAE;gBACN,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACxB,KAAK,EAAE,MAAM,CAAC,IAAI;gBAClB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI;oBAC7D,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;aACrC;YACD,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS;YACpC,QAAQ,EAAE,SAAS;SACpB,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DISPLAY — the read-only half of every value type.
|
|
3
|
+
*
|
|
4
|
+
* A storefront renders an attribute far more often than it edits one: a card
|
|
5
|
+
* shows badges, a detail page shows the whole spec table, a title carries the
|
|
6
|
+
* `show_at_title` values. Formatting therefore lives HERE, in the main entry,
|
|
7
|
+
* React-free and antd-free, so a card can format a value without pulling a
|
|
8
|
+
* skin into its bundle. `<FeatureBadges>`/`<FeatureValueList>` in `/default`
|
|
9
|
+
* are renderers over this function, not a second implementation of it.
|
|
10
|
+
*
|
|
11
|
+
* It mirrors each type's `format_value(config, dao)` (`stapel_attributes
|
|
12
|
+
* .types.*.type`), with the one honest difference the browser forces:
|
|
13
|
+
* `date` formats with the VIEWER's locale and time zone, where the engine
|
|
14
|
+
* formats with the server's — the same instant, written the way the person
|
|
15
|
+
* reading it writes dates.
|
|
16
|
+
*
|
|
17
|
+
* Unsupported types do not vanish. `formatFeatureValue` returns `undefined`
|
|
18
|
+
* for a type it cannot read, and the caller says so; a silent empty cell
|
|
19
|
+
* where a spec line belongs is the display twin of a dropped mandatory field.
|
|
20
|
+
*/
|
|
21
|
+
import type { FeatureDef, FeatureValueDto } from "./types.js";
|
|
22
|
+
/** The types this module can render, sorted — the display half of the
|
|
23
|
+
* builtin set, and asserted equal to the editor half in `contract.test.ts`
|
|
24
|
+
* (a type you can fill in but cannot read back is a half-shipped type). */
|
|
25
|
+
export declare const FORMATTABLE_TYPES: readonly string[];
|
|
26
|
+
/** Copy the formatter needs from the host's translator — one function, so a
|
|
27
|
+
* caller outside React (a meta-tag builder, a title composer) can pass a
|
|
28
|
+
* plain lookup instead of standing up a provider. */
|
|
29
|
+
export interface FormatOptions {
|
|
30
|
+
/** Resolve an option label / boolean caption. Option labels are translation
|
|
31
|
+
* keys when the config says `translatable_options` (the default). */
|
|
32
|
+
readonly t?: (key: string) => string;
|
|
33
|
+
/** BCP-47 tag for `date`. Defaults to the runtime's own locale. */
|
|
34
|
+
readonly locale?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A submitted value, as a person reads it — or `undefined` when there is
|
|
38
|
+
* nothing to show (blank) or nothing this build can read (an unknown type).
|
|
39
|
+
* The two cases are distinguished by {@link isBlank}, so a caller can say
|
|
40
|
+
* "not specified" for one and name the type for the other.
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatFeatureValue(feature: FeatureDef, dto: FeatureValueDto | undefined, options?: FormatOptions): string | undefined;
|
|
43
|
+
/** The `#RRGGBB` a `hex_color` value carries, when it carries one — the swatch
|
|
44
|
+
* a display skin paints beside the label. */
|
|
45
|
+
export declare function hexColorSwatch(dto: FeatureValueDto | undefined): string | undefined;
|
|
46
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI9D;;2EAE2E;AAC3E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAW9C,CAAC;AAEF;;qDAEqD;AACrD,MAAM,WAAW,aAAa;IAC5B;yEACqE;IACrE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAiFD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,eAAe,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,GAAG,SAAS,CA0DpB;AAED;6CAC6C;AAC7C,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOnF"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { featureConfig, featureType } from "./types.js";
|
|
2
|
+
import { isBlank } from "./validate.js";
|
|
3
|
+
/** The types this module can render, sorted — the display half of the
|
|
4
|
+
* builtin set, and asserted equal to the editor half in `contract.test.ts`
|
|
5
|
+
* (a type you can fill in but cannot read back is a half-shipped type). */
|
|
6
|
+
export const FORMATTABLE_TYPES = [
|
|
7
|
+
"bool",
|
|
8
|
+
"convertible_unit",
|
|
9
|
+
"date",
|
|
10
|
+
"float",
|
|
11
|
+
"header",
|
|
12
|
+
"hex_color",
|
|
13
|
+
"hierarchical_select",
|
|
14
|
+
"int",
|
|
15
|
+
"select",
|
|
16
|
+
"string",
|
|
17
|
+
];
|
|
18
|
+
function str(value) {
|
|
19
|
+
return typeof value === "string" ? value : value === null || value === undefined ? "" : String(value);
|
|
20
|
+
}
|
|
21
|
+
function translate(options, key) {
|
|
22
|
+
const t = options?.t;
|
|
23
|
+
if (t === undefined)
|
|
24
|
+
return key;
|
|
25
|
+
const resolved = t(key);
|
|
26
|
+
// A translator that does not know a key conventionally returns the key —
|
|
27
|
+
// which is still the most informative thing available, so it stands.
|
|
28
|
+
return resolved.length > 0 ? resolved : key;
|
|
29
|
+
}
|
|
30
|
+
/** `{value → label}` for an options-bearing config, in either option shape. */
|
|
31
|
+
function labelOf(config, value, options) {
|
|
32
|
+
const raw = config["options"];
|
|
33
|
+
if (Array.isArray(raw)) {
|
|
34
|
+
for (const option of raw) {
|
|
35
|
+
if (option !== null && typeof option === "object") {
|
|
36
|
+
const entry = option;
|
|
37
|
+
if (entry.value === value && typeof entry.label === "string" && entry.label.length > 0) {
|
|
38
|
+
return config["translatable_options"] === false
|
|
39
|
+
? entry.label
|
|
40
|
+
: translate(options, entry.label);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return str(value);
|
|
46
|
+
}
|
|
47
|
+
function formatNumber(config, value, defaultPrecision) {
|
|
48
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
49
|
+
if (!Number.isFinite(parsed))
|
|
50
|
+
return undefined;
|
|
51
|
+
const precision = config["precision"];
|
|
52
|
+
const digits = typeof precision === "number" && precision >= 0 ? precision : defaultPrecision;
|
|
53
|
+
const body = digits > 0 ? parsed.toFixed(digits) : String(Math.trunc(parsed));
|
|
54
|
+
const prefix = str(config["prefix"]);
|
|
55
|
+
const postfix = str(config["postfix"]);
|
|
56
|
+
return `${prefix}${body}${postfix ? ` ${postfix}` : ""}`;
|
|
57
|
+
}
|
|
58
|
+
/** `precision` → the `Intl` fields the engine's own `strftime` would show. */
|
|
59
|
+
function formatTimestamp(seconds, precision, locale) {
|
|
60
|
+
const date = new Date(seconds * 1000);
|
|
61
|
+
switch (precision) {
|
|
62
|
+
case "year":
|
|
63
|
+
return new Intl.DateTimeFormat(locale, { year: "numeric" }).format(date);
|
|
64
|
+
case "month":
|
|
65
|
+
return new Intl.DateTimeFormat(locale, { year: "numeric", month: "long" }).format(date);
|
|
66
|
+
case "datetime":
|
|
67
|
+
return new Intl.DateTimeFormat(locale, {
|
|
68
|
+
year: "numeric",
|
|
69
|
+
month: "short",
|
|
70
|
+
day: "numeric",
|
|
71
|
+
hour: "2-digit",
|
|
72
|
+
minute: "2-digit",
|
|
73
|
+
}).format(date);
|
|
74
|
+
default:
|
|
75
|
+
return new Intl.DateTimeFormat(locale, {
|
|
76
|
+
year: "numeric",
|
|
77
|
+
month: "short",
|
|
78
|
+
day: "numeric",
|
|
79
|
+
}).format(date);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A submitted value, as a person reads it — or `undefined` when there is
|
|
84
|
+
* nothing to show (blank) or nothing this build can read (an unknown type).
|
|
85
|
+
* The two cases are distinguished by {@link isBlank}, so a caller can say
|
|
86
|
+
* "not specified" for one and name the type for the other.
|
|
87
|
+
*/
|
|
88
|
+
export function formatFeatureValue(feature, dto, options) {
|
|
89
|
+
const type = featureType(feature);
|
|
90
|
+
if (type === "header" || dto === undefined || isBlank(dto.value))
|
|
91
|
+
return undefined;
|
|
92
|
+
const config = featureConfig(feature);
|
|
93
|
+
const value = dto.value;
|
|
94
|
+
switch (type) {
|
|
95
|
+
case "string":
|
|
96
|
+
return `${str(config["prefix"])}${str(value)}${str(config["postfix"]) ? ` ${str(config["postfix"])}` : ""}`;
|
|
97
|
+
case "int":
|
|
98
|
+
return formatNumber(config, value, 0);
|
|
99
|
+
case "float":
|
|
100
|
+
return formatNumber(config, value, 2);
|
|
101
|
+
case "bool": {
|
|
102
|
+
const on = value === true || value === 1 || value === "true";
|
|
103
|
+
const label = str(config[on ? "trueLabel" : "falseLabel"]);
|
|
104
|
+
if (label.length > 0)
|
|
105
|
+
return translate(options, label);
|
|
106
|
+
return on ? "✓" : "—";
|
|
107
|
+
}
|
|
108
|
+
case "select": {
|
|
109
|
+
const items = Array.isArray(value) ? value : [value];
|
|
110
|
+
return items.map((item) => labelOf(config, item, options)).join(", ");
|
|
111
|
+
}
|
|
112
|
+
case "hierarchical_select": {
|
|
113
|
+
const path = Array.isArray(value) ? value : [value];
|
|
114
|
+
return path.map((step) => str(step)).join(" / ");
|
|
115
|
+
}
|
|
116
|
+
case "date": {
|
|
117
|
+
const seconds = typeof value === "number"
|
|
118
|
+
? Math.trunc(value)
|
|
119
|
+
: typeof value === "string" && /^-?\d+$/.test(value.trim())
|
|
120
|
+
? Number.parseInt(value.trim(), 10)
|
|
121
|
+
: undefined;
|
|
122
|
+
if (seconds === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
return formatTimestamp(seconds, str(config["precision"]) || "date", options?.locale);
|
|
125
|
+
}
|
|
126
|
+
case "hex_color": {
|
|
127
|
+
if (value === null || typeof value !== "object")
|
|
128
|
+
return undefined;
|
|
129
|
+
const entry = value;
|
|
130
|
+
if (typeof entry.label === "string" && entry.label.length > 0) {
|
|
131
|
+
return translate(options, entry.label);
|
|
132
|
+
}
|
|
133
|
+
return str(entry.simple) || str(entry.hex) || undefined;
|
|
134
|
+
}
|
|
135
|
+
case "convertible_unit": {
|
|
136
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
137
|
+
if (!Number.isFinite(parsed))
|
|
138
|
+
return undefined;
|
|
139
|
+
const digits = typeof config["precision"] === "number" ? config["precision"] : 2;
|
|
140
|
+
const unit = str(dto["unit"]) || str(config["unit_m"]) || str(config["unit_i"]);
|
|
141
|
+
const body = `${str(config["prefix"])}${parsed.toFixed(digits)}`;
|
|
142
|
+
return unit ? `${body} ${unit}` : body;
|
|
143
|
+
}
|
|
144
|
+
default:
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** The `#RRGGBB` a `hex_color` value carries, when it carries one — the swatch
|
|
149
|
+
* a display skin paints beside the label. */
|
|
150
|
+
export function hexColorSwatch(dto) {
|
|
151
|
+
const value = dto?.value;
|
|
152
|
+
if (value === null || value === undefined || typeof value !== "object")
|
|
153
|
+
return undefined;
|
|
154
|
+
const hex = value.hex;
|
|
155
|
+
return typeof hex === "string" && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(hex.trim())
|
|
156
|
+
? hex.trim()
|
|
157
|
+
: undefined;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { I18nDictionary, I18nEngine } from "@stapel/core";
|
|
2
|
+
/**
|
|
3
|
+
* Spanish bundle — the `@stapel/attributes-react/i18n/es` subpath, opt-in
|
|
4
|
+
* (i18n-shipping.md §2), same shape and same provenance caveat as `./ru`:
|
|
5
|
+
* stapel-attributes ships English only, so this copy is pair-authored and
|
|
6
|
+
* unreviewed, and deliberately worded to match forms-react's copy of the same
|
|
7
|
+
* twelve engine keys.
|
|
8
|
+
*/
|
|
9
|
+
export declare const attributesI18nBundleEs: I18nDictionary;
|
|
10
|
+
/** Register the `es` bundle. Call AFTER `registerAttributesI18n` so it
|
|
11
|
+
* overrides the English floor. */
|
|
12
|
+
export declare function registerAttributesI18nEs(engine: I18nEngine, locale?: string): void;
|
|
13
|
+
//# sourceMappingURL=es.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,cAyBpC,CAAC;AAEF;kCACkC;AAClC,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,SAAO,GAAG,IAAI,CAEhF"}
|
package/dist/i18n/es.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spanish bundle — the `@stapel/attributes-react/i18n/es` subpath, opt-in
|
|
3
|
+
* (i18n-shipping.md §2), same shape and same provenance caveat as `./ru`:
|
|
4
|
+
* stapel-attributes ships English only, so this copy is pair-authored and
|
|
5
|
+
* unreviewed, and deliberately worded to match forms-react's copy of the same
|
|
6
|
+
* twelve engine keys.
|
|
7
|
+
*/
|
|
8
|
+
export const attributesI18nBundleEs = {
|
|
9
|
+
"error.400.feature_below_minimum": "El valor es inferior al mínimo de {feature}",
|
|
10
|
+
"error.400.feature_above_maximum": "El valor supera el máximo de {feature}",
|
|
11
|
+
"error.400.feature_not_in_options": "El valor no está entre las opciones de {feature}",
|
|
12
|
+
"error.400.feature_invalid_type": "Tipo de valor no válido para {feature}",
|
|
13
|
+
"error.400.feature_invalid_format": "Formato no válido para {feature}",
|
|
14
|
+
"error.400.feature_mandatory_missing": "{feature} es obligatorio",
|
|
15
|
+
"error.400.feature_unknown_type": "Tipo de característica desconocido para {feature}",
|
|
16
|
+
"error.400.feature_not_allowed": "{feature} no se admite aquí",
|
|
17
|
+
"error.400.feature_unknown": "Característica desconocida {feature}",
|
|
18
|
+
"error.400.feature_invalid_config": "Configuración no válida de {feature}",
|
|
19
|
+
"error.400.description_too_short": "La descripción debe tener al menos {min_length} caracteres",
|
|
20
|
+
"error.400.description_too_long": "La descripción debe tener como máximo {max_length} caracteres",
|
|
21
|
+
"attributes.unsupported_type": "Esta versión no incluye un editor para el tipo de atributo «{type}», así que no se puede rellenar aquí.",
|
|
22
|
+
"attributes.submit.blocked.unsupported_type": "Algunos atributos no se pueden rellenar en esta página: {types}",
|
|
23
|
+
"attributes.untyped_feature": "Este atributo no declara ningún tipo y no se puede editar.",
|
|
24
|
+
"attributes.value.not_set": "Sin especificar",
|
|
25
|
+
"attributes.value.unreadable": "Esta versión no muestra valores de tipo «{type}»",
|
|
26
|
+
"attributes.bool.yes": "Sí",
|
|
27
|
+
"attributes.bool.no": "No",
|
|
28
|
+
"attributes.select.placeholder": "Elegir",
|
|
29
|
+
"attributes.required": "Obligatorio",
|
|
30
|
+
};
|
|
31
|
+
/** Register the `es` bundle. Call AFTER `registerAttributesI18n` so it
|
|
32
|
+
* overrides the English floor. */
|
|
33
|
+
export function registerAttributesI18nEs(engine, locale = "es") {
|
|
34
|
+
engine.registerBundle(locale, attributesI18nBundleEs);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"es.js","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAmB;IACpD,iCAAiC,EAAE,6CAA6C;IAChF,iCAAiC,EAAE,wCAAwC;IAC3E,kCAAkC,EAAE,kDAAkD;IACtF,gCAAgC,EAAE,wCAAwC;IAC1E,kCAAkC,EAAE,kCAAkC;IACtE,qCAAqC,EAAE,0BAA0B;IACjE,gCAAgC,EAAE,mDAAmD;IACrF,+BAA+B,EAAE,6BAA6B;IAC9D,2BAA2B,EAAE,sCAAsC;IACnE,kCAAkC,EAAE,sCAAsC;IAC1E,iCAAiC,EAAE,4DAA4D;IAC/F,gCAAgC,EAAE,+DAA+D;IAEjG,6BAA6B,EAC3B,yGAAyG;IAC3G,4CAA4C,EAC1C,iEAAiE;IACnE,4BAA4B,EAAE,4DAA4D;IAC1F,0BAA0B,EAAE,iBAAiB;IAC7C,6BAA6B,EAAE,kDAAkD;IACjF,qBAAqB,EAAE,IAAI;IAC3B,oBAAoB,EAAE,IAAI;IAC1B,+BAA+B,EAAE,QAAQ;IACzC,qBAAqB,EAAE,aAAa;CACrC,CAAC;AAEF;kCACkC;AAClC,MAAM,UAAU,wBAAwB,CAAC,MAAkB,EAAE,MAAM,GAAG,IAAI;IACxE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { I18nDictionary, I18nEngine } from "@stapel/core";
|
|
2
|
+
/**
|
|
3
|
+
* `@stapel/attributes-react`'s own translation KEYS (frontend-standard §4.2):
|
|
4
|
+
* nothing in this package renders a literal string — a host resolves these
|
|
5
|
+
* through core's i18n engine (`useT`).
|
|
6
|
+
*
|
|
7
|
+
* Two families live here, and only two:
|
|
8
|
+
*
|
|
9
|
+
* - `attributes.*` — this package's OWN chrome: the unsupported-type notice,
|
|
10
|
+
* the blocked-submit reason, the empty/optional captions, the control
|
|
11
|
+
* placeholders.
|
|
12
|
+
* - `error.400.feature_*` / `error.400.description_*` — the engine's own
|
|
13
|
+
* error catalogue (`stapel_attributes.errors.ATTRIBUTES_ERRORS`, registered
|
|
14
|
+
* with stapel-core), carried here as an English floor so a host that has
|
|
15
|
+
* not installed a pair whose `gen:errors` bundle includes them still shows
|
|
16
|
+
* a sentence rather than a key. A host that HAS one registers it after
|
|
17
|
+
* this bundle and the generated copy wins.
|
|
18
|
+
*
|
|
19
|
+
* ── What is NOT a key here ─────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* A feature's `name` and its options' `label`s are admin-authored content
|
|
22
|
+
* carried in the category's own data, not keys of this package. When
|
|
23
|
+
* `config.translatable_options` is set (the default) those labels ARE
|
|
24
|
+
* translation keys — but they belong to the deployment's catalogue, not to
|
|
25
|
+
* this bundle, which is why the formatter takes a `t` and never a table.
|
|
26
|
+
*/
|
|
27
|
+
export declare const ATTRIBUTES_I18N_KEYS: {
|
|
28
|
+
/** The loud last rung of the resolution ladder. */
|
|
29
|
+
readonly unsupportedType: "attributes.unsupported_type";
|
|
30
|
+
/** Why the submit is off while an undrawable feature is on screen. */
|
|
31
|
+
readonly submitBlockedUnsupportedType: "attributes.submit.blocked.unsupported_type";
|
|
32
|
+
/** A feature whose config declares no type at all. */
|
|
33
|
+
readonly untypedFeature: "attributes.untyped_feature";
|
|
34
|
+
/** Display side: the value is absent. Never rendered as an empty cell. */
|
|
35
|
+
readonly valueNotSet: "attributes.value.not_set";
|
|
36
|
+
/** Display side: the type has no formatter in this build. */
|
|
37
|
+
readonly valueUnreadable: "attributes.value.unreadable";
|
|
38
|
+
readonly boolYes: "attributes.bool.yes";
|
|
39
|
+
readonly boolNo: "attributes.bool.no";
|
|
40
|
+
readonly selectPlaceholder: "attributes.select.placeholder";
|
|
41
|
+
readonly required: "attributes.required";
|
|
42
|
+
};
|
|
43
|
+
export type AttributesI18nKey = (typeof ATTRIBUTES_I18N_KEYS)[keyof typeof ATTRIBUTES_I18N_KEYS];
|
|
44
|
+
/**
|
|
45
|
+
* The engine's error catalogue, English — a verbatim mirror of
|
|
46
|
+
* `stapel_attributes.errors.ATTRIBUTES_ERRORS`, including its
|
|
47
|
+
* `{feature}`/`{min_length}`/`{max_length}` placeholders. Same key, same
|
|
48
|
+
* sentence, whichever side of the wire noticed the problem.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ATTRIBUTES_ERROR_BUNDLE_EN: I18nDictionary;
|
|
51
|
+
export declare const attributesI18nBundleEn: I18nDictionary;
|
|
52
|
+
/** Register the package's `en` floor into a core i18n engine (call once at
|
|
53
|
+
* startup, before any locale override — the convention every
|
|
54
|
+
* `@stapel/*-react` package follows). */
|
|
55
|
+
export declare function registerAttributesI18n(engine: I18nEngine, locale?: string): void;
|
|
56
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB;IAC/B,mDAAmD;;IAEnD,sEAAsE;;IAEtE,sDAAsD;;IAEtD,0EAA0E;;IAE1E,6DAA6D;;;;;;CAMrD,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAC3B,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,cAaxC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,cAapC,CAAC;AAEF;;yCAEyC;AACzC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,SAAO,GAAG,IAAI,CAE9E"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@stapel/attributes-react`'s own translation KEYS (frontend-standard §4.2):
|
|
3
|
+
* nothing in this package renders a literal string — a host resolves these
|
|
4
|
+
* through core's i18n engine (`useT`).
|
|
5
|
+
*
|
|
6
|
+
* Two families live here, and only two:
|
|
7
|
+
*
|
|
8
|
+
* - `attributes.*` — this package's OWN chrome: the unsupported-type notice,
|
|
9
|
+
* the blocked-submit reason, the empty/optional captions, the control
|
|
10
|
+
* placeholders.
|
|
11
|
+
* - `error.400.feature_*` / `error.400.description_*` — the engine's own
|
|
12
|
+
* error catalogue (`stapel_attributes.errors.ATTRIBUTES_ERRORS`, registered
|
|
13
|
+
* with stapel-core), carried here as an English floor so a host that has
|
|
14
|
+
* not installed a pair whose `gen:errors` bundle includes them still shows
|
|
15
|
+
* a sentence rather than a key. A host that HAS one registers it after
|
|
16
|
+
* this bundle and the generated copy wins.
|
|
17
|
+
*
|
|
18
|
+
* ── What is NOT a key here ─────────────────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* A feature's `name` and its options' `label`s are admin-authored content
|
|
21
|
+
* carried in the category's own data, not keys of this package. When
|
|
22
|
+
* `config.translatable_options` is set (the default) those labels ARE
|
|
23
|
+
* translation keys — but they belong to the deployment's catalogue, not to
|
|
24
|
+
* this bundle, which is why the formatter takes a `t` and never a table.
|
|
25
|
+
*/
|
|
26
|
+
export const ATTRIBUTES_I18N_KEYS = {
|
|
27
|
+
/** The loud last rung of the resolution ladder. */
|
|
28
|
+
unsupportedType: "attributes.unsupported_type",
|
|
29
|
+
/** Why the submit is off while an undrawable feature is on screen. */
|
|
30
|
+
submitBlockedUnsupportedType: "attributes.submit.blocked.unsupported_type",
|
|
31
|
+
/** A feature whose config declares no type at all. */
|
|
32
|
+
untypedFeature: "attributes.untyped_feature",
|
|
33
|
+
/** Display side: the value is absent. Never rendered as an empty cell. */
|
|
34
|
+
valueNotSet: "attributes.value.not_set",
|
|
35
|
+
/** Display side: the type has no formatter in this build. */
|
|
36
|
+
valueUnreadable: "attributes.value.unreadable",
|
|
37
|
+
boolYes: "attributes.bool.yes",
|
|
38
|
+
boolNo: "attributes.bool.no",
|
|
39
|
+
selectPlaceholder: "attributes.select.placeholder",
|
|
40
|
+
required: "attributes.required",
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The engine's error catalogue, English — a verbatim mirror of
|
|
44
|
+
* `stapel_attributes.errors.ATTRIBUTES_ERRORS`, including its
|
|
45
|
+
* `{feature}`/`{min_length}`/`{max_length}` placeholders. Same key, same
|
|
46
|
+
* sentence, whichever side of the wire noticed the problem.
|
|
47
|
+
*/
|
|
48
|
+
export const ATTRIBUTES_ERROR_BUNDLE_EN = {
|
|
49
|
+
"error.400.feature_below_minimum": "Value is below minimum for {feature}",
|
|
50
|
+
"error.400.feature_above_maximum": "Value is above maximum for {feature}",
|
|
51
|
+
"error.400.feature_not_in_options": "Value is not in allowed options for {feature}",
|
|
52
|
+
"error.400.feature_invalid_type": "Invalid type for {feature}",
|
|
53
|
+
"error.400.feature_invalid_format": "Invalid format for {feature}",
|
|
54
|
+
"error.400.feature_mandatory_missing": "Mandatory feature {feature} is required",
|
|
55
|
+
"error.400.feature_unknown_type": "Unknown feature type for {feature}",
|
|
56
|
+
"error.400.feature_not_allowed": "Feature {feature} is not allowed here",
|
|
57
|
+
"error.400.feature_unknown": "Unknown feature {feature}",
|
|
58
|
+
"error.400.feature_invalid_config": "Invalid config for {feature}",
|
|
59
|
+
"error.400.description_too_short": "Description must be at least {min_length} characters",
|
|
60
|
+
"error.400.description_too_long": "Description must be at most {max_length} characters",
|
|
61
|
+
};
|
|
62
|
+
export const attributesI18nBundleEn = {
|
|
63
|
+
...ATTRIBUTES_ERROR_BUNDLE_EN,
|
|
64
|
+
"attributes.unsupported_type": "This build has no editor for the “{type}” attribute type, so it cannot be filled in here.",
|
|
65
|
+
"attributes.submit.blocked.unsupported_type": "Some attributes cannot be filled in on this page: {types}",
|
|
66
|
+
"attributes.untyped_feature": "This attribute declares no type and cannot be edited.",
|
|
67
|
+
"attributes.value.not_set": "Not specified",
|
|
68
|
+
"attributes.value.unreadable": "Cannot display a “{type}” value in this build",
|
|
69
|
+
"attributes.bool.yes": "Yes",
|
|
70
|
+
"attributes.bool.no": "No",
|
|
71
|
+
"attributes.select.placeholder": "Choose",
|
|
72
|
+
"attributes.required": "Required",
|
|
73
|
+
};
|
|
74
|
+
/** Register the package's `en` floor into a core i18n engine (call once at
|
|
75
|
+
* startup, before any locale override — the convention every
|
|
76
|
+
* `@stapel/*-react` package follows). */
|
|
77
|
+
export function registerAttributesI18n(engine, locale = "en") {
|
|
78
|
+
engine.registerBundle(locale, attributesI18nBundleEn);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,mDAAmD;IACnD,eAAe,EAAE,6BAA6B;IAC9C,sEAAsE;IACtE,4BAA4B,EAAE,4CAA4C;IAC1E,sDAAsD;IACtD,cAAc,EAAE,4BAA4B;IAC5C,0EAA0E;IAC1E,WAAW,EAAE,0BAA0B;IACvC,6DAA6D;IAC7D,eAAe,EAAE,6BAA6B;IAC9C,OAAO,EAAE,qBAAqB;IAC9B,MAAM,EAAE,oBAAoB;IAC5B,iBAAiB,EAAE,+BAA+B;IAClD,QAAQ,EAAE,qBAAqB;CACvB,CAAC;AAKX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAmB;IACxD,iCAAiC,EAAE,sCAAsC;IACzE,iCAAiC,EAAE,sCAAsC;IACzE,kCAAkC,EAAE,+CAA+C;IACnF,gCAAgC,EAAE,4BAA4B;IAC9D,kCAAkC,EAAE,8BAA8B;IAClE,qCAAqC,EAAE,yCAAyC;IAChF,gCAAgC,EAAE,oCAAoC;IACtE,+BAA+B,EAAE,uCAAuC;IACxE,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,8BAA8B;IAClE,iCAAiC,EAAE,sDAAsD;IACzF,gCAAgC,EAAE,qDAAqD;CACxF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAmB;IACpD,GAAG,0BAA0B;IAC7B,6BAA6B,EAC3B,2FAA2F;IAC7F,4CAA4C,EAC1C,2DAA2D;IAC7D,4BAA4B,EAAE,uDAAuD;IACrF,0BAA0B,EAAE,eAAe;IAC3C,6BAA6B,EAAE,+CAA+C;IAC9E,qBAAqB,EAAE,KAAK;IAC5B,oBAAoB,EAAE,IAAI;IAC1B,+BAA+B,EAAE,QAAQ;IACzC,qBAAqB,EAAE,UAAU;CAClC,CAAC;AAEF;;yCAEyC;AACzC,MAAM,UAAU,sBAAsB,CAAC,MAAkB,EAAE,MAAM,GAAG,IAAI;IACtE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { I18nDictionary, I18nEngine } from "@stapel/core";
|
|
2
|
+
/**
|
|
3
|
+
* Russian bundle — the `@stapel/attributes-react/i18n/ru` subpath, opt-in
|
|
4
|
+
* (i18n-shipping.md §2): the main entry does not import this module, so a
|
|
5
|
+
* host that does not register it never carries these strings (gated by
|
|
6
|
+
* size-limit).
|
|
7
|
+
*
|
|
8
|
+
* PROVENANCE, stated rather than implied: stapel-attributes ships English
|
|
9
|
+
* only (no `translations/` directory — which is why `gen:errors` runs with
|
|
10
|
+
* `ERRORS_LOCALE_EXEMPT_OWNERS=stapel_attributes` for forms-react), so the
|
|
11
|
+
* error copy below is pair-authored, not upstream, and unreviewed. Same grade
|
|
12
|
+
* as forms-react's copy of the same twelve keys, and deliberately the same
|
|
13
|
+
* WORDING — two pairs must not give one refusal two sentences.
|
|
14
|
+
*/
|
|
15
|
+
export declare const attributesI18nBundleRu: I18nDictionary;
|
|
16
|
+
/** Register the `ru` bundle. Call AFTER `registerAttributesI18n` so it
|
|
17
|
+
* overrides the English floor. */
|
|
18
|
+
export declare function registerAttributesI18nRu(engine: I18nEngine, locale?: string): void;
|
|
19
|
+
//# sourceMappingURL=ru.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ru.d.ts","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,cA0BpC,CAAC;AAEF;kCACkC;AAClC,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,SAAO,GAAG,IAAI,CAEhF"}
|
package/dist/i18n/ru.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Russian bundle — the `@stapel/attributes-react/i18n/ru` subpath, opt-in
|
|
3
|
+
* (i18n-shipping.md §2): the main entry does not import this module, so a
|
|
4
|
+
* host that does not register it never carries these strings (gated by
|
|
5
|
+
* size-limit).
|
|
6
|
+
*
|
|
7
|
+
* PROVENANCE, stated rather than implied: stapel-attributes ships English
|
|
8
|
+
* only (no `translations/` directory — which is why `gen:errors` runs with
|
|
9
|
+
* `ERRORS_LOCALE_EXEMPT_OWNERS=stapel_attributes` for forms-react), so the
|
|
10
|
+
* error copy below is pair-authored, not upstream, and unreviewed. Same grade
|
|
11
|
+
* as forms-react's copy of the same twelve keys, and deliberately the same
|
|
12
|
+
* WORDING — two pairs must not give one refusal two sentences.
|
|
13
|
+
*/
|
|
14
|
+
export const attributesI18nBundleRu = {
|
|
15
|
+
"error.400.feature_below_minimum": "Значение меньше минимального для «{feature}»",
|
|
16
|
+
"error.400.feature_above_maximum": "Значение больше максимального для «{feature}»",
|
|
17
|
+
"error.400.feature_not_in_options": "Значение отсутствует среди допустимых вариантов для «{feature}»",
|
|
18
|
+
"error.400.feature_invalid_type": "Неверный тип значения для «{feature}»",
|
|
19
|
+
"error.400.feature_invalid_format": "Неверный формат значения для «{feature}»",
|
|
20
|
+
"error.400.feature_mandatory_missing": "Поле «{feature}» обязательно для заполнения",
|
|
21
|
+
"error.400.feature_unknown_type": "Неизвестный тип поля «{feature}»",
|
|
22
|
+
"error.400.feature_not_allowed": "Поле «{feature}» здесь недопустимо",
|
|
23
|
+
"error.400.feature_unknown": "Неизвестное поле «{feature}»",
|
|
24
|
+
"error.400.feature_invalid_config": "Неверная конфигурация поля «{feature}»",
|
|
25
|
+
"error.400.description_too_short": "Описание должно содержать не менее {min_length} символов",
|
|
26
|
+
"error.400.description_too_long": "Описание должно содержать не более {max_length} символов",
|
|
27
|
+
"attributes.unsupported_type": "В этой сборке нет редактора для типа характеристики «{type}», заполнить её здесь нельзя.",
|
|
28
|
+
"attributes.submit.blocked.unsupported_type": "Часть характеристик нельзя заполнить на этой странице: {types}",
|
|
29
|
+
"attributes.untyped_feature": "У характеристики не указан тип, редактировать её нельзя.",
|
|
30
|
+
"attributes.value.not_set": "Не указано",
|
|
31
|
+
"attributes.value.unreadable": "Значение типа «{type}» в этой сборке не отображается",
|
|
32
|
+
"attributes.bool.yes": "Да",
|
|
33
|
+
"attributes.bool.no": "Нет",
|
|
34
|
+
"attributes.select.placeholder": "Выберите",
|
|
35
|
+
"attributes.required": "Обязательно",
|
|
36
|
+
};
|
|
37
|
+
/** Register the `ru` bundle. Call AFTER `registerAttributesI18n` so it
|
|
38
|
+
* overrides the English floor. */
|
|
39
|
+
export function registerAttributesI18nRu(engine, locale = "ru") {
|
|
40
|
+
engine.registerBundle(locale, attributesI18nBundleRu);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ru.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ru.js","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAmB;IACpD,iCAAiC,EAAE,8CAA8C;IACjF,iCAAiC,EAAE,+CAA+C;IAClF,kCAAkC,EAChC,iEAAiE;IACnE,gCAAgC,EAAE,uCAAuC;IACzE,kCAAkC,EAAE,0CAA0C;IAC9E,qCAAqC,EAAE,6CAA6C;IACpF,gCAAgC,EAAE,kCAAkC;IACpE,+BAA+B,EAAE,oCAAoC;IACrE,2BAA2B,EAAE,8BAA8B;IAC3D,kCAAkC,EAAE,wCAAwC;IAC5E,iCAAiC,EAAE,0DAA0D;IAC7F,gCAAgC,EAAE,0DAA0D;IAE5F,6BAA6B,EAC3B,0FAA0F;IAC5F,4CAA4C,EAC1C,gEAAgE;IAClE,4BAA4B,EAAE,0DAA0D;IACxF,0BAA0B,EAAE,YAAY;IACxC,6BAA6B,EAAE,sDAAsD;IACrF,qBAAqB,EAAE,IAAI;IAC3B,oBAAoB,EAAE,KAAK;IAC3B,+BAA+B,EAAE,UAAU;IAC3C,qBAAqB,EAAE,aAAa;CACrC,CAAC;AAEF;kCACkC;AAClC,MAAM,UAAU,wBAAwB,CAAC,MAAkB,EAAE,MAAM,GAAG,IAAI;IACxE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC"}
|