@i18nprune/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/adapters-gp1lXp0T.d.ts +12 -0
  4. package/dist/capabilities-x74cD2Hu.d.ts +48 -0
  5. package/dist/cleanup.d.ts +64 -0
  6. package/dist/cleanup.js +3999 -0
  7. package/dist/config.d.ts +201 -0
  8. package/dist/config.js +2865 -0
  9. package/dist/coreContext-DMaWLvmB.d.ts +388 -0
  10. package/dist/fs-BUYD8ZhA.d.ts +20 -0
  11. package/dist/generate.d.ts +487 -0
  12. package/dist/generate.js +9389 -0
  13. package/dist/humanEmit-ygNlYX-S.d.ts +79 -0
  14. package/dist/index-BQuLEQ9b.d.ts +7 -0
  15. package/dist/index-B_ow_Xvr.d.ts +97 -0
  16. package/dist/index-BgG01AKL.d.ts +287 -0
  17. package/dist/index-CIzZl4W8.d.ts +124 -0
  18. package/dist/index-Csm1w7XD.d.ts +58 -0
  19. package/dist/index-DLwTogCo.d.ts +43 -0
  20. package/dist/index-DVT26v11.d.ts +61 -0
  21. package/dist/index-DdjljwMj.d.ts +39 -0
  22. package/dist/index-DeIw-cZd.d.ts +52 -0
  23. package/dist/index-X50E1FIX.d.ts +50 -0
  24. package/dist/index.d.ts +9180 -0
  25. package/dist/index.js +21888 -0
  26. package/dist/init.d.ts +86 -0
  27. package/dist/init.js +848 -0
  28. package/dist/listWindow-XEFxQZi1.d.ts +30 -0
  29. package/dist/localeTargetCodes-BBIQjauw.d.ts +11 -0
  30. package/dist/locales.d.ts +39 -0
  31. package/dist/locales.js +2288 -0
  32. package/dist/missing-BVCvgUC8.d.ts +10 -0
  33. package/dist/missing.d.ts +85 -0
  34. package/dist/missing.js +5892 -0
  35. package/dist/modeResolve-cGVaY5Hh.d.ts +25 -0
  36. package/dist/path-Bfn3SAts.d.ts +11 -0
  37. package/dist/profile-BwOP9WKh.d.ts +9 -0
  38. package/dist/providers-0uMEfT6q.d.ts +82 -0
  39. package/dist/prune-c6hKZCv_.d.ts +33 -0
  40. package/dist/quality.d.ts +36 -0
  41. package/dist/quality.js +3868 -0
  42. package/dist/report-D5-6bVFj.d.ts +8 -0
  43. package/dist/report-schema.d.ts +102 -0
  44. package/dist/report-schema.js +42 -0
  45. package/dist/resumeCandidates-xR13eEwt.d.ts +200 -0
  46. package/dist/root-2-kCaBvQ.d.ts +1110 -0
  47. package/dist/runtime/edge.d.ts +21 -0
  48. package/dist/runtime/edge.js +87 -0
  49. package/dist/runtime/helpers/sync.d.ts +16 -0
  50. package/dist/runtime/helpers/sync.js +117 -0
  51. package/dist/runtime/node.d.ts +24 -0
  52. package/dist/runtime/node.js +204 -0
  53. package/dist/runtime/web.d.ts +21 -0
  54. package/dist/runtime/web.js +84 -0
  55. package/dist/shared.d.ts +1177 -0
  56. package/dist/shared.js +4897 -0
  57. package/dist/sourceContext-1LQg3HiQ.d.ts +36 -0
  58. package/dist/sourceSurface-mDtwGo1E.d.ts +122 -0
  59. package/dist/sync.d.ts +86 -0
  60. package/dist/sync.js +4971 -0
  61. package/dist/syncSegment-Bx6He2Mu.d.ts +149 -0
  62. package/dist/targets-EmtKyr6F.d.ts +23 -0
  63. package/dist/template-CGM-_WLT.d.ts +139 -0
  64. package/dist/translate-CIHYp7wi.d.ts +77 -0
  65. package/dist/types/shared.d.ts +21 -0
  66. package/dist/types/shared.js +1 -0
  67. package/dist/types.d.ts +1345 -0
  68. package/dist/types.js +1 -0
  69. package/dist/validate.d.ts +126 -0
  70. package/dist/validate.js +3717 -0
  71. package/package.json +128 -0
