@smartcat/sanity-plugin 1.0.0 → 1.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 (121) hide show
  1. package/README.md +294 -0
  2. package/dist/_chunks-cjs/constants.cjs +13 -0
  3. package/dist/_chunks-cjs/constants.cjs.map +1 -0
  4. package/dist/_chunks-cjs/index.cjs +174 -0
  5. package/dist/_chunks-cjs/index.cjs.map +1 -0
  6. package/dist/_chunks-cjs/index2.cjs +338 -0
  7. package/dist/_chunks-cjs/index2.cjs.map +1 -0
  8. package/dist/_chunks-cjs/workflow.cjs +16 -0
  9. package/dist/_chunks-cjs/workflow.cjs.map +1 -0
  10. package/dist/_chunks-es/constants.js +14 -0
  11. package/dist/_chunks-es/constants.js.map +1 -0
  12. package/dist/_chunks-es/index.js +175 -0
  13. package/dist/_chunks-es/index.js.map +1 -0
  14. package/dist/_chunks-es/index2.js +340 -0
  15. package/dist/_chunks-es/index2.js.map +1 -0
  16. package/dist/_chunks-es/workflow.js +17 -0
  17. package/dist/_chunks-es/workflow.js.map +1 -0
  18. package/dist/export.cjs +160 -0
  19. package/dist/export.cjs.map +1 -0
  20. package/dist/export.d.cts +162 -0
  21. package/dist/export.d.ts +162 -0
  22. package/dist/export.js +162 -0
  23. package/dist/export.js.map +1 -0
  24. package/dist/import.cjs +169 -0
  25. package/dist/import.cjs.map +1 -0
  26. package/dist/import.d.cts +155 -0
  27. package/dist/import.d.ts +155 -0
  28. package/dist/import.js +169 -0
  29. package/dist/import.js.map +1 -0
  30. package/dist/index.cjs +2172 -0
  31. package/dist/index.cjs.map +1 -0
  32. package/dist/index.d.cts +122 -0
  33. package/dist/index.d.ts +122 -0
  34. package/dist/index.js +2179 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/locjson.cjs +12 -0
  37. package/dist/locjson.cjs.map +1 -0
  38. package/dist/locjson.d.cts +291 -0
  39. package/dist/locjson.d.ts +291 -0
  40. package/dist/locjson.js +12 -0
  41. package/dist/locjson.js.map +1 -0
  42. package/dist/progress.cjs +16 -0
  43. package/dist/progress.cjs.map +1 -0
  44. package/dist/progress.d.cts +277 -0
  45. package/dist/progress.d.ts +277 -0
  46. package/dist/progress.js +16 -0
  47. package/dist/progress.js.map +1 -0
  48. package/dist/smartcat.cjs +287 -0
  49. package/dist/smartcat.cjs.map +1 -0
  50. package/dist/smartcat.d.cts +234 -0
  51. package/dist/smartcat.d.ts +234 -0
  52. package/dist/smartcat.js +287 -0
  53. package/dist/smartcat.js.map +1 -0
  54. package/dist/templates.cjs +12 -0
  55. package/dist/templates.cjs.map +1 -0
  56. package/dist/templates.d.cts +52 -0
  57. package/dist/templates.d.ts +52 -0
  58. package/dist/templates.js +12 -0
  59. package/dist/templates.js.map +1 -0
  60. package/package.json +101 -15
  61. package/src/actions/AddToProjectAction.tsx +274 -0
  62. package/src/export/export.test.ts +537 -0
  63. package/src/export/index.ts +393 -0
  64. package/src/form/TranslationStatusInput.tsx +212 -0
  65. package/src/import/import.test.ts +346 -0
  66. package/src/import/index.ts +418 -0
  67. package/src/index.ts +63 -0
  68. package/src/lib/constants.ts +23 -0
  69. package/src/lib/documentTitle.test.ts +43 -0
  70. package/src/lib/documentTitle.ts +30 -0
  71. package/src/lib/languageMap.test.ts +56 -0
  72. package/src/lib/languageMap.ts +71 -0
  73. package/src/lib/linkedDocuments.test.ts +56 -0
  74. package/src/lib/linkedDocuments.ts +100 -0
  75. package/src/lib/locjson/deserialize.ts +60 -0
  76. package/src/lib/locjson/fields.ts +355 -0
  77. package/src/lib/locjson/filename.ts +34 -0
  78. package/src/lib/locjson/index.ts +10 -0
  79. package/src/lib/locjson/locjson.test.ts +615 -0
  80. package/src/lib/locjson/paths.test.ts +41 -0
  81. package/src/lib/locjson/paths.ts +73 -0
  82. package/src/lib/locjson/portableText.ts +157 -0
  83. package/src/lib/locjson/serialize.ts +124 -0
  84. package/src/lib/locjson/types.ts +106 -0
  85. package/src/lib/log.ts +33 -0
  86. package/src/lib/projectItems.ts +31 -0
  87. package/src/lib/resolveConfig.test.ts +62 -0
  88. package/src/lib/resolveConfig.ts +54 -0
  89. package/src/lib/workflow.test.ts +37 -0
  90. package/src/lib/workflow.ts +48 -0
  91. package/src/lib/zip.fixtures.ts +75 -0
  92. package/src/lib/zip.test.ts +110 -0
  93. package/src/lib/zip.ts +164 -0
  94. package/src/progress/core.ts +409 -0
  95. package/src/progress/index.ts +7 -0
  96. package/src/progress/progress.test.ts +290 -0
  97. package/src/schema/settings.ts +55 -0
  98. package/src/schema/translatableOptions.ts +25 -0
  99. package/src/schema/translationProject.ts +268 -0
  100. package/src/smartcat/client.test.ts +222 -0
  101. package/src/smartcat/client.ts +351 -0
  102. package/src/smartcat/index.ts +10 -0
  103. package/src/smartcat/types.ts +99 -0
  104. package/src/templates/core.ts +55 -0
  105. package/src/templates/index.ts +5 -0
  106. package/src/templates/templates.test.ts +50 -0
  107. package/src/tool/Dashboard.tsx +46 -0
  108. package/src/tool/ItemProgress.tsx +176 -0
  109. package/src/tool/LogPanel.tsx +207 -0
  110. package/src/tool/ProjectView.tsx +1004 -0
  111. package/src/tool/ProjectsView.tsx +208 -0
  112. package/src/tool/StatusBadge.tsx +33 -0
  113. package/src/tool/StudioInit.tsx +42 -0
  114. package/src/tool/WorkflowSelect.tsx +41 -0
  115. package/src/tool/data.ts +86 -0
  116. package/src/tool/index.ts +19 -0
  117. package/src/tool/processing.test.ts +698 -0
  118. package/src/tool/processing.ts +839 -0
  119. package/src/tool/useTemplates.ts +84 -0
  120. package/src/tool/useWorkflowSelection.ts +65 -0
  121. package/src/types.ts +77 -0
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Builds the full progress array from a freshly fetched Smartcat project and the
3
+ * project's items — independent of any export-time skeleton, so it works for
4
+ * projects exported before progress tracking existed.
5
+ *
6
+ * Documents are correlated to items by the 8-char id prefix in their filename;
7
+ * `imported` flags are carried over from the previous progress (by source doc +
8
+ * language) so importing isn't forgotten on refresh.
9
+ *
10
+ * `mappings` invert Smartcat's returned target codes back to Sanity ids, so all
11
+ * stored progress uses Sanity locale tags. When omitted, codes pass through
12
+ * unchanged (identity) — keeping legacy projects working.
13
+ */
14
+ export declare function buildProgress(
15
+ items: ProjectItem[],
16
+ scProject: SmartcatProject,
17
+ previous: DocProgress[] | undefined,
18
+ now: string,
19
+ mappings?: SmartcatLanguageMapping[],
20
+ ): DocProgress[];
21
+
22
+ /**
23
+ * Builds a stage-id → display-name map from a project's `workflowStages`. On
24
+ * Smartcat, document-level stages carry only `{id, progress}` — the human name
25
+ * (`stageType`, e.g. "translation") lives on the project-level stages.
26
+ */
27
+ export declare function buildStageNameMap(
28
+ scProject: SmartcatProject,
29
+ ): Map<string, string>;
30
+
31
+ export declare interface CompletionSummary {
32
+ /** Total (document × language) targets. */
33
+ total: number;
34
+ /** Targets whose stages are all at 100%. */
35
+ complete: number;
36
+ /** Targets a variant has been built for. */
37
+ imported: number;
38
+ /** True when every target is complete and imported (and there is ≥1 target). */
39
+ allDone: boolean;
40
+ /** True when at least one stage shows any progress. */
41
+ anyProgress: boolean;
42
+ }
43
+
44
+ export declare interface DocProgress {
45
+ _key: string;
46
+ sourceDocId: string;
47
+ title?: string;
48
+ targets: TargetProgress[];
49
+ }
50
+
51
+ /**
52
+ * Whether a target has any content confirmed at any stage — i.e. there is
53
+ * something worth importing. Used to gate `mode=confirmed` downloads so we skip
54
+ * targets with nothing confirmed yet (which would otherwise come back as source).
55
+ */
56
+ export declare function hasConfirmedContent(stages: StageProgress[]): boolean;
57
+
58
+ /** A target is complete when it has stages and every one is at 100%. */
59
+ export declare function isTargetComplete(stages: StageProgress[]): boolean;
60
+
61
+ /**
62
+ * Resolves a project's items into the lightweight shape we correlate on. The id
63
+ * is the item's stored `docId` — NOT a dereferenced document — so an item whose
64
+ * document exists only as a draft (never published) still correlates instead of
65
+ * being silently dropped. Tolerates the legacy `{doc}` projection.
66
+ */
67
+ export declare function itemsFromProject(project: {
68
+ items?: ProjectItemRef[];
69
+ }): ProjectItem[];
70
+
71
+ /** Sanitizes an arbitrary string into a stable, Sanity-safe array `_key`. */
72
+ export declare function keyify(value: string): string;
73
+
74
+ /** A project item we correlate Smartcat documents back to. */
75
+ export declare interface ProjectItem {
76
+ _id: string;
77
+ title?: string;
78
+ }
79
+
80
+ /** A project item as read for correlation: its stored id (always present) plus a
81
+ * best-effort title. `doc` is the legacy shape — some callers still project it. */
82
+ declare interface ProjectItemRef {
83
+ _id?: string;
84
+ title?: string;
85
+ doc?: {
86
+ _id?: string;
87
+ title?: string;
88
+ } | null;
89
+ }
90
+
91
+ /** Sink for per-request tracing; attach with `SmartcatClient.setRequestLogger`. */
92
+ declare type RequestLogger = (info: RequestLogInfo) => void;
93
+
94
+ /** One Smartcat HTTP call, reported to a {@link RequestLogger} for tracing. */
95
+ declare interface RequestLogInfo {
96
+ method: string;
97
+ /** Request path incl. query string (no host, no secrets). */
98
+ path: string;
99
+ status: number;
100
+ /** Raw response body text — carries Smartcat's error detail on failures. */
101
+ body: string;
102
+ }
103
+
104
+ /**
105
+ * Thin progress step run by the `smartcat-progress` Function: fetches the
106
+ * Smartcat project and mirrors its per-stage progress onto the project's
107
+ * `progress` array. Read-only with respect to Smartcat — it never downloads or
108
+ * creates variants, so it is cheap to run on every dashboard page load.
109
+ */
110
+ export declare function runProgressSync(
111
+ options: RunProgressSyncOptions,
112
+ ): Promise<RunProgressSyncResult>;
113
+
114
+ export declare interface RunProgressSyncOptions {
115
+ sanity: SanityLikeClient;
116
+ smartcat: SmartcatProgressClient;
117
+ /** `_id` of the `smartcat.translationProject` to refresh. */
118
+ projectId: string;
119
+ now?: () => string;
120
+ }
121
+
122
+ export declare interface RunProgressSyncResult {
123
+ summary: CompletionSummary;
124
+ /** Set when the Smartcat fetch failed (e.g. timed out); the run was recorded, not thrown. */
125
+ error?: string;
126
+ }
127
+
128
+ /** Minimal structural subset of @sanity/client used by the progress refresh. */
129
+ export declare interface SanityLikeClient {
130
+ fetch<T = unknown>(
131
+ query: string,
132
+ params?: Record<string, unknown>,
133
+ ): Promise<T>;
134
+ patch(id: string): {
135
+ set(attrs: Record<string, unknown>): {
136
+ commit(): Promise<unknown>;
137
+ };
138
+ };
139
+ }
140
+
141
+ /** A document within a Smartcat project (one per source file × target language). */
142
+ declare interface SmartcatDocument {
143
+ /** Target document id, formatted `<fileGuid>_<languageNumber>`. */
144
+ id: string;
145
+ name?: string;
146
+ fullPath?: string;
147
+ filename?: string;
148
+ /** Shared id of the uploaded source file (the `<fileGuid>` part of `id`). */
149
+ externalId?: string;
150
+ sourceLanguage?: string;
151
+ targetLanguage?: string;
152
+ /** Per-stage progress. On documents these carry only `{id, progress}`; the
153
+ * stage names live on the project-level `workflowStages` (keyed by `id`). */
154
+ workflowStages?: SmartcatWorkflowStage[];
155
+ }
156
+
157
+ /**
158
+ * Sanity ↔ Smartcat language-code mapping.
159
+ *
160
+ * Sanity locale tags (`id`) don't always match the codes Smartcat understands
161
+ * (e.g. Sanity "PL-PL" vs Smartcat "pl"). The browser resolves the mapping from
162
+ * plugin config and stamps the relevant pairs onto the project; the thin
163
+ * Functions read them back. This module is dependency-free so it bundles into
164
+ * both the Studio and the Functions.
165
+ *
166
+ * The invariant: everything stored in Sanity uses the Sanity `id`; only the
167
+ * Smartcat HTTP calls use `smartcatLanguage`. So callers map forward (id → code)
168
+ * when talking to Smartcat and invert (code → id) when storing what comes back.
169
+ */
170
+ declare interface SmartcatLanguageMapping {
171
+ sanityId: string;
172
+ smartcatLanguage: string;
173
+ }
174
+
175
+ /** Structural subset of SmartcatClient the progress refresh needs. */
176
+ export declare interface SmartcatProgressClient {
177
+ getProject(projectId: string): Promise<SmartcatProject>;
178
+ /** Optional: trace every HTTP call so a timeout/error reaches the functionLog. */
179
+ setRequestLogger?(logger: RequestLogger): void;
180
+ }
181
+
182
+ /** A Smartcat project as returned by the API. */
183
+ declare interface SmartcatProject {
184
+ id: string;
185
+ name?: string;
186
+ sourceLanguage?: string;
187
+ targetLanguages?: string[];
188
+ /** Project-level stages, where each `id` maps to a `stageType` (e.g. "translation"). */
189
+ workflowStages?: SmartcatWorkflowStage[];
190
+ documents?: SmartcatDocument[];
191
+ }
192
+
193
+ declare interface SmartcatWorkflowStage {
194
+ id?: string;
195
+ /** Stage type/name, e.g. "translation" / "editing" (casing varies by API). */
196
+ stageType?: string;
197
+ /** Human-readable stage name, when the API provides one. */
198
+ stageName?: string;
199
+ /** Completion percentage for this stage, 0–100. */
200
+ progress?: number;
201
+ /** Word counts, when present — useful for a weighted progress view. */
202
+ wordsTranslated?: number;
203
+ totalWordsCount?: number;
204
+ }
205
+
206
+ /**
207
+ * Extracts the 8-char source-id prefix Smartcat preserves in a document's
208
+ * filename (built as `<title>-<idPrefix>.locjson`, or `<title>-<idPrefix>-draft.locjson`
209
+ * when the content came from the document's draft). Used to correlate a Smartcat
210
+ * document back to a Sanity source document.
211
+ *
212
+ * A trailing `-draft` marker is stripped first, so a draft-sourced file resolves
213
+ * to the same id as its published counterpart. The prefix is then always the
214
+ * final 8 characters before the (marker and) extension, so take the tail rather
215
+ * than splitting on a dash — the title or the id prefix itself can
216
+ * contain dashes (e.g. a custom id like `demo-pdpA` → prefix `demo-pdp`), which
217
+ * would make a last-dash split return the wrong fragment.
218
+ *
219
+ * Only a literal `.locjson` extension is stripped (Smartcat's API often returns
220
+ * the name without it). A generic strip-after-last-dot would eat the tail of any
221
+ * DOTTED title — e.g. micro-copy keys like `aiAssistantModal.resetChat-11AKrV8G`
222
+ * — leaving the wrong 8 chars, so those documents silently never correlate,
223
+ * never import, and re-syncs duplicate them instead of updating.
224
+ */
225
+ export declare function sourceIdPrefix(doc: SmartcatDocument): string;
226
+
227
+ /**
228
+ * Per-document, per-language, per-stage translation progress mirrored from
229
+ * Smartcat onto a `smartcat.translationProject`.
230
+ *
231
+ * This module is intentionally **dependency-free** (no DOM, no @sanity/* runtime)
232
+ * so it bundles cleanly into the thin `smartcat-progress` / `smartcat-import`
233
+ * Functions. All keys are deterministic, so repeated refreshes patch the same
234
+ * array members in place instead of churning `_key`s.
235
+ */
236
+ export declare interface StageProgress {
237
+ /** Stable key for the Sanity array item (always set by `stagesFromDocument`). */
238
+ _key?: string;
239
+ name: string;
240
+ /** 0–100, rounded. */
241
+ percent: number;
242
+ }
243
+
244
+ /** Maps a Smartcat document's workflow stages to display-ready stage progress. */
245
+ export declare function stagesFromDocument(
246
+ doc: SmartcatDocument,
247
+ stageNames: Map<string, string>,
248
+ ): StageProgress[];
249
+
250
+ /** Summarizes a progress array for status decisions and the dashboard. */
251
+ export declare function summarizeCompletion(
252
+ progress: DocProgress[],
253
+ ): CompletionSummary;
254
+
255
+ /** Builds a progress target's `_key` from its document + language. */
256
+ export declare function targetKey(
257
+ sourceDocId: string,
258
+ language: string,
259
+ ): string;
260
+
261
+ /** Average completion across a target's stages (0–100). */
262
+ export declare function targetPercent(stages: StageProgress[]): number;
263
+
264
+ export declare interface TargetProgress {
265
+ _key: string;
266
+ language: string;
267
+ /** Smartcat target document id (`<fileGuid>_<languageNumber>`). */
268
+ smartcatDocumentId?: string;
269
+ stages: StageProgress[];
270
+ /** All stages at 100%. */
271
+ complete: boolean;
272
+ /** A locale variant has been built from this target (set by the browser). */
273
+ imported: boolean;
274
+ syncedAt?: string;
275
+ }
276
+
277
+ export {};
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Builds the full progress array from a freshly fetched Smartcat project and the
3
+ * project's items — independent of any export-time skeleton, so it works for
4
+ * projects exported before progress tracking existed.
5
+ *
6
+ * Documents are correlated to items by the 8-char id prefix in their filename;
7
+ * `imported` flags are carried over from the previous progress (by source doc +
8
+ * language) so importing isn't forgotten on refresh.
9
+ *
10
+ * `mappings` invert Smartcat's returned target codes back to Sanity ids, so all
11
+ * stored progress uses Sanity locale tags. When omitted, codes pass through
12
+ * unchanged (identity) — keeping legacy projects working.
13
+ */
14
+ export declare function buildProgress(
15
+ items: ProjectItem[],
16
+ scProject: SmartcatProject,
17
+ previous: DocProgress[] | undefined,
18
+ now: string,
19
+ mappings?: SmartcatLanguageMapping[],
20
+ ): DocProgress[];
21
+
22
+ /**
23
+ * Builds a stage-id → display-name map from a project's `workflowStages`. On
24
+ * Smartcat, document-level stages carry only `{id, progress}` — the human name
25
+ * (`stageType`, e.g. "translation") lives on the project-level stages.
26
+ */
27
+ export declare function buildStageNameMap(
28
+ scProject: SmartcatProject,
29
+ ): Map<string, string>;
30
+
31
+ export declare interface CompletionSummary {
32
+ /** Total (document × language) targets. */
33
+ total: number;
34
+ /** Targets whose stages are all at 100%. */
35
+ complete: number;
36
+ /** Targets a variant has been built for. */
37
+ imported: number;
38
+ /** True when every target is complete and imported (and there is ≥1 target). */
39
+ allDone: boolean;
40
+ /** True when at least one stage shows any progress. */
41
+ anyProgress: boolean;
42
+ }
43
+
44
+ export declare interface DocProgress {
45
+ _key: string;
46
+ sourceDocId: string;
47
+ title?: string;
48
+ targets: TargetProgress[];
49
+ }
50
+
51
+ /**
52
+ * Whether a target has any content confirmed at any stage — i.e. there is
53
+ * something worth importing. Used to gate `mode=confirmed` downloads so we skip
54
+ * targets with nothing confirmed yet (which would otherwise come back as source).
55
+ */
56
+ export declare function hasConfirmedContent(stages: StageProgress[]): boolean;
57
+
58
+ /** A target is complete when it has stages and every one is at 100%. */
59
+ export declare function isTargetComplete(stages: StageProgress[]): boolean;
60
+
61
+ /**
62
+ * Resolves a project's items into the lightweight shape we correlate on. The id
63
+ * is the item's stored `docId` — NOT a dereferenced document — so an item whose
64
+ * document exists only as a draft (never published) still correlates instead of
65
+ * being silently dropped. Tolerates the legacy `{doc}` projection.
66
+ */
67
+ export declare function itemsFromProject(project: {
68
+ items?: ProjectItemRef[];
69
+ }): ProjectItem[];
70
+
71
+ /** Sanitizes an arbitrary string into a stable, Sanity-safe array `_key`. */
72
+ export declare function keyify(value: string): string;
73
+
74
+ /** A project item we correlate Smartcat documents back to. */
75
+ export declare interface ProjectItem {
76
+ _id: string;
77
+ title?: string;
78
+ }
79
+
80
+ /** A project item as read for correlation: its stored id (always present) plus a
81
+ * best-effort title. `doc` is the legacy shape — some callers still project it. */
82
+ declare interface ProjectItemRef {
83
+ _id?: string;
84
+ title?: string;
85
+ doc?: {
86
+ _id?: string;
87
+ title?: string;
88
+ } | null;
89
+ }
90
+
91
+ /** Sink for per-request tracing; attach with `SmartcatClient.setRequestLogger`. */
92
+ declare type RequestLogger = (info: RequestLogInfo) => void;
93
+
94
+ /** One Smartcat HTTP call, reported to a {@link RequestLogger} for tracing. */
95
+ declare interface RequestLogInfo {
96
+ method: string;
97
+ /** Request path incl. query string (no host, no secrets). */
98
+ path: string;
99
+ status: number;
100
+ /** Raw response body text — carries Smartcat's error detail on failures. */
101
+ body: string;
102
+ }
103
+
104
+ /**
105
+ * Thin progress step run by the `smartcat-progress` Function: fetches the
106
+ * Smartcat project and mirrors its per-stage progress onto the project's
107
+ * `progress` array. Read-only with respect to Smartcat — it never downloads or
108
+ * creates variants, so it is cheap to run on every dashboard page load.
109
+ */
110
+ export declare function runProgressSync(
111
+ options: RunProgressSyncOptions,
112
+ ): Promise<RunProgressSyncResult>;
113
+
114
+ export declare interface RunProgressSyncOptions {
115
+ sanity: SanityLikeClient;
116
+ smartcat: SmartcatProgressClient;
117
+ /** `_id` of the `smartcat.translationProject` to refresh. */
118
+ projectId: string;
119
+ now?: () => string;
120
+ }
121
+
122
+ export declare interface RunProgressSyncResult {
123
+ summary: CompletionSummary;
124
+ /** Set when the Smartcat fetch failed (e.g. timed out); the run was recorded, not thrown. */
125
+ error?: string;
126
+ }
127
+
128
+ /** Minimal structural subset of @sanity/client used by the progress refresh. */
129
+ export declare interface SanityLikeClient {
130
+ fetch<T = unknown>(
131
+ query: string,
132
+ params?: Record<string, unknown>,
133
+ ): Promise<T>;
134
+ patch(id: string): {
135
+ set(attrs: Record<string, unknown>): {
136
+ commit(): Promise<unknown>;
137
+ };
138
+ };
139
+ }
140
+
141
+ /** A document within a Smartcat project (one per source file × target language). */
142
+ declare interface SmartcatDocument {
143
+ /** Target document id, formatted `<fileGuid>_<languageNumber>`. */
144
+ id: string;
145
+ name?: string;
146
+ fullPath?: string;
147
+ filename?: string;
148
+ /** Shared id of the uploaded source file (the `<fileGuid>` part of `id`). */
149
+ externalId?: string;
150
+ sourceLanguage?: string;
151
+ targetLanguage?: string;
152
+ /** Per-stage progress. On documents these carry only `{id, progress}`; the
153
+ * stage names live on the project-level `workflowStages` (keyed by `id`). */
154
+ workflowStages?: SmartcatWorkflowStage[];
155
+ }
156
+
157
+ /**
158
+ * Sanity ↔ Smartcat language-code mapping.
159
+ *
160
+ * Sanity locale tags (`id`) don't always match the codes Smartcat understands
161
+ * (e.g. Sanity "PL-PL" vs Smartcat "pl"). The browser resolves the mapping from
162
+ * plugin config and stamps the relevant pairs onto the project; the thin
163
+ * Functions read them back. This module is dependency-free so it bundles into
164
+ * both the Studio and the Functions.
165
+ *
166
+ * The invariant: everything stored in Sanity uses the Sanity `id`; only the
167
+ * Smartcat HTTP calls use `smartcatLanguage`. So callers map forward (id → code)
168
+ * when talking to Smartcat and invert (code → id) when storing what comes back.
169
+ */
170
+ declare interface SmartcatLanguageMapping {
171
+ sanityId: string;
172
+ smartcatLanguage: string;
173
+ }
174
+
175
+ /** Structural subset of SmartcatClient the progress refresh needs. */
176
+ export declare interface SmartcatProgressClient {
177
+ getProject(projectId: string): Promise<SmartcatProject>;
178
+ /** Optional: trace every HTTP call so a timeout/error reaches the functionLog. */
179
+ setRequestLogger?(logger: RequestLogger): void;
180
+ }
181
+
182
+ /** A Smartcat project as returned by the API. */
183
+ declare interface SmartcatProject {
184
+ id: string;
185
+ name?: string;
186
+ sourceLanguage?: string;
187
+ targetLanguages?: string[];
188
+ /** Project-level stages, where each `id` maps to a `stageType` (e.g. "translation"). */
189
+ workflowStages?: SmartcatWorkflowStage[];
190
+ documents?: SmartcatDocument[];
191
+ }
192
+
193
+ declare interface SmartcatWorkflowStage {
194
+ id?: string;
195
+ /** Stage type/name, e.g. "translation" / "editing" (casing varies by API). */
196
+ stageType?: string;
197
+ /** Human-readable stage name, when the API provides one. */
198
+ stageName?: string;
199
+ /** Completion percentage for this stage, 0–100. */
200
+ progress?: number;
201
+ /** Word counts, when present — useful for a weighted progress view. */
202
+ wordsTranslated?: number;
203
+ totalWordsCount?: number;
204
+ }
205
+
206
+ /**
207
+ * Extracts the 8-char source-id prefix Smartcat preserves in a document's
208
+ * filename (built as `<title>-<idPrefix>.locjson`, or `<title>-<idPrefix>-draft.locjson`
209
+ * when the content came from the document's draft). Used to correlate a Smartcat
210
+ * document back to a Sanity source document.
211
+ *
212
+ * A trailing `-draft` marker is stripped first, so a draft-sourced file resolves
213
+ * to the same id as its published counterpart. The prefix is then always the
214
+ * final 8 characters before the (marker and) extension, so take the tail rather
215
+ * than splitting on a dash — the title or the id prefix itself can
216
+ * contain dashes (e.g. a custom id like `demo-pdpA` → prefix `demo-pdp`), which
217
+ * would make a last-dash split return the wrong fragment.
218
+ *
219
+ * Only a literal `.locjson` extension is stripped (Smartcat's API often returns
220
+ * the name without it). A generic strip-after-last-dot would eat the tail of any
221
+ * DOTTED title — e.g. micro-copy keys like `aiAssistantModal.resetChat-11AKrV8G`
222
+ * — leaving the wrong 8 chars, so those documents silently never correlate,
223
+ * never import, and re-syncs duplicate them instead of updating.
224
+ */
225
+ export declare function sourceIdPrefix(doc: SmartcatDocument): string;
226
+
227
+ /**
228
+ * Per-document, per-language, per-stage translation progress mirrored from
229
+ * Smartcat onto a `smartcat.translationProject`.
230
+ *
231
+ * This module is intentionally **dependency-free** (no DOM, no @sanity/* runtime)
232
+ * so it bundles cleanly into the thin `smartcat-progress` / `smartcat-import`
233
+ * Functions. All keys are deterministic, so repeated refreshes patch the same
234
+ * array members in place instead of churning `_key`s.
235
+ */
236
+ export declare interface StageProgress {
237
+ /** Stable key for the Sanity array item (always set by `stagesFromDocument`). */
238
+ _key?: string;
239
+ name: string;
240
+ /** 0–100, rounded. */
241
+ percent: number;
242
+ }
243
+
244
+ /** Maps a Smartcat document's workflow stages to display-ready stage progress. */
245
+ export declare function stagesFromDocument(
246
+ doc: SmartcatDocument,
247
+ stageNames: Map<string, string>,
248
+ ): StageProgress[];
249
+
250
+ /** Summarizes a progress array for status decisions and the dashboard. */
251
+ export declare function summarizeCompletion(
252
+ progress: DocProgress[],
253
+ ): CompletionSummary;
254
+
255
+ /** Builds a progress target's `_key` from its document + language. */
256
+ export declare function targetKey(
257
+ sourceDocId: string,
258
+ language: string,
259
+ ): string;
260
+
261
+ /** Average completion across a target's stages (0–100). */
262
+ export declare function targetPercent(stages: StageProgress[]): number;
263
+
264
+ export declare interface TargetProgress {
265
+ _key: string;
266
+ language: string;
267
+ /** Smartcat target document id (`<fileGuid>_<languageNumber>`). */
268
+ smartcatDocumentId?: string;
269
+ stages: StageProgress[];
270
+ /** All stages at 100%. */
271
+ complete: boolean;
272
+ /** A locale variant has been built from this target (set by the browser). */
273
+ imported: boolean;
274
+ syncedAt?: string;
275
+ }
276
+
277
+ export {};
@@ -0,0 +1,16 @@
1
+ import { buildProgress, buildStageNameMap, hasConfirmedContent, isTargetComplete, itemsFromProject, keyify, runProgressSync, sourceIdPrefix, stagesFromDocument, summarizeCompletion, targetKey, targetPercent } from "./_chunks-es/index.js";
2
+ export {
3
+ buildProgress,
4
+ buildStageNameMap,
5
+ hasConfirmedContent,
6
+ isTargetComplete,
7
+ itemsFromProject,
8
+ keyify,
9
+ runProgressSync,
10
+ sourceIdPrefix,
11
+ stagesFromDocument,
12
+ summarizeCompletion,
13
+ targetKey,
14
+ targetPercent
15
+ };
16
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}