@pixi-ui-editor/schema 0.3.0 → 0.5.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.
@@ -0,0 +1,201 @@
1
+ import { type Static } from "@sinclair/typebox";
2
+ import type { ProjectDocument, ValidationIssue } from "./index.js";
3
+ export declare const LocalizationLocaleSchema: import("@sinclair/typebox").TObject<{
4
+ id: import("@sinclair/typebox").TString;
5
+ label: import("@sinclair/typebox").TString;
6
+ }>;
7
+ export type LocalizationLocale = Static<typeof LocalizationLocaleSchema>;
8
+ /**
9
+ * `entries[key][localeId]` — плоская строка перевода. Отсутствующий перевод — это отсутствие
10
+ * свойства локали, а не пустая строка: `""` является валидным заполненным переводом и обрывает
11
+ * fallback, поэтому резолвер нигде не проверяет значения через truthiness.
12
+ */
13
+ export declare const LocalizationSchema: import("@sinclair/typebox").TObject<{
14
+ baseLocale: import("@sinclair/typebox").TString;
15
+ locales: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
16
+ id: import("@sinclair/typebox").TString;
17
+ label: import("@sinclair/typebox").TString;
18
+ }>>;
19
+ entries: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TString>>;
20
+ }>;
21
+ export type LocalizationCatalog = Static<typeof LocalizationSchema>;
22
+ export declare const DEFAULT_LOCALE_ID = "en";
23
+ /** Каталог, который получает документ v19 при миграции и любой новый проект. */
24
+ export declare function createDefaultLocalization(): LocalizationCatalog;
25
+ /**
26
+ * Каноническая BCP-47 форма: `en`, `en-US`, `pt-BR`, `zh-Hant`, `zh-Hant-TW`.
27
+ *
28
+ * Грамматика намеренно узкая — только буквы, три цифры региона и дефис. Поэтому канонический ID
29
+ * автоматически является безопасным сегментом пути `locales/<locale>.json`: в нём не может быть
30
+ * ни `/`, ни `\`, ни `.`, ни `..`.
31
+ */
32
+ export declare function canonicalizeLocaleId(input: string): string | undefined;
33
+ export declare function isCanonicalLocaleId(id: string): boolean;
34
+ /**
35
+ * Справочник популярных локалей для UI выбора языка: готовый ID в канонической форме плюс
36
+ * английский display label. Он живёт рядом с `canonicalizeLocaleId`, потому что это часть
37
+ * локализационной модели, а не украшение панели: каждая запись обязана удовлетворять
38
+ * `canonicalizeLocaleId(id) === id`, иначе выбор из списка создал бы невалидный документ.
39
+ *
40
+ * Список намеренно неполон — он покрывает частые случаи и снимает ручной ввод, а редкая локаль
41
+ * по-прежнему добавляется вводом канонического BCP-47 идентификатора вручную.
42
+ */
43
+ export declare const COMMON_LOCALES: readonly {
44
+ id: string;
45
+ label: string;
46
+ }[];
47
+ /**
48
+ * Порядок локалей для любого UI: base locale первой, остальные сохраняют порядок объявления.
49
+ * Правило одно на весь редактор, поэтому и живёт оно здесь, а не копией в каждой панели.
50
+ */
51
+ export declare function orderLocalesForDisplay(catalog: LocalizationCatalog): LocalizationLocale[];
52
+ export declare const LOCALIZATION_DIRECTORY = "locales";
53
+ export declare const LOCALIZATION_COVERAGE_FILE = "locales/coverage.json";
54
+ /** Путь словаря внутри пакета. Безопасность сегмента гарантирует канонический ID. */
55
+ export declare function localeFilePath(localeId: string): string;
56
+ export type LocalizationParams = Readonly<Record<string, string | number>>;
57
+ /** Имена runtime-параметров `{name}` внутри значения перевода, детерминированно отсортированные. */
58
+ export declare function collectLocalizationParams(value: string): string[];
59
+ /** Неизвестный параметр остаётся видимым в фигурных скобках — это признак незаполненного значения. */
60
+ export declare function interpolateLocalizedText(value: string, params?: LocalizationParams): string;
61
+ export type LocalizationTranslateContext = {
62
+ key: string;
63
+ locale: string;
64
+ baseLocale: string;
65
+ params?: LocalizationParams;
66
+ };
67
+ /** Внешний переводчик потребителя. `undefined` означает «нет мнения» и не обрывает fallback. */
68
+ export type TranslateFn = (key: string, context: LocalizationTranslateContext) => string | undefined;
69
+ export type ResolveLocalizedTextInput = {
70
+ /** Авторская строка `Text.text`: ручной режим и последний содержательный fallback. */
71
+ text: string;
72
+ textKey?: string;
73
+ catalog?: LocalizationCatalog;
74
+ locale?: string;
75
+ translate?: TranslateFn;
76
+ params?: LocalizationParams;
77
+ };
78
+ /** Откуда взялась итоговая строка. `literal` — у ноды нет ключа и локализация не участвовала вообще. */
79
+ export type LocalizedTextSource = "literal" | "translate" | "locale" | "baseLocale" | "text" | "key";
80
+ export type LocalizedTextResolution = {
81
+ value: string;
82
+ source: LocalizedTextSource;
83
+ };
84
+ /**
85
+ * Единственная fallback-цепочка: внешний `translate` → выбранная локаль → базовая локаль →
86
+ * `Text.text` → сам ключ. Нода без `textKey` не обращается к локализации вообще, поэтому документ
87
+ * без ключей выглядит ровно как до появления каталога.
88
+ *
89
+ * Возвращает и значение, и источник: редактору нужно показать, почему на макете именно эта строка,
90
+ * и он обязан читать это из той же реализации, а не выводить цепочку заново.
91
+ */
92
+ export declare function describeLocalizedText(input: ResolveLocalizedTextInput): LocalizedTextResolution;
93
+ export declare function resolveLocalizedText(input: ResolveLocalizedTextInput): string;
94
+ /** Владелец иерархии, в которой найдена ссылка: сцена или определение пресета. */
95
+ export type LocalizationReferenceOwner = {
96
+ kind: "scene";
97
+ id: string;
98
+ } | {
99
+ kind: "prefab";
100
+ id: string;
101
+ };
102
+ export type LocalizationKeyReference = {
103
+ key: string;
104
+ path: string;
105
+ owner: LocalizationReferenceOwner;
106
+ /**
107
+ * Адрес узла в терминах редактора: собственный id персистентного/локального узла либо
108
+ * materialized-адрес `instanceId::prefab-node::nodePath` для property override.
109
+ */
110
+ nodeId: string;
111
+ };
112
+ /** Ссылка вместе с записью значения: одна и та же реализация обхода читает и переименовывает ключи. */
113
+ export type LocalizationKeyReferenceSite = LocalizationKeyReference & {
114
+ setKey(next: string): void;
115
+ };
116
+ /**
117
+ * Все ссылки `Text.textKey` документа: сцены, определения пресетов, локально добавленные узлы любой
118
+ * вложенности и persisted property overrides. Унаследованные узлы инстанса ключ не «размножают»:
119
+ * их источником является узел определения, уже посчитанный обходом `document.prefabs`.
120
+ *
121
+ * Обход единственный: `collectTextKeyReferences` только собирает результат, а rename каталога
122
+ * переписывает ключи через `setKey`, поэтому «где живут ссылки» описано ровно в одном месте.
123
+ */
124
+ export declare function forEachTextKeyReference(document: ProjectDocument, visit: (site: LocalizationKeyReferenceSite) => void): void;
125
+ export declare function collectTextKeyReferences(document: ProjectDocument): LocalizationKeyReference[];
126
+ export type LocalizationLocaleCoverage = {
127
+ id: string;
128
+ label: string;
129
+ isBase: boolean;
130
+ translated: number;
131
+ missingKeys: string[];
132
+ };
133
+ export type LocalizationCoverage = {
134
+ baseLocale: string;
135
+ /** Все ключи каталога — покрытие считается по каталогу, а не по текущему usage. */
136
+ keys: string[];
137
+ keyCount: number;
138
+ locales: LocalizationLocaleCoverage[];
139
+ usedKeys: string[];
140
+ unusedKeys: string[];
141
+ /** Ключи, на которые ссылается `Text`, но которых нет в каталоге. */
142
+ missingKeys: string[];
143
+ };
144
+ /** Детерминированное покрытие: и ключи, и локали, и списки отсортированы. */
145
+ export declare function computeLocalizationCoverage(document: ProjectDocument): LocalizationCoverage;
146
+ /**
147
+ * Structural/semantic ошибки каталога: они делают документ невалидным.
148
+ *
149
+ * Здесь только то, что нельзя доставить ни при каком заполнении переводов: неканоничный или
150
+ * дублирующийся locale ID, неизвестная base locale и пустая ссылка на ключ.
151
+ */
152
+ export declare function collectLocalizationErrors(document: ProjectDocument): ValidationIssue[];
153
+ /**
154
+ * Authoring diagnostics: каталог заполняется постепенно, поэтому всё это — warnings, и документ с
155
+ * ними остаётся валидным и сохраняемым.
156
+ */
157
+ export declare function collectLocalizationWarnings(document: ProjectDocument): ValidationIssue[];
158
+ export declare function collectLocalizationIssues(document: ProjectDocument): ValidationIssue[];
159
+ /**
160
+ * Строгая export-проверка: то же состояние, что в авторинге является warning, для пакета является
161
+ * блокирующей ошибкой, если ключ каталога вообще нельзя доставить — у него нет base translation.
162
+ * Неполные secondary locales и unused keys экспорт не блокируют и живут в coverage-отчёте.
163
+ */
164
+ export declare function collectLocalizationExportErrors(document: ProjectDocument): ValidationIssue[];
165
+ /**
166
+ * Словарь одной локали: плоский `Record<string, string>` без metadata wrapper, готовый любому
167
+ * внешнему i18n. Ключ попадает в файл только если у него есть значение именно этой локали;
168
+ * отсутствующий перевод не превращается в `""`, а остаётся отмеченным в coverage.
169
+ */
170
+ export declare function buildLocaleDictionary(catalog: LocalizationCatalog, localeId: string): Record<string, string>;
171
+ export declare function buildLocaleDictionaries(catalog: LocalizationCatalog): Record<string, Record<string, string>>;
172
+ export type LocalizationCoverageReport = LocalizationCoverage & {
173
+ warnings: ValidationIssue[];
174
+ };
175
+ /** Отчёт покрытия пакета: он дополняет словари, а не заменяет их. */
176
+ export declare function buildLocalizationCoverageReport(document: ProjectDocument): LocalizationCoverageReport;
177
+ /**
178
+ * Localization-часть пакета: по одному плоскому словарю на каждую объявленную локаль плюс отчёт
179
+ * покрытия. Каталог экспортируется целиком: unused-ключ может быть контрактом игрового кода, а
180
+ * usage текущей иерархии не доказывает, что он не нужен.
181
+ *
182
+ * Раскладка описана здесь и только здесь: и ZIP-экспорт редактора, и фикстура демо обязаны звать
183
+ * эту функцию, иначе демо проверяло бы не тот контракт. Документ ожидается уже подготовленным к
184
+ * доставке (без `editorOnly` поддеревьев), потому что coverage говорит о доставляемых `Text`.
185
+ */
186
+ export declare function collectPackageLocaleEntries(document: ProjectDocument): Record<string, string>;
187
+ /**
188
+ * Блокировка экспорта каталогом. Сообщение формируется ровно здесь, чтобы UI показывал ту же
189
+ * диагностику, что попадает в консоль, а не собственную формулировку.
190
+ */
191
+ export declare class LocalizationExportError extends Error {
192
+ readonly issues: ValidationIssue[];
193
+ constructor(issues: ValidationIssue[]);
194
+ }
195
+ /**
196
+ * Строгий pre-export gate. То, что в авторинге остаётся warning, здесь блокирует пакет, если ключ
197
+ * невозможно доставить вообще: у него нет перевода базовой локали. Неполные secondary locales и
198
+ * unused keys экспорт не останавливают и попадают только в `locales/coverage.json`.
199
+ */
200
+ export declare function assertExportableLocalization(document: ProjectDocument): void;
201
+ //# sourceMappingURL=localization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,368 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { materializedPrefabNodeId } from "./prefabs.js";
3
+ /**
4
+ * Единственная реализация локализации документа: контракт каталога, канонизация locale ID,
5
+ * fallback-цепочка, интерполяция параметров, сбор ссылок `Text.textKey`, покрытие и диагностики.
6
+ *
7
+ * Runtime, экспорт, редактор и демо обязаны переиспользовать именно её: дублирование fallback- или
8
+ * interpolation-логики в другом слое немедленно расходится по поведению.
9
+ */
10
+ const LocaleIdSchema = Type.String({ minLength: 1 });
11
+ export const LocalizationLocaleSchema = Type.Object({ id: LocaleIdSchema, label: Type.String({ minLength: 1 }) });
12
+ /**
13
+ * `entries[key][localeId]` — плоская строка перевода. Отсутствующий перевод — это отсутствие
14
+ * свойства локали, а не пустая строка: `""` является валидным заполненным переводом и обрывает
15
+ * fallback, поэтому резолвер нигде не проверяет значения через truthiness.
16
+ */
17
+ export const LocalizationSchema = Type.Object({
18
+ baseLocale: LocaleIdSchema,
19
+ locales: Type.Array(LocalizationLocaleSchema),
20
+ entries: Type.Record(Type.String({ minLength: 1 }), Type.Record(Type.String({ minLength: 1 }), Type.String())),
21
+ });
22
+ export const DEFAULT_LOCALE_ID = "en";
23
+ /** Каталог, который получает документ v19 при миграции и любой новый проект. */
24
+ export function createDefaultLocalization() {
25
+ return { baseLocale: DEFAULT_LOCALE_ID, locales: [{ id: DEFAULT_LOCALE_ID, label: "English" }], entries: {} };
26
+ }
27
+ /**
28
+ * Каноническая BCP-47 форма: `en`, `en-US`, `pt-BR`, `zh-Hant`, `zh-Hant-TW`.
29
+ *
30
+ * Грамматика намеренно узкая — только буквы, три цифры региона и дефис. Поэтому канонический ID
31
+ * автоматически является безопасным сегментом пути `locales/<locale>.json`: в нём не может быть
32
+ * ни `/`, ни `\`, ни `.`, ни `..`.
33
+ */
34
+ export function canonicalizeLocaleId(input) {
35
+ const parts = input.trim().split("-");
36
+ const language = parts[0];
37
+ if (language === undefined || !/^[A-Za-z]{2,3}$/.test(language))
38
+ return undefined;
39
+ const segments = [language.toLowerCase()];
40
+ let index = 1;
41
+ const script = parts[index];
42
+ if (script !== undefined && /^[A-Za-z]{4}$/.test(script)) {
43
+ segments.push(`${script[0].toUpperCase()}${script.slice(1).toLowerCase()}`);
44
+ index += 1;
45
+ }
46
+ const region = parts[index];
47
+ if (region !== undefined) {
48
+ if (/^[A-Za-z]{2}$/.test(region))
49
+ segments.push(region.toUpperCase());
50
+ else if (/^[0-9]{3}$/.test(region))
51
+ segments.push(region);
52
+ else
53
+ return undefined;
54
+ index += 1;
55
+ }
56
+ return index === parts.length ? segments.join("-") : undefined;
57
+ }
58
+ export function isCanonicalLocaleId(id) { return canonicalizeLocaleId(id) === id; }
59
+ /**
60
+ * Справочник популярных локалей для UI выбора языка: готовый ID в канонической форме плюс
61
+ * английский display label. Он живёт рядом с `canonicalizeLocaleId`, потому что это часть
62
+ * локализационной модели, а не украшение панели: каждая запись обязана удовлетворять
63
+ * `canonicalizeLocaleId(id) === id`, иначе выбор из списка создал бы невалидный документ.
64
+ *
65
+ * Список намеренно неполон — он покрывает частые случаи и снимает ручной ввод, а редкая локаль
66
+ * по-прежнему добавляется вводом канонического BCP-47 идентификатора вручную.
67
+ */
68
+ export const COMMON_LOCALES = [
69
+ { id: "en", label: "English" },
70
+ { id: "en-US", label: "English (United States)" },
71
+ { id: "en-GB", label: "English (United Kingdom)" },
72
+ { id: "ru", label: "Russian" },
73
+ { id: "ru-RU", label: "Russian (Russia)" },
74
+ { id: "uk", label: "Ukrainian" },
75
+ { id: "de", label: "German" },
76
+ { id: "fr", label: "French" },
77
+ { id: "fr-CA", label: "French (Canada)" },
78
+ { id: "es", label: "Spanish" },
79
+ { id: "es-ES", label: "Spanish (Spain)" },
80
+ { id: "es-419", label: "Spanish (Latin America)" },
81
+ { id: "pt-BR", label: "Portuguese (Brazil)" },
82
+ { id: "pt-PT", label: "Portuguese (Portugal)" },
83
+ { id: "it", label: "Italian" },
84
+ { id: "pl", label: "Polish" },
85
+ { id: "tr", label: "Turkish" },
86
+ { id: "nl", label: "Dutch" },
87
+ { id: "sv", label: "Swedish" },
88
+ { id: "da", label: "Danish" },
89
+ { id: "nb", label: "Norwegian Bokmal" },
90
+ { id: "fi", label: "Finnish" },
91
+ { id: "cs", label: "Czech" },
92
+ { id: "sk", label: "Slovak" },
93
+ { id: "hu", label: "Hungarian" },
94
+ { id: "ro", label: "Romanian" },
95
+ { id: "bg", label: "Bulgarian" },
96
+ { id: "el", label: "Greek" },
97
+ { id: "sr", label: "Serbian" },
98
+ { id: "hr", label: "Croatian" },
99
+ { id: "ar", label: "Arabic" },
100
+ { id: "he", label: "Hebrew" },
101
+ { id: "fa", label: "Persian" },
102
+ { id: "hi", label: "Hindi" },
103
+ { id: "th", label: "Thai" },
104
+ { id: "vi", label: "Vietnamese" },
105
+ { id: "id", label: "Indonesian" },
106
+ { id: "ms", label: "Malay" },
107
+ { id: "tl", label: "Filipino" },
108
+ { id: "ja", label: "Japanese" },
109
+ { id: "ko", label: "Korean" },
110
+ { id: "zh-Hans", label: "Chinese (Simplified)" },
111
+ { id: "zh-Hant", label: "Chinese (Traditional)" },
112
+ ];
113
+ /**
114
+ * Порядок локалей для любого UI: base locale первой, остальные сохраняют порядок объявления.
115
+ * Правило одно на весь редактор, поэтому и живёт оно здесь, а не копией в каждой панели.
116
+ */
117
+ export function orderLocalesForDisplay(catalog) {
118
+ return [
119
+ ...catalog.locales.filter((locale) => locale.id === catalog.baseLocale),
120
+ ...catalog.locales.filter((locale) => locale.id !== catalog.baseLocale),
121
+ ];
122
+ }
123
+ export const LOCALIZATION_DIRECTORY = "locales";
124
+ export const LOCALIZATION_COVERAGE_FILE = `${LOCALIZATION_DIRECTORY}/coverage.json`;
125
+ /** Путь словаря внутри пакета. Безопасность сегмента гарантирует канонический ID. */
126
+ export function localeFilePath(localeId) { return `${LOCALIZATION_DIRECTORY}/${localeId}.json`; }
127
+ const PARAM_PATTERN = /\{([A-Za-z0-9_.-]+)\}/g;
128
+ /** Имена runtime-параметров `{name}` внутри значения перевода, детерминированно отсортированные. */
129
+ export function collectLocalizationParams(value) {
130
+ return [...new Set([...value.matchAll(PARAM_PATTERN)].map((match) => match[1]))].sort();
131
+ }
132
+ /** Неизвестный параметр остаётся видимым в фигурных скобках — это признак незаполненного значения. */
133
+ export function interpolateLocalizedText(value, params) {
134
+ if (params === undefined)
135
+ return value;
136
+ return value.replace(PARAM_PATTERN, (match, name) => (Object.hasOwn(params, name) ? String(params[name]) : match));
137
+ }
138
+ /**
139
+ * Единственная fallback-цепочка: внешний `translate` → выбранная локаль → базовая локаль →
140
+ * `Text.text` → сам ключ. Нода без `textKey` не обращается к локализации вообще, поэтому документ
141
+ * без ключей выглядит ровно как до появления каталога.
142
+ *
143
+ * Возвращает и значение, и источник: редактору нужно показать, почему на макете именно эта строка,
144
+ * и он обязан читать это из той же реализации, а не выводить цепочку заново.
145
+ */
146
+ export function describeLocalizedText(input) {
147
+ const key = input.textKey?.trim();
148
+ if (key === undefined || key === "")
149
+ return { value: input.text, source: "literal" };
150
+ const baseLocale = input.catalog?.baseLocale ?? DEFAULT_LOCALE_ID;
151
+ const locale = input.locale ?? baseLocale;
152
+ const entry = input.catalog?.entries[key];
153
+ const external = input.translate?.(key, { key, locale, baseLocale, params: input.params });
154
+ const resolution = external !== undefined
155
+ ? { value: external, source: "translate" }
156
+ : entry !== undefined && Object.hasOwn(entry, locale) ? { value: entry[locale], source: "locale" }
157
+ : entry !== undefined && Object.hasOwn(entry, baseLocale) ? { value: entry[baseLocale], source: "baseLocale" }
158
+ : input.text.length > 0 ? { value: input.text, source: "text" } : { value: key, source: "key" };
159
+ return { value: interpolateLocalizedText(resolution.value, input.params), source: resolution.source };
160
+ }
161
+ export function resolveLocalizedText(input) {
162
+ return describeLocalizedText(input).value;
163
+ }
164
+ /**
165
+ * Все ссылки `Text.textKey` документа: сцены, определения пресетов, локально добавленные узлы любой
166
+ * вложенности и persisted property overrides. Унаследованные узлы инстанса ключ не «размножают»:
167
+ * их источником является узел определения, уже посчитанный обходом `document.prefabs`.
168
+ *
169
+ * Обход единственный: `collectTextKeyReferences` только собирает результат, а rename каталога
170
+ * переписывает ключи через `setKey`, поэтому «где живут ссылки» описано ровно в одном месте.
171
+ */
172
+ export function forEachTextKeyReference(document, visit) {
173
+ const visitNode = (node, path, owner) => {
174
+ if (node.type === "text" && node.textKey !== undefined) {
175
+ visit({ key: node.textKey, path: `${path}/textKey`, owner, nodeId: node.id, setKey: (next) => { node.textKey = next; } });
176
+ }
177
+ if (node.type !== "prefab-instance")
178
+ return;
179
+ (node.propertyOverrides ?? []).forEach((override, index) => {
180
+ const value = override.patch.textKey;
181
+ if (typeof value !== "string")
182
+ return;
183
+ visit({
184
+ key: value,
185
+ path: `${path}/propertyOverrides/${index}/patch/textKey`,
186
+ owner,
187
+ nodeId: materializedPrefabNodeId(node.id, override.nodeId),
188
+ setKey: (next) => { override.patch.textKey = next; },
189
+ });
190
+ });
191
+ (node.locallyAddedNodes ?? []).forEach((local, index) => visitNode(local, `${path}/locallyAddedNodes/${index}`, owner));
192
+ };
193
+ document.scenes.forEach((scene, sceneIndex) => scene.nodes.forEach((node, nodeIndex) => visitNode(node, `/scenes/${sceneIndex}/nodes/${nodeIndex}`, { kind: "scene", id: scene.id })));
194
+ document.prefabs.forEach((prefab, prefabIndex) => prefab.nodes.forEach((node, nodeIndex) => visitNode(node, `/prefabs/${prefabIndex}/nodes/${nodeIndex}`, { kind: "prefab", id: prefab.id })));
195
+ }
196
+ export function collectTextKeyReferences(document) {
197
+ const references = [];
198
+ forEachTextKeyReference(document, ({ key, path, owner, nodeId }) => references.push({ key, path, owner, nodeId }));
199
+ return references;
200
+ }
201
+ /** Детерминированное покрытие: и ключи, и локали, и списки отсортированы. */
202
+ export function computeLocalizationCoverage(document) {
203
+ const catalog = document.localization;
204
+ const keys = Object.keys(catalog.entries).sort();
205
+ const referenced = new Set(collectTextKeyReferences(document).map((reference) => reference.key.trim()).filter((key) => key !== ""));
206
+ const usedKeys = keys.filter((key) => referenced.has(key));
207
+ return {
208
+ baseLocale: catalog.baseLocale,
209
+ keys,
210
+ keyCount: keys.length,
211
+ locales: catalog.locales.map((locale) => {
212
+ const missingKeys = keys.filter((key) => !Object.hasOwn(catalog.entries[key], locale.id));
213
+ return { id: locale.id, label: locale.label, isBase: locale.id === catalog.baseLocale, translated: keys.length - missingKeys.length, missingKeys };
214
+ }),
215
+ usedKeys,
216
+ unusedKeys: keys.filter((key) => !referenced.has(key)),
217
+ missingKeys: [...referenced].filter((key) => !Object.hasOwn(catalog.entries, key)).sort(),
218
+ };
219
+ }
220
+ const issue = (code, path, message, severity) => ({ code, path, message, severity });
221
+ /**
222
+ * Structural/semantic ошибки каталога: они делают документ невалидным.
223
+ *
224
+ * Здесь только то, что нельзя доставить ни при каком заполнении переводов: неканоничный или
225
+ * дублирующийся locale ID, неизвестная base locale и пустая ссылка на ключ.
226
+ */
227
+ export function collectLocalizationErrors(document) {
228
+ const issues = [];
229
+ const catalog = document.localization;
230
+ const seen = new Set();
231
+ catalog.locales.forEach((locale, index) => {
232
+ const path = `/localization/locales/${index}/id`;
233
+ if (!isCanonicalLocaleId(locale.id))
234
+ issues.push(issue("INVALID_LOCALE_ID", path, `Locale '${locale.id}' is not a canonical BCP-47 identifier.`, "error"));
235
+ if (seen.has(locale.id))
236
+ issues.push(issue("DUPLICATE_LOCALE", path, `Locale '${locale.id}' is declared more than once.`, "error"));
237
+ seen.add(locale.id);
238
+ });
239
+ if (!seen.has(catalog.baseLocale))
240
+ issues.push(issue("UNKNOWN_BASE_LOCALE", "/localization/baseLocale", `Base locale '${catalog.baseLocale}' is not declared.`, "error"));
241
+ for (const key of Object.keys(catalog.entries)) {
242
+ if (key.trim() === "")
243
+ issues.push(issue("EMPTY_LOCALIZATION_KEY", `/localization/entries/${key}`, "A localization key must not be blank.", "error"));
244
+ }
245
+ for (const reference of collectTextKeyReferences(document)) {
246
+ if (reference.key.trim() === "")
247
+ issues.push(issue("EMPTY_LOCALIZATION_KEY", reference.path, "A textKey reference must not be blank.", "error"));
248
+ }
249
+ return issues;
250
+ }
251
+ /**
252
+ * Authoring diagnostics: каталог заполняется постепенно, поэтому всё это — warnings, и документ с
253
+ * ними остаётся валидным и сохраняемым.
254
+ */
255
+ export function collectLocalizationWarnings(document) {
256
+ const issues = [];
257
+ const catalog = document.localization;
258
+ const coverage = computeLocalizationCoverage(document);
259
+ const declared = new Set(catalog.locales.map((locale) => locale.id));
260
+ for (const reference of collectTextKeyReferences(document)) {
261
+ const key = reference.key.trim();
262
+ if (key !== "" && !Object.hasOwn(catalog.entries, key))
263
+ issues.push(issue("MISSING_LOCALIZATION_ENTRY", reference.path, `Localization key '${key}' is not in the catalog.`, "warning"));
264
+ }
265
+ for (const key of coverage.keys) {
266
+ const entry = catalog.entries[key];
267
+ if (!Object.hasOwn(entry, catalog.baseLocale))
268
+ issues.push(issue("MISSING_BASE_TRANSLATION", `/localization/entries/${key}`, `Key '${key}' has no '${catalog.baseLocale}' translation.`, "warning"));
269
+ const baseParams = Object.hasOwn(entry, catalog.baseLocale) ? collectLocalizationParams(entry[catalog.baseLocale]).join(",") : undefined;
270
+ for (const localeId of Object.keys(entry).sort()) {
271
+ if (!declared.has(localeId)) {
272
+ issues.push(issue("UNKNOWN_TRANSLATION_LOCALE", `/localization/entries/${key}/${localeId}`, `Locale '${localeId}' is not declared and will not be exported.`, "warning"));
273
+ continue;
274
+ }
275
+ if (baseParams === undefined || localeId === catalog.baseLocale)
276
+ continue;
277
+ if (collectLocalizationParams(entry[localeId]).join(",") !== baseParams)
278
+ issues.push(issue("PARAM_MISMATCH", `/localization/entries/${key}/${localeId}`, `Translation '${key}' for '${localeId}' uses different runtime parameters than the base locale.`, "warning"));
279
+ }
280
+ }
281
+ for (const locale of coverage.locales) {
282
+ if (locale.isBase || locale.missingKeys.length === 0)
283
+ continue;
284
+ issues.push(issue("INCOMPLETE_LOCALE", `/localization/locales/${catalog.locales.findIndex((candidate) => candidate.id === locale.id)}`, `Locale '${locale.id}' is missing ${locale.missingKeys.length} translation(s).`, "warning"));
285
+ }
286
+ for (const key of coverage.unusedKeys) {
287
+ issues.push(issue("UNUSED_LOCALIZATION_KEY", `/localization/entries/${key}`, `Key '${key}' is not referenced by any delivered Text node.`, "warning"));
288
+ }
289
+ return issues;
290
+ }
291
+ export function collectLocalizationIssues(document) {
292
+ return [...collectLocalizationErrors(document), ...collectLocalizationWarnings(document)];
293
+ }
294
+ /**
295
+ * Строгая export-проверка: то же состояние, что в авторинге является warning, для пакета является
296
+ * блокирующей ошибкой, если ключ каталога вообще нельзя доставить — у него нет base translation.
297
+ * Неполные secondary locales и unused keys экспорт не блокируют и живут в coverage-отчёте.
298
+ */
299
+ export function collectLocalizationExportErrors(document) {
300
+ const catalog = document.localization;
301
+ const issues = collectLocalizationErrors(document);
302
+ for (const key of Object.keys(catalog.entries).sort()) {
303
+ if (!Object.hasOwn(catalog.entries[key], catalog.baseLocale))
304
+ issues.push(issue("MISSING_BASE_TRANSLATION", `/localization/entries/${key}`, `Key '${key}' cannot be delivered: it has no '${catalog.baseLocale}' translation.`, "error"));
305
+ }
306
+ return issues;
307
+ }
308
+ /**
309
+ * Словарь одной локали: плоский `Record<string, string>` без metadata wrapper, готовый любому
310
+ * внешнему i18n. Ключ попадает в файл только если у него есть значение именно этой локали;
311
+ * отсутствующий перевод не превращается в `""`, а остаётся отмеченным в coverage.
312
+ */
313
+ export function buildLocaleDictionary(catalog, localeId) {
314
+ const dictionary = {};
315
+ for (const key of Object.keys(catalog.entries).sort()) {
316
+ const entry = catalog.entries[key];
317
+ if (Object.hasOwn(entry, localeId))
318
+ dictionary[key] = entry[localeId];
319
+ }
320
+ return dictionary;
321
+ }
322
+ export function buildLocaleDictionaries(catalog) {
323
+ return Object.fromEntries(catalog.locales.map((locale) => [locale.id, buildLocaleDictionary(catalog, locale.id)]));
324
+ }
325
+ /** Отчёт покрытия пакета: он дополняет словари, а не заменяет их. */
326
+ export function buildLocalizationCoverageReport(document) {
327
+ return { ...computeLocalizationCoverage(document), warnings: collectLocalizationWarnings(document) };
328
+ }
329
+ /**
330
+ * Localization-часть пакета: по одному плоскому словарю на каждую объявленную локаль плюс отчёт
331
+ * покрытия. Каталог экспортируется целиком: unused-ключ может быть контрактом игрового кода, а
332
+ * usage текущей иерархии не доказывает, что он не нужен.
333
+ *
334
+ * Раскладка описана здесь и только здесь: и ZIP-экспорт редактора, и фикстура демо обязаны звать
335
+ * эту функцию, иначе демо проверяло бы не тот контракт. Документ ожидается уже подготовленным к
336
+ * доставке (без `editorOnly` поддеревьев), потому что coverage говорит о доставляемых `Text`.
337
+ */
338
+ export function collectPackageLocaleEntries(document) {
339
+ const entries = {};
340
+ for (const locale of document.localization.locales) {
341
+ entries[localeFilePath(locale.id)] = `${JSON.stringify(buildLocaleDictionary(document.localization, locale.id), null, 2)}\n`;
342
+ }
343
+ entries[LOCALIZATION_COVERAGE_FILE] = `${JSON.stringify(buildLocalizationCoverageReport(document), null, 2)}\n`;
344
+ return entries;
345
+ }
346
+ /**
347
+ * Блокировка экспорта каталогом. Сообщение формируется ровно здесь, чтобы UI показывал ту же
348
+ * диагностику, что попадает в консоль, а не собственную формулировку.
349
+ */
350
+ export class LocalizationExportError extends Error {
351
+ issues;
352
+ constructor(issues) {
353
+ super(`The localization catalog cannot be packaged:\n${issues.map((item) => `• ${item.message} (${item.code} at ${item.path})`).join("\n")}`);
354
+ this.name = "LocalizationExportError";
355
+ this.issues = issues;
356
+ }
357
+ }
358
+ /**
359
+ * Строгий pre-export gate. То, что в авторинге остаётся warning, здесь блокирует пакет, если ключ
360
+ * невозможно доставить вообще: у него нет перевода базовой локали. Неполные secondary locales и
361
+ * unused keys экспорт не останавливают и попадают только в `locales/coverage.json`.
362
+ */
363
+ export function assertExportableLocalization(document) {
364
+ const errors = collectLocalizationExportErrors(document);
365
+ if (errors.length > 0)
366
+ throw new LocalizationExportError(errors);
367
+ }
368
+ //# sourceMappingURL=localization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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"}