@@ -0,0 +1,79 @@
1
+ import { D as DynamicKeySite } from './index-DdjljwMj.js';
2
+ import { I as Issue } from './index-X50E1FIX.js';
3
+ import { L as LocaleMetadataReport } from './index-DLwTogCo.js';
4
+ import { R as RunEmitter, S as SyncProgressEvent } from './index-BgG01AKL.js';
5
+ import { S as SourcePlaceholderLeaf, L as LocalePlaceholderLeaf } from './index-DeIw-cZd.js';
6
+
7
+ /** Counts for human sync logging (**merge + prune** vs source template only). */
8
+ type SyncHumanLeafSummary = {
9
+ /** Source paths that had no existing leaf in the target before sync. */
10
+ hydratedFromSource: number;
11
+ /** Source paths that already had a readable leaf before merge+prune. */
12
+ preservedExistingLeaves: number;
13
+ /** Previously present string-leaf dotted paths outside the template (removed to match source shape). */
14
+ prunedExtraLeaves: number;
15
+ };
16
+
17
+ type SyncFileLine = {
18
+ path: string;
19
+ changed: boolean;
20
+ };
21
+ /**
22
+ * Payload shape for `i18nprune sync --json`.
23
+ * Additive fields may appear in future versions.
24
+ */
25
+ type SyncJsonOutput = {
26
+ kind: 'sync';
27
+ sourcePath: string;
28
+ localesDir: string;
29
+ targetFiles: number;
30
+ writtenFiles: number;
31
+ dynamicKeySites: number;
32
+ dryRun: boolean;
33
+ files: SyncFileLine[];
34
+ localeMetadataReports?: Record<string, LocaleMetadataReport>;
35
+ };
36
+ type SyncRunOptions = {
37
+ /** Report only; do not write locale files. */
38
+ dryRun?: boolean;
39
+ /** Comma-separated locale basenames, or `all` (default: all non-source locales). */
40
+ target?: string;
41
+ /** Write/repair structured locale leaves (`{ value, status, confidence, needsReview, source }`). */
42
+ metadata?: boolean;
43
+ /** Force reset structured leaf metadata to plain string values. */
44
+ stripMetadata?: boolean;
45
+ };
46
+ type SyncHostHooks = {
47
+ emit?: RunEmitter;
48
+ runId?: string;
49
+ emitProgress: (e: Omit<Extract<SyncProgressEvent, {
50
+ type: 'run.progress.sync';
51
+ }>, 'op' | 'runId' | 'at'>) => void;
52
+ };
53
+ type SyncRunResult = {
54
+ payload: SyncJsonOutput;
55
+ issues: Issue[];
56
+ fileLines: SyncFileLine[];
57
+ targets: string[];
58
+ updated: number;
59
+ dynamicSites: DynamicKeySite[];
60
+ keyObservationsCount: number;
61
+ /** Requested locale codes with no matching file under `localesDir` (human-mode warning). */
62
+ missingLocaleCodes: string[];
63
+ /** Per-locale leaf stats for human stderr (not part of `--json`). */
64
+ humanLeafSummaryByLocaleFile: Record<string, SyncHumanLeafSummary>;
65
+ /** Source placeholder leaves skipped to avoid copying scaffold sentinels into target locales. */
66
+ sourcePlaceholderLeaves: SourcePlaceholderLeaf[];
67
+ /** Target placeholder leaves observed before sync applies its source-shape plan. */
68
+ targetPlaceholderLeaves: LocalePlaceholderLeaf[];
69
+ };
70
+
71
+ type SyncLocaleDisplayGroup = {
72
+ localeCode: string;
73
+ reportKeys: string[];
74
+ fileLines: SyncFileLine[];
75
+ changedCount: number;
76
+ summaries: SyncHumanLeafSummary[];
77
+ };
78
+
79
+ export type { SyncHostHooks as S, SyncRunResult as a, SyncRunOptions as b, SyncHumanLeafSummary as c, SyncFileLine as d, SyncJsonOutput as e, SyncLocaleDisplayGroup as f };
@@ -0,0 +1,7 @@
1
+ /** One string leaf in a JSON tree (`a[0].b` style paths). */
2
+ type StringLeaf = {
3
+ path: string;
4
+ value: string;
5
+ };
6
+
7
+ export type { StringLeaf as S };
@@ -0,0 +1,97 @@
1
+ import { a as LocaleLeafMode, S as StructuredLocaleLeaf } from './index-DLwTogCo.js';
2
+ import { T as TranslationProviderId } from './providers-0uMEfT6q.js';
3
+
4
+ type ApplyLocaleMetadataModeInput = {
5
+ localeJson: unknown;
6
+ sourceMap: Map<string, string>;
7
+ mode: LocaleLeafMode;
8
+ sampleLimit?: number;
9
+ };
10
+ type ResolveLocaleLeafModeInput = {
11
+ configMode?: LocaleLeafMode;
12
+ metadataFlag?: boolean;
13
+ stripMetadataFlag?: boolean;
14
+ };
15
+
16
+ /**
17
+ * Optional per-leaf fields merged into a structured locale leaf (`{ value, … }`).
18
+ * `value` always comes from {@link TranslationResult.text}; this patch is everything else.
19
+ */
20
+ type TranslationLeafMetaPatch = Partial<Pick<StructuredLocaleLeaf, 'status' | 'confidence' | 'needsReview' | 'needsTranslationAgain' | 'source'>>;
21
+ /**
22
+ * Rich provider response (before heuristic merge). `leafMeta` may be partial or omitted.
23
+ */
24
+ type TranslationProviderYield = {
25
+ readonly text: string;
26
+ readonly leafMeta?: TranslationLeafMetaPatch;
27
+ };
28
+ /**
29
+ * Final per-leaf metadata after provider + heuristic merge (`translateLeaf`).
30
+ * All fields are always set so hosts can rely on them without optional chaining.
31
+ */
32
+ type TranslationLeafMeta = {
33
+ status: string;
34
+ confidence: number | null;
35
+ needsReview: boolean;
36
+ needsTranslationAgain: boolean;
37
+ source: string;
38
+ };
39
+ /**
40
+ * Post-translation routing signal for a single leaf.
41
+ *
42
+ * - `'translated'` — leaf is final; downstream consumers treat it as done.
43
+ * - `'review'` — leaf needs human or workflow attention before it can be considered
44
+ * complete. The persisted marker is `needsReview: true` on the structured leaf
45
+ * (no separate key — see `translate-policy (shipped)` §5).
46
+ *
47
+ * The decision is the source of truth; the structured-leaf `needsReview` flag mirrors it.
48
+ * `finalizeTranslationLeafMeta` enforces the mirror.
49
+ */
50
+ type LeafDecision = 'translated' | 'review';
51
+ /**
52
+ * Output of {@link translateLeaf}: final string plus **merged** metadata (provider + heuristic).
53
+ * **`leafMeta`** is always fully populated. The CLI only **persists** structured locale JSON when the
54
+ * user passes **`--metadata`**; core does not strip metadata based on that flag.
55
+ */
56
+ type TranslationResult = {
57
+ readonly text: string;
58
+ readonly leafMeta: TranslationLeafMeta;
59
+ /** Optional policy decision; `review` promotes attention workflows downstream. */
60
+ readonly decision?: LeafDecision;
61
+ /** Runtime-only transport stats (not persisted to locale JSON). */
62
+ readonly runtime?: {
63
+ attempts: number;
64
+ retries: number;
65
+ };
66
+ };
67
+ /** Context for heuristic metadata when a provider returns no scores. */
68
+ type HeuristicLeafMetaInput = {
69
+ readonly sourceText: string;
70
+ readonly translatedText: string;
71
+ readonly providerId: TranslationProviderId;
72
+ };
73
+
74
+ /** HTTP/API backend: one string in, one string out (placeholders handled by `Translator`). */
75
+ type TranslateRequest = {
76
+ text: string;
77
+ sourceLang: string;
78
+ targetLang: string;
79
+ };
80
+ /** Defaults: 3 tries; delays 400ms / 900ms after 1st and 2nd failure. */
81
+ type TranslatorRetryOptions = {
82
+ maxAttempts: number;
83
+ delaysMs: number[];
84
+ };
85
+ type Translator = {
86
+ translate(text: string, sourceLang: string, targetLang: string): Promise<string | TranslationProviderYield | TranslationResult>;
87
+ };
88
+
89
+ type TranslateTargetLanguage = {
90
+ code: string;
91
+ english: string;
92
+ native: string;
93
+ direction: 'ltr' | 'rtl';
94
+ [extra: string]: unknown;
95
+ };
96
+
97
+ export type { ApplyLocaleMetadataModeInput as A, HeuristicLeafMetaInput as H, LeafDecision as L, ResolveLocaleLeafModeInput as R, TranslationResult as T, TranslationLeafMeta as a, TranslateTargetLanguage as b, Translator as c, TranslateRequest as d, TranslationLeafMetaPatch as e, TranslationProviderYield as f, TranslatorRetryOptions as g };
@@ -0,0 +1,287 @@
1
+ import { I as Issue } from './index-X50E1FIX.js';
2
+ import { T as TranslationProviderId } from './providers-0uMEfT6q.js';
3
+
4
+ /**
5
+ * Core share cache + worker envelope types (disk `share.json` + worker JSON).
6
+ * @see maintainer/systems/share.md
7
+ */
8
+
9
+ type ShareKind = 'project' | 'report';
10
+ /** On-disk `share.json` (v1) beside `files.json` / `analysis.json`. */
11
+ type ShareJsonFile = {
12
+ version: 1;
13
+ entries: ShareCacheEntry[];
14
+ };
15
+ type ShareLinks = {
16
+ web?: string;
17
+ report?: string;
18
+ worker?: string;
19
+ };
20
+ /** One recorded upload from this machine (local cache metadata). */
21
+ type ShareCacheEntry = {
22
+ kind: ShareKind;
23
+ workerBaseUrl: string;
24
+ workerProjectId?: string;
25
+ workerReportId?: string;
26
+ payloadContentHash: string;
27
+ configHash?: string;
28
+ /** Tracked-files epoch from `files.json` when the project snapshot was last shared (skip zip rebuild). */
29
+ inputFilesEpoch?: string;
30
+ byteSize: number;
31
+ uploadedAt: string;
32
+ lastUsedAt: string;
33
+ links: ShareLinks;
34
+ };
35
+ type ShareJsonHealKind = 'missing_file' | 'invalid_json' | 'oversized_file' | 'version_reset' | 'entries_sanitized' | 'duplicates_merged';
36
+ type ShareJsonHealReport = {
37
+ /** True when any corrective action was applied (including initializing an empty file). */
38
+ repaired: boolean;
39
+ actions: ShareJsonHealKind[];
40
+ /** Human-readable detail lines for hosts (CLI may log once). */
41
+ details: string[];
42
+ /** Set when the previous `share.json` was copied under `share.bak/` before replace. */
43
+ backupBakPath?: string;
44
+ };
45
+ type LoadShareJsonResult = {
46
+ file: ShareJsonFile;
47
+ heal: ShareJsonHealReport;
48
+ issues: Issue[];
49
+ };
50
+ /** Parsed worker JSON envelope (subset used by share / worker hosts). */
51
+ type WorkerShareEnvelope = {
52
+ success: boolean;
53
+ code?: string;
54
+ data: unknown;
55
+ errors: Array<{
56
+ code: string;
57
+ message: string;
58
+ }>;
59
+ warnings?: Array<{
60
+ code: string;
61
+ message: string;
62
+ }>;
63
+ };
64
+
65
+ /**
66
+ * Prepared project snapshot manifest (zip not included — described by hashes + counts).
67
+ */
68
+ type ShareProjectManifest = {
69
+ kind: 'project';
70
+ fileCount: number;
71
+ textFileCount: number;
72
+ byteSize: number;
73
+ /** Distinct first path segments (cap ~20) for human logs. */
74
+ topLevelPrefixes: readonly string[];
75
+ /** Short label describing built-in exclude rules (see `shouldSkipPathForShareZip`). */
76
+ appliedZipIgnoresLabel: string;
77
+ payloadContentHash: string;
78
+ configHash: string;
79
+ detectedConfigRelPath: string | null;
80
+ };
81
+ /** Prepared report payload manifest (validated `ProjectReportDocument` JSON). */
82
+ type ShareReportManifest = {
83
+ kind: 'report';
84
+ byteSize: number;
85
+ payloadContentHash: string;
86
+ schemaVersion: number;
87
+ toolVersion: string;
88
+ generatedAt: string;
89
+ };
90
+ type ShareManifest = ShareProjectManifest | ShareReportManifest;
91
+
92
+ /**
93
+ * Known operation identifiers for `run.*` events.
94
+ *
95
+ * Note: this is intentionally small while the event contract is being threaded
96
+ * through operations. Expand as each operation adopts `run.*`.
97
+ */
98
+ type OperationId = 'generate' | 'sync' | 'validate' | 'quality' | 'doctor' | 'report' | 'review' | 'missing' | 'cleanup' | 'locales-dynamic' | 'share';
99
+ type RunEventBase = {
100
+ /** Operation identifier (matches `CliJsonEnvelope.kind`). */
101
+ op: OperationId;
102
+ /** Optional run correlation id (host-provided). */
103
+ runId?: string;
104
+ };
105
+ type RunStartedEvent = RunEventBase & {
106
+ type: 'run.started';
107
+ at: number;
108
+ };
109
+ type GenerateCounts = {
110
+ targets: number;
111
+ leaves: number;
112
+ dynamicKeySites: number;
113
+ };
114
+ type SyncCounts = {
115
+ targets: number;
116
+ written: number;
117
+ dynamicKeySites: number;
118
+ };
119
+ type ValidateCounts = {
120
+ missing: number;
121
+ dynamic: number;
122
+ keyObservations: number;
123
+ };
124
+ type QualityCounts = {
125
+ total: number;
126
+ dynamicKeySites: number;
127
+ };
128
+ type DoctorCounts = {
129
+ findings: number;
130
+ };
131
+ type ReportCounts = {
132
+ filesScanned?: number;
133
+ missing?: number;
134
+ dynamic?: number;
135
+ keyObservations?: number;
136
+ };
137
+ type ReviewCounts = {
138
+ locales: number;
139
+ dynamicKeySites: number;
140
+ };
141
+ type MissingCounts = {
142
+ pathsAdded: number;
143
+ targets?: number;
144
+ skippedTargets?: number;
145
+ };
146
+ type CleanupCounts = {
147
+ wouldRemove: number;
148
+ dynamicKeySites: number;
149
+ };
150
+ type LocalesDynamicCounts = {
151
+ dynamicKeySites: number;
152
+ shown: number;
153
+ };
154
+ type ShareCounts = {
155
+ fileCount: number;
156
+ zipBytes: number;
157
+ };
158
+ type RunCountsByOperation = {
159
+ generate: GenerateCounts;
160
+ sync: SyncCounts;
161
+ validate: ValidateCounts;
162
+ quality: QualityCounts;
163
+ doctor: DoctorCounts;
164
+ report: ReportCounts;
165
+ review: ReviewCounts;
166
+ missing: MissingCounts;
167
+ cleanup: CleanupCounts;
168
+ 'locales-dynamic': LocalesDynamicCounts;
169
+ share: ShareCounts;
170
+ };
171
+ type RunCompletedEventFor<T extends OperationId> = Omit<RunEventBase, 'op'> & {
172
+ op: T;
173
+ type: 'run.completed';
174
+ at: number;
175
+ ok: boolean;
176
+ };
177
+ type RunCompletedEvent = {
178
+ [K in OperationId]: RunCompletedEventFor<K>;
179
+ }[OperationId];
180
+ type RunFailedEvent = RunEventBase & {
181
+ type: 'run.failed';
182
+ at: number;
183
+ error: {
184
+ /** Stable-ish error identifier for clients (not necessarily an issue code). */
185
+ name: string;
186
+ message: string;
187
+ recoverable: false;
188
+ };
189
+ };
190
+ type RunWarningEvent = RunEventBase & {
191
+ type: 'run.warning';
192
+ at: number;
193
+ issue: Issue;
194
+ };
195
+ type RunErrorEvent = RunEventBase & {
196
+ type: 'run.error';
197
+ at: number;
198
+ issue: Issue;
199
+ /** When true, operation may continue and still complete successfully. */
200
+ recoverable: boolean;
201
+ };
202
+ type RunMessageLevel = 'detail' | 'info' | 'notice' | 'tip' | 'warn';
203
+ type RunMessageChannel = 'default' | 'cache' | 'verbose';
204
+ type RunMessageEvent = RunEventBase & {
205
+ type: 'run.message';
206
+ at: number;
207
+ level: RunMessageLevel;
208
+ channel?: RunMessageChannel;
209
+ message: string;
210
+ target?: string;
211
+ path?: string;
212
+ data?: Record<string, string | number | boolean | null>;
213
+ };
214
+ type RunShareManifestEvent = RunEventBase & {
215
+ op: 'share';
216
+ type: 'run.share.manifest';
217
+ at: number;
218
+ manifest: ShareManifest;
219
+ };
220
+ type RunShareSkippedEvent = RunEventBase & {
221
+ op: 'share';
222
+ type: 'run.share.skipped';
223
+ at: number;
224
+ reason: string;
225
+ links: ShareLinks;
226
+ workerIds: {
227
+ projectId?: string;
228
+ reportId?: string;
229
+ };
230
+ };
231
+ type RunShareUploadedEvent = RunEventBase & {
232
+ op: 'share';
233
+ type: 'run.share.uploaded';
234
+ at: number;
235
+ kind: 'project' | 'report';
236
+ workerProjectId?: string;
237
+ workerReportId?: string;
238
+ byteSize: number;
239
+ };
240
+ type RunShareLinksEvent = RunEventBase & {
241
+ op: 'share';
242
+ type: 'run.share.links';
243
+ at: number;
244
+ links: ShareLinks;
245
+ };
246
+ type ProgressEvent<T extends OperationId> = RunEventBase & {
247
+ type: `run.progress.${T}`;
248
+ at: number;
249
+ current?: number;
250
+ total?: number;
251
+ label?: string;
252
+ };
253
+ /** Not all operations emit progress events; only ones with meaningful streaming progress should. */
254
+ type GeneratePhase = 'scan_dynamic_sites' | 'read_source' | 'resolve_targets' | 'build_target' | 'translate' | 'write_files' | 'done';
255
+ type SyncPhase = 'scan_dynamic_sites' | 'read_source' | 'resolve_targets' | 'build_target' | 'merge' | 'prune' | 'write_files' | 'done';
256
+ type ValidatePhase = 'scan_sources' | 'extract_keys' | 'read_source' | 'compare' | 'done';
257
+ /** Per-operation progress payloads. */
258
+ type GenerateProgressEvent = ProgressEvent<'generate'> & {
259
+ target?: string;
260
+ phase: GeneratePhase;
261
+ /** Active translation backend — **non-secret** (for logs / `--json` consumers). */
262
+ providerId?: TranslationProviderId;
263
+ /** e.g. LLM model id when using an AI provider — **never** API keys or tokens. */
264
+ translationModel?: string;
265
+ };
266
+ type SyncProgressEvent = ProgressEvent<'sync'> & {
267
+ target?: string;
268
+ phase: SyncPhase;
269
+ };
270
+ type ValidateProgressEvent = ProgressEvent<'validate'> & {
271
+ phase: ValidatePhase;
272
+ };
273
+ type RunSummaryEventFor<T extends OperationId> = Omit<RunEventBase, 'op'> & {
274
+ op: T;
275
+ type: 'run.summary';
276
+ at: number;
277
+ ok: boolean;
278
+ issueCount: number;
279
+ counts: RunCountsByOperation[T];
280
+ };
281
+ type RunSummaryEvent = {
282
+ [K in OperationId]: RunSummaryEventFor<K>;
283
+ }[OperationId];
284
+ type RunEvent = RunStartedEvent | RunWarningEvent | RunErrorEvent | RunMessageEvent | RunFailedEvent | RunCompletedEvent | RunSummaryEvent | GenerateProgressEvent | SyncProgressEvent | ValidateProgressEvent | RunShareManifestEvent | RunShareSkippedEvent | RunShareUploadedEvent | RunShareLinksEvent;
285
+ type RunEmitter = (event: RunEvent) => void;
286
+
287
+ export type { RunStartedEvent as A, RunSummaryEvent as B, CleanupCounts as C, DoctorCounts as D, RunWarningEvent as E, ShareCounts as F, GenerateCounts as G, ShareJsonHealKind as H, SyncCounts as I, SyncPhase as J, ValidatePhase as K, LoadShareJsonResult as L, MissingCounts as M, ValidateProgressEvent as N, OperationId as O, ProgressEvent as P, QualityCounts as Q, RunEmitter as R, SyncProgressEvent as S, ValidateCounts as V, WorkerShareEnvelope as W, RunEvent as a, ShareProjectManifest as b, ShareReportManifest as c, ShareKind as d, ShareCacheEntry as e, ShareManifest as f, ShareLinks as g, ShareJsonFile as h, ShareJsonHealReport as i, GeneratePhase as j, GenerateProgressEvent as k, LocalesDynamicCounts as l, ReportCounts as m, ReviewCounts as n, RunCompletedEvent as o, RunCountsByOperation as p, RunErrorEvent as q, RunEventBase as r, RunFailedEvent as s, RunMessageChannel as t, RunMessageEvent as u, RunMessageLevel as v, RunShareLinksEvent as w, RunShareManifestEvent as x, RunShareSkippedEvent as y, RunShareUploadedEvent as z };
@@ -0,0 +1,124 @@
1
+ import { I as Issue } from './index-X50E1FIX.js';
2
+ import { R as RunEmitter } from './index-BgG01AKL.js';
3
+
4
+ type MissingTargetKind = 'source' | 'locale';
5
+ /**
6
+ * Payload shape for `i18nprune missing --json`.
7
+ * Additive fields may appear in future versions.
8
+ */
9
+ type MissingJsonOutput = {
10
+ kind: 'missing';
11
+ targetPath: string;
12
+ targetPaths?: string[];
13
+ targetKind: MissingTargetKind;
14
+ pathsAdded: number;
15
+ shown: number;
16
+ top: number | null;
17
+ full: boolean;
18
+ paths: string[];
19
+ dryRun: boolean;
20
+ skippedNotInScan: string[];
21
+ targets: MissingJsonTarget[];
22
+ skippedTargets: MissingSkippedTarget[];
23
+ placeholderLeaves: MissingPlaceholderLeafList;
24
+ };
25
+ type MissingRunOptions = {
26
+ /** Locale basename(s) under `localesDir`, or `all`; omit = source locale file. */
27
+ target?: string;
28
+ dryRun?: boolean;
29
+ /** Max placeholder leaves to include in JSON listings; default 10. Ignored when `full` is true. */
30
+ top?: number;
31
+ /** JSON listings include every placeholder leaf (overrides `top`). */
32
+ full?: boolean;
33
+ };
34
+ type MissingTargetState = {
35
+ targetPath: string;
36
+ targetKind: MissingTargetKind;
37
+ localeJson: unknown;
38
+ localeText: string;
39
+ selectedLocaleCode?: string;
40
+ selectedLocaleEnglishName?: string;
41
+ targetDisplayPath?: string;
42
+ };
43
+ type MissingSkippedTarget = {
44
+ localeCode: string;
45
+ targetPath: string;
46
+ reason: 'not_found' | 'source_locale';
47
+ suggestions?: string[];
48
+ };
49
+ type MissingSegmentWrite = {
50
+ targetPath: string;
51
+ relativePath: string;
52
+ paths: string[];
53
+ };
54
+ type MissingTargetPlan = {
55
+ target: MissingTargetState;
56
+ toAdd: string[];
57
+ skippedNotInScan: string[];
58
+ /** Per-segment file writes (multi-segment layouts). */
59
+ writePlan: MissingSegmentWrite[];
60
+ };
61
+ type MissingJsonTarget = {
62
+ targetPath: string;
63
+ targetPaths?: string[];
64
+ targetKind: MissingTargetKind;
65
+ selectedLocaleCode?: string;
66
+ pathsAdded: number;
67
+ paths: string[];
68
+ skippedNotInScan: string[];
69
+ };
70
+ type MissingPlaceholderLeaf = {
71
+ localeRole: MissingTargetKind;
72
+ localeCode: string;
73
+ file: string;
74
+ path: string;
75
+ value: string;
76
+ line: number | null;
77
+ location: string;
78
+ };
79
+ type MissingPlaceholderLeafList = {
80
+ count: number;
81
+ shown: number;
82
+ top: number | null;
83
+ full: boolean;
84
+ leaves: MissingPlaceholderLeaf[];
85
+ };
86
+ type MissingHostHooks = {
87
+ emit?: RunEmitter;
88
+ runId?: string;
89
+ };
90
+ type MissingRunResult = {
91
+ payload: MissingJsonOutput;
92
+ issues: Issue[];
93
+ targets: MissingTargetPlan[];
94
+ skippedTargets: MissingSkippedTarget[];
95
+ /** Aggregate across planned targets, preserved for simple callers. */
96
+ toAdd: string[];
97
+ skippedNotInScan: string[];
98
+ dynamicSites: number;
99
+ keyObservationsCount: number;
100
+ placeholderLeaves: MissingPlaceholderLeaf[];
101
+ };
102
+ type MissingWriteInput = {
103
+ targetPath: string;
104
+ localeJson: unknown;
105
+ localeCode?: string;
106
+ paths: readonly string[];
107
+ placeholder: string;
108
+ writePlan?: MissingSegmentWrite[];
109
+ };
110
+
111
+ type ResolveMissingPathsPlanInput = {
112
+ /** Target locale JSON object used to detect already-existing string leaves. */
113
+ localeJson?: unknown;
114
+ /** Merged leaves for multi-segment locales (preferred over `localeJson` when set). */
115
+ localeLeaves?: ReadonlyArray<{
116
+ path: string;
117
+ }>;
118
+ /** All resolved literal keys seen in the current project scan. */
119
+ resolvedKeys: ReadonlySet<string>;
120
+ /** Optional `missing` entries from a prior validate JSON report. */
121
+ reportMissingPaths?: readonly string[];
122
+ };
123
+
124
+ export type { MissingHostHooks as M, ResolveMissingPathsPlanInput as R, MissingPlaceholderLeaf as a, MissingTargetPlan as b, MissingRunOptions as c, MissingRunResult as d, MissingWriteInput as e, MissingSegmentWrite as f, MissingJsonOutput as g, MissingJsonTarget as h, MissingPlaceholderLeafList as i, MissingSkippedTarget as j, MissingTargetKind as k, MissingTargetState as l };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Rich observations for literal and template-resolved translation keys (keySites phase).
3
+ * Heuristic dynamic sites stay under `types/extractor/dynamic`.
4
+ */
5
+ /** Where an observation was found (merged scan may omit `filePath`). */
6
+ type SourceSpan = {
7
+ filePath?: string;
8
+ line: number;
9
+ column?: number;
10
+ functionName?: string;
11
+ /** True when the translation call spans multiple lines. */
12
+ isMultilineCall?: boolean;
13
+ /** UTF-16 offset of the translation call in the file (for comment filtering). */
14
+ charOffset?: number;
15
+ };
16
+ /** One step replacing `${identifier}` using `constMap` during template resolution. */
17
+ type ConstSubstitutionStep = {
18
+ identifier: string;
19
+ value: string;
20
+ };
21
+ /** Optional cross-link to a heuristic dynamic site (same file:line when matched). */
22
+ type DynamicKeyRef = {
23
+ filePath?: string;
24
+ line?: number;
25
+ };
26
+ type LiteralKeyObservation = {
27
+ kind: 'literal';
28
+ resolvedKey: string;
29
+ /** Inner string as matched, e.g. `a.b.c` */
30
+ raw: string;
31
+ span: SourceSpan;
32
+ dynamicRef?: DynamicKeyRef;
33
+ };
34
+ type TemplateResolvedKeyObservation = {
35
+ kind: 'template_resolved';
36
+ resolvedKey: string;
37
+ templateRaw: string;
38
+ substitutions: ConstSubstitutionStep[];
39
+ span: SourceSpan;
40
+ dynamicRef?: DynamicKeyRef;
41
+ };
42
+ type TemplatePartialKeyObservation = {
43
+ kind: 'template_partial';
44
+ templateRaw: string;
45
+ substitutions: ConstSubstitutionStep[];
46
+ /** `${name}` segments still unresolved after constMap */
47
+ unresolvedPlaceholders: string[];
48
+ span: SourceSpan;
49
+ dynamicRef?: DynamicKeyRef;
50
+ /**
51
+ * Longest static key path prefix before the first unresolvable `${…}` (see dynamic rebuild),
52
+ * when it contains a dot segment; used for uncertain-key protection.
53
+ */
54
+ uncertainPrefix?: string;
55
+ };
56
+ type KeyObservation = LiteralKeyObservation | TemplateResolvedKeyObservation | TemplatePartialKeyObservation;
57
+
58
+ export type { ConstSubstitutionStep as C, DynamicKeyRef as D, KeyObservation as K, LiteralKeyObservation as L, SourceSpan as S, TemplatePartialKeyObservation as T, TemplateResolvedKeyObservation as a };
@@ -0,0 +1,43 @@
1
+ type LocaleLeafMode = 'legacy_string' | 'structured';
2
+
3
+ type StructuredLocaleLeaf = {
4
+ value: string;
5
+ status?: string;
6
+ confidence?: number | null;
7
+ needsReview?: boolean;
8
+ needsTranslationAgain?: boolean;
9
+ source?: string;
10
+ };
11
+
12
+ type LocaleMetadataRepairReason = 'legacy_string_promoted' | 'non_object_replaced' | 'missing_value' | 'invalid_status' | 'invalid_confidence' | 'invalid_needs_review' | 'invalid_needs_translation_again' | 'invalid_source' | 'canonical_metadata_materialized';
13
+ type LocaleMetadataPathChange = {
14
+ path: string;
15
+ reason: LocaleMetadataRepairReason;
16
+ };
17
+ type LocaleLeafRuntimeKind = 'missing' | 'legacy_string' | 'structured_valid' | 'structured_corrupt' | 'other';
18
+ type LocaleLeafDecisionAction = 'unchanged' | 'hydrated_missing' | 'promoted_legacy' | 'repaired_corrupt' | 'stripped_structured';
19
+ type LocaleMetadataLeafDecision = {
20
+ path: string;
21
+ sourceValue: string;
22
+ beforeKind: LocaleLeafRuntimeKind;
23
+ afterKind: LocaleLeafRuntimeKind;
24
+ action: LocaleLeafDecisionAction;
25
+ reasons: LocaleMetadataRepairReason[];
26
+ beforeValue: unknown;
27
+ afterValue: unknown;
28
+ };
29
+ type LocaleMetadataReport = {
30
+ mode: LocaleLeafMode;
31
+ totalSourceLeafPaths: number;
32
+ unchangedLeaves: number;
33
+ structuredLeavesWritten: number;
34
+ promotedLegacyLeaves: number;
35
+ repairedCorruptLeaves: number;
36
+ strippedStructuredLeaves: number;
37
+ missingPathsHydratedFromSource: number;
38
+ byReason: Record<LocaleMetadataRepairReason, number>;
39
+ changedPathsSample: LocaleMetadataPathChange[];
40
+ leafDecisions: LocaleMetadataLeafDecision[];
41
+ };
42
+
43
+ export type { LocaleMetadataReport as L, StructuredLocaleLeaf as S, LocaleLeafMode as a, LocaleLeafDecisionAction as b, LocaleLeafRuntimeKind as c, LocaleMetadataLeafDecision as d, LocaleMetadataPathChange as e, LocaleMetadataRepairReason as f };