@verbatra/sdk 0.12.0 → 0.13.1
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 +6 -5
- package/dist/index.cjs +4567 -440
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1554 -34
- package/dist/index.d.ts +1554 -34
- package/dist/index.js +4552 -450
- package/dist/index.js.map +1 -1
- package/dist/schemas/check-file-summary.json +16 -0
- package/dist/schemas/check-summary.json +16 -0
- package/dist/schemas/data-flow-manifest.json +1 -0
- package/dist/schemas/doctor-result.json +1 -0
- package/dist/schemas/export-workbook-result.json +16 -0
- package/dist/schemas/run-history-result.json +346 -0
- package/dist/schemas/run-summary.json +1 -0
- package/package.json +15 -14
package/dist/index.d.ts
CHANGED
|
@@ -1521,6 +1521,16 @@ interface FlatFileAdapterOptions {
|
|
|
1521
1521
|
*/
|
|
1522
1522
|
declare function createFlatFileAdapter(options: FlatFileAdapterOptions): FormatAdapter;
|
|
1523
1523
|
|
|
1524
|
+
/** Which part of a rendered message a segment came from. */
|
|
1525
|
+
type IcuSegmentKind = "text" | "argument" | "tag";
|
|
1526
|
+
/** One run of a rendered message. `text` is always plain text, never markup to interpret. */
|
|
1527
|
+
interface IcuSegment {
|
|
1528
|
+
/** Literal message text, a substituted or formatted argument, or a tag boundary. */
|
|
1529
|
+
readonly kind: IcuSegmentKind;
|
|
1530
|
+
/** The text of this run. */
|
|
1531
|
+
readonly text: string;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1524
1534
|
/**
|
|
1525
1535
|
* Derives the per-entry facts a format decides for itself from one key and its string value: the
|
|
1526
1536
|
* placeholder tokens the value carries, and whether the key is one plural form of a set.
|
|
@@ -1646,6 +1656,11 @@ type BoundedFileRead = {
|
|
|
1646
1656
|
* a file the process may not open or a directory. Absent when nothing exists at the path.
|
|
1647
1657
|
*/
|
|
1648
1658
|
readonly unreadable?: boolean;
|
|
1659
|
+
/**
|
|
1660
|
+
* `true` together with `unreadable` when what exists at the path is not a regular file, such
|
|
1661
|
+
* as a directory. Absent when the process was refused access to a file.
|
|
1662
|
+
*/
|
|
1663
|
+
readonly notRegularFile?: boolean;
|
|
1649
1664
|
} | {
|
|
1650
1665
|
/** The file exists but exceeds the requested byte limit, so nothing was read. */
|
|
1651
1666
|
readonly kind: "too-large";
|
|
@@ -1667,6 +1682,11 @@ type BoundedBytesRead = {
|
|
|
1667
1682
|
* a file the process may not open or a directory. Absent when nothing exists at the path.
|
|
1668
1683
|
*/
|
|
1669
1684
|
readonly unreadable?: boolean;
|
|
1685
|
+
/**
|
|
1686
|
+
* `true` together with `unreadable` when what exists at the path is not a regular file, such
|
|
1687
|
+
* as a directory. Absent when the process was refused access to a file.
|
|
1688
|
+
*/
|
|
1689
|
+
readonly notRegularFile?: boolean;
|
|
1670
1690
|
} | {
|
|
1671
1691
|
/** The file exists but exceeds the requested byte limit, so nothing was read. */
|
|
1672
1692
|
readonly kind: "too-large";
|
|
@@ -1688,9 +1708,10 @@ interface DirectoryEntry {
|
|
|
1688
1708
|
* embedding application can back part of a project with something other than a local disk.
|
|
1689
1709
|
*
|
|
1690
1710
|
* The seam carries every file the SDK touches once a config is loaded: the run-status file, the
|
|
1691
|
-
* lock-file and the write locks, the translation-memory cache, the config
|
|
1692
|
-
* I/O, generated declaration and pseudolocale files, the source scan,
|
|
1693
|
-
* themselves, which the adapters read and write through a port built from this
|
|
1711
|
+
* run-history file, the lock-file and the write locks, the translation-memory cache, the config
|
|
1712
|
+
* glossary, workbook and TMX I/O, generated declaration and pseudolocale files, the source scan,
|
|
1713
|
+
* and the locale files themselves, which the adapters read and write through a port built from this
|
|
1714
|
+
* one. Two exceptions
|
|
1694
1715
|
* remain. {@link loadConfig} finds and loads the config file itself directly from disk; only its
|
|
1695
1716
|
* glossary goes through the port. And a caller-supplied `deps.adapterRegistry` holds adapters the
|
|
1696
1717
|
* caller constructed, so their file access is whatever the caller wired into them, and supplying
|
|
@@ -2425,7 +2446,7 @@ declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
|
2425
2446
|
* lock file's path. Thrown by
|
|
2426
2447
|
* {@link editEntry}, {@link retranslateEntry}, {@link approveEntry}, {@link rejectEntry}, and
|
|
2427
2448
|
* {@link approveLocale}, which act on one locale, and by {@link updateGlossaryTerm}, which takes the project's glossary
|
|
2428
|
-
* lock. {@link translate} and {@link importWorkbook} do not throw it: they record it on the
|
|
2449
|
+
* lock, and {@link setKeyLengthLimit}, which takes the project's limits lock. {@link translate} and {@link importWorkbook} do not throw it: they record it on the
|
|
2429
2450
|
* contended locale's {@link LocaleSummary} and carry on with the other locales. For
|
|
2430
2451
|
* {@link translate}, {@link watch}, and {@link importWorkbook}, `lockAcquireTimeoutMs` bounds
|
|
2431
2452
|
* only the locale write lock taken before any provider call or file write, so a locale that fails
|
|
@@ -2439,6 +2460,21 @@ declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
|
2439
2460
|
* read-only, has been removed, or the disk is out of space, or the project's glossary write lock
|
|
2440
2461
|
* could not be created, for instance in a read-only project. The file-system error is the
|
|
2441
2462
|
* `cause`. Thrown by {@link updateGlossaryTerm}.
|
|
2463
|
+
* - `LENGTH_LIMIT_INVALID`: {@link setKeyLengthLimit} refused its input: the `maxLength` is not a
|
|
2464
|
+
* whole number from 1 to `Number.MAX_SAFE_INTEGER` (or `null`), the key is empty or longer than
|
|
2465
|
+
* 1024 characters, the limit is a number and the config's own `maxLength` already sets the key,
|
|
2466
|
+
* so the limits file cannot override it, or the write would take the file past 10,000 entries or
|
|
2467
|
+
* 1 MiB. Nothing is written.
|
|
2468
|
+
* - `LIMITS_FILE_UNUSABLE`: `verbatra.limits.json` cannot be used: it is not a
|
|
2469
|
+
* regular file, is over 1 MiB, is not UTF-8 or JSON, has another shape or a newer version, or holds more than 10,000
|
|
2470
|
+
* entries. A file that cannot be used is never overwritten. Thrown by
|
|
2471
|
+
* {@link setKeyLengthLimit}. A run that meets such a file does not throw: it returns a
|
|
2472
|
+
* `LIMITS_FILE_IGNORED` notice.
|
|
2473
|
+
* - `LIMITS_FILE_UNWRITABLE`: the limits file exists but the process may not read it, or it or the
|
|
2474
|
+
* project's limits write lock could not be written, for instance in a read-only project, or the
|
|
2475
|
+
* lock could not be released after the limit was saved, which the message says. A write failure
|
|
2476
|
+
* carries the file-system error as its `cause`; a refused read does not. Thrown by
|
|
2477
|
+
* {@link setKeyLengthLimit}.
|
|
2442
2478
|
* - `LOCALE_LAYOUT_INVALID`: the configured `files.pattern` and `files.localeStyle` cannot be
|
|
2443
2479
|
* combined, or the style has no valid path spelling for a configured locale. Thrown by
|
|
2444
2480
|
* {@link createLocalePathResolver}, and so by every entry point that maps a locale to a path,
|
|
@@ -2460,8 +2496,8 @@ declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
|
2460
2496
|
* - `LOCK_TIMEOUT_INVALID`: the `lockAcquireTimeoutMs` input is not a whole number of
|
|
2461
2497
|
* milliseconds of at least 0. Thrown by {@link translate}, {@link importWorkbook},
|
|
2462
2498
|
* {@link retranslateEntry}, {@link retranslateEntries}, {@link editEntry}, {@link approveEntry},
|
|
2463
|
-
* {@link rejectEntry}, {@link approveEntries}, {@link rejectEntries}, {@link approveLocale},
|
|
2464
|
-
* {@link updateGlossaryTerm} before anything is read or locked, and
|
|
2499
|
+
* {@link rejectEntry}, {@link approveEntries}, {@link rejectEntries}, {@link approveLocale},
|
|
2500
|
+
* {@link updateGlossaryTerm}, and {@link setKeyLengthLimit} before anything is read or locked, and
|
|
2465
2501
|
* by {@link watch} once at startup, before any watching begins.
|
|
2466
2502
|
* - `PAGE_CURSOR_INVALID`: the `cursor` passed to {@link localeValuesPage} or
|
|
2467
2503
|
* {@link provenanceReportPage} is malformed, longer than {@link PAGE_CURSOR_MAX_LENGTH}, was made
|
|
@@ -2469,6 +2505,9 @@ declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
|
2469
2505
|
* changed between pages. Call again without a cursor.
|
|
2470
2506
|
* - `PAGE_LIMIT_INVALID`: the `limit` passed to {@link localeValuesPage} or
|
|
2471
2507
|
* {@link provenanceReportPage} is not a whole number from 1 to {@link PAGE_LIMIT_CAP}.
|
|
2508
|
+
* - `FIND_TEXT_INVALID`: the `find` text passed to {@link previewValueReplace} or
|
|
2509
|
+
* {@link applyValueReplace} is empty or longer than 20,000 characters, or that `find` or the
|
|
2510
|
+
* `replace` text holds an unpaired surrogate. Thrown before anything is read.
|
|
2472
2511
|
* - `TARGET_UNWRITABLE`: a target locale file could not be written, because its directory is not
|
|
2473
2512
|
* writable, does not exist, is read-only, or is out of space. The message names the target file
|
|
2474
2513
|
* relative to `cwd` and the underlying file-system code, never the internal temporary file the
|
|
@@ -2565,7 +2604,7 @@ declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
|
2565
2604
|
* - `LOCALE_FAILED`: never thrown. It is the fallback code recorded on a failed
|
|
2566
2605
|
* {@link LocaleSummary} when a per-locale failure carries no code of its own.
|
|
2567
2606
|
*/
|
|
2568
|
-
type SdkErrorCode = "CONFIG_NOT_FOUND" | "CONFIG_INVALID" | "UNKNOWN_FORMAT" | "UNKNOWN_LOCALE" | "UNKNOWN_KEY" | "KEY_PROTECTED" | "KEY_PINNED" | "PROVIDER_CONSTRUCTION_FAILED" | "MACHINE_TRANSLATION_DISABLED" | "NETWORK_POLICY_VIOLATION" | "SOURCE_UNREADABLE" | "SOURCE_INVALID" | "LOCK_FILE_INVALID" | "PROVENANCE_FILE_INVALID" | "PROVENANCE_FILE_UNWRITABLE" | "REVIEW_VALUE_CHANGED" | "REVIEW_SOURCE_CHANGED" | "REVIEW_REJECT_UNSUPPORTED" | "REVIEW_RESTORE_FAILED" | "REVIEWER_INVALID" | "LOCK_CONTENDED" | "GLOSSARY_NOT_FILE_BACKED" | "GLOSSARY_UNWRITABLE" | "LOCALE_LAYOUT_INVALID" | "LOCALE_PATH_COLLISION" | "CONCURRENCY_INVALID" | "CONCURRENCY_BUDGET_CONFLICT" | "MAX_TOKENS_INVALID" | "LOCK_TIMEOUT_INVALID" | "PAGE_CURSOR_INVALID" | "PAGE_LIMIT_INVALID" | "TARGET_UNWRITABLE" | "PSEUDO_OUTPUT_CONFLICT" | "SOURCE_UNWRITABLE" | "EXTRACT_NOT_CONFIGURED" | "EXTRACT_FS_UNSUPPORTED" | "TYPES_OUTPUT_CONFLICT" | "TYPES_UNWRITABLE" | "TMX_OUTPUT_CONFLICT" | "TMX_UNWRITABLE" | "MEMORY_UNWRITABLE" | "EXPORT_OUTPUT_CONFLICT" | "EXPORT_UNWRITABLE" | "LOCALE_STATE_NOT_CARRIED_OVER" | "LOCALE_UNSUPPORTED_BY_PROVIDER" | "NOT_A_LOCALE_FILE" | "SENSITIVE_CONTENT_WITHHELD" | "RUN_CANCELLED" | "LOCALE_FAILED";
|
|
2607
|
+
type SdkErrorCode = "CONFIG_NOT_FOUND" | "CONFIG_INVALID" | "UNKNOWN_FORMAT" | "UNKNOWN_LOCALE" | "UNKNOWN_KEY" | "KEY_PROTECTED" | "KEY_PINNED" | "PROVIDER_CONSTRUCTION_FAILED" | "MACHINE_TRANSLATION_DISABLED" | "NETWORK_POLICY_VIOLATION" | "SOURCE_UNREADABLE" | "SOURCE_INVALID" | "LOCK_FILE_INVALID" | "PROVENANCE_FILE_INVALID" | "PROVENANCE_FILE_UNWRITABLE" | "REVIEW_VALUE_CHANGED" | "REVIEW_SOURCE_CHANGED" | "REVIEW_REJECT_UNSUPPORTED" | "REVIEW_RESTORE_FAILED" | "REVIEWER_INVALID" | "LOCK_CONTENDED" | "GLOSSARY_NOT_FILE_BACKED" | "GLOSSARY_UNWRITABLE" | "LENGTH_LIMIT_INVALID" | "LIMITS_FILE_UNUSABLE" | "LIMITS_FILE_UNWRITABLE" | "LOCALE_LAYOUT_INVALID" | "LOCALE_PATH_COLLISION" | "CONCURRENCY_INVALID" | "CONCURRENCY_BUDGET_CONFLICT" | "MAX_TOKENS_INVALID" | "LOCK_TIMEOUT_INVALID" | "PAGE_CURSOR_INVALID" | "PAGE_LIMIT_INVALID" | "FIND_TEXT_INVALID" | "TARGET_UNWRITABLE" | "PSEUDO_OUTPUT_CONFLICT" | "SOURCE_UNWRITABLE" | "EXTRACT_NOT_CONFIGURED" | "EXTRACT_FS_UNSUPPORTED" | "TYPES_OUTPUT_CONFLICT" | "TYPES_UNWRITABLE" | "TMX_OUTPUT_CONFLICT" | "TMX_UNWRITABLE" | "MEMORY_UNWRITABLE" | "EXPORT_OUTPUT_CONFLICT" | "EXPORT_UNWRITABLE" | "LOCALE_STATE_NOT_CARRIED_OVER" | "LOCALE_UNSUPPORTED_BY_PROVIDER" | "NOT_A_LOCALE_FILE" | "SENSITIVE_CONTENT_WITHHELD" | "RUN_CANCELLED" | "LOCALE_FAILED";
|
|
2569
2608
|
/**
|
|
2570
2609
|
* The single structured error the SDK throws. Every whole-run failure surfaces as an `SdkError`
|
|
2571
2610
|
* carrying a stable {@link SdkErrorCode}, except the few a flow's `@throws` names otherwise (a
|
|
@@ -2585,7 +2624,7 @@ declare class SdkError extends Error {
|
|
|
2585
2624
|
* error for a `SOURCE_INVALID` TMX file. Read that file's line, column and unit with
|
|
2586
2625
|
* `tmxErrorLocation` rather than from the cause directly. Only `SOURCE_INVALID`,
|
|
2587
2626
|
* `PROVIDER_CONSTRUCTION_FAILED`, `EXPORT_UNWRITABLE`, `GLOSSARY_UNWRITABLE`,
|
|
2588
|
-
* `REVIEW_RESTORE_FAILED`, `SOURCE_UNWRITABLE` and `LOCK_CONTENDED` carry one, and `CONFIG_INVALID` only when the
|
|
2627
|
+
* `LIMITS_FILE_UNWRITABLE`, `REVIEW_RESTORE_FAILED`, `SOURCE_UNWRITABLE` and `LOCK_CONTENDED` carry one, and `CONFIG_INVALID` only when the
|
|
2589
2628
|
* config file failed to load with a coded error, such as an import that does not resolve. A
|
|
2590
2629
|
* config parse or schema error and `CONFIG_NOT_FOUND` carry none, because a config parser's error
|
|
2591
2630
|
* can quote the file's content.
|
|
@@ -3522,6 +3561,9 @@ interface RateCard {
|
|
|
3522
3561
|
table: Record<string, ModelRate>;
|
|
3523
3562
|
}
|
|
3524
3563
|
|
|
3564
|
+
/** Where a key's `maxLength` budget comes from: the config's own `maxLength`, or `verbatra.limits.json`. The config wins per key. */
|
|
3565
|
+
type MaxLengthSource = "config" | "limits-file";
|
|
3566
|
+
|
|
3525
3567
|
/** The locale spellings {@link LocaleStyle} is drawn from, in declaration order. */
|
|
3526
3568
|
declare const LOCALE_STYLES: readonly ["literal", "posix", "android"];
|
|
3527
3569
|
/**
|
|
@@ -4121,6 +4163,10 @@ type IntegrityGateReason = (typeof INTEGRITY_GATE_REASONS)[number];
|
|
|
4121
4163
|
* - `PROVENANCE_FILE_TOO_LARGE`: recording this locale's provenance would have grown the provenance
|
|
4122
4164
|
* file past the size verbatra reads back, so the file was left as it was and the values the
|
|
4123
4165
|
* locale wrote have no record.
|
|
4166
|
+
* - `LIMITS_FILE_IGNORED`: `verbatra.limits.json` could not be used, so this run held the keys to
|
|
4167
|
+
* the config's `maxLength` budgets only and flagged no value against a limit the file sets. The
|
|
4168
|
+
* message names the reason. Nothing is written and the file is left as it is. Reported by
|
|
4169
|
+
* {@link translate} and {@link watch}, dry runs too.
|
|
4124
4170
|
* - `LOCALE_STATE_CARRIED_OVER`: the lock file, translation memory, or provenance file held no state
|
|
4125
4171
|
* for this locale but held state under exactly one underscore spelling of it, such as `pt_BR` for
|
|
4126
4172
|
* `pt-BR`, left behind when the configured code was respelled. {@link translate} and
|
|
@@ -4186,7 +4232,7 @@ type IntegrityGateReason = (typeof INTEGRITY_GATE_REASONS)[number];
|
|
|
4186
4232
|
* and `FORMALITY_UNSUPPORTED_BY_PROVIDER` are raised before anything is spent, from the same
|
|
4187
4233
|
* assessment {@link doctor} reports under its `locales` check, and on a dry run too.
|
|
4188
4234
|
*/
|
|
4189
|
-
type SdkNoticeCode = "PLURAL_CATEGORIES_INCOMPLETE" | "SUB_BATCH_FAILED" | "BLANK_ROW_BASELINE_RETAINED" | "HANDOFF_REVIEWS_RECORDED" | "BUDGET_TOKENS_EXCEEDED" | "CACHE_VERSION_UNRECOGNIZED" | "PROVENANCE_VERSION_UNRECOGNIZED" | "PROVENANCE_FILE_TOO_LARGE" | "LOCALE_STATE_CARRIED_OVER" | "LOCALE_STATE_CARRY_OVER_SKIPPED" | "LOCALE_UNVERIFIED_BY_PROVIDER" | "LOCALE_NOT_WELL_TESTED" | "GLOSSARY_UNSUPPORTED_BY_PROVIDER" | "FORMALITY_UNSUPPORTED_BY_PROVIDER" | "SOURCE_FOREIGN_PLACEHOLDERS" | "SOURCE_VALUE_EMPTY" | "SENSITIVE_CONTENT_SENT" | "SENSITIVE_CONTENT_REDACTED" | "SENSITIVE_CONTENT_WITHHELD" | "RUN_CANCELLED";
|
|
4235
|
+
type SdkNoticeCode = "PLURAL_CATEGORIES_INCOMPLETE" | "SUB_BATCH_FAILED" | "BLANK_ROW_BASELINE_RETAINED" | "HANDOFF_REVIEWS_RECORDED" | "BUDGET_TOKENS_EXCEEDED" | "CACHE_VERSION_UNRECOGNIZED" | "PROVENANCE_VERSION_UNRECOGNIZED" | "PROVENANCE_FILE_TOO_LARGE" | "LIMITS_FILE_IGNORED" | "LOCALE_STATE_CARRIED_OVER" | "LOCALE_STATE_CARRY_OVER_SKIPPED" | "LOCALE_UNVERIFIED_BY_PROVIDER" | "LOCALE_NOT_WELL_TESTED" | "GLOSSARY_UNSUPPORTED_BY_PROVIDER" | "FORMALITY_UNSUPPORTED_BY_PROVIDER" | "SOURCE_FOREIGN_PLACEHOLDERS" | "SOURCE_VALUE_EMPTY" | "SENSITIVE_CONTENT_SENT" | "SENSITIVE_CONTENT_REDACTED" | "SENSITIVE_CONTENT_WITHHELD" | "RUN_CANCELLED";
|
|
4190
4236
|
/**
|
|
4191
4237
|
* Token usage as reported by the provider. Absent when the provider does not report usage, which is
|
|
4192
4238
|
* the case for machine-translation APIs such as DeepL that do not bill in tokens.
|
|
@@ -4783,6 +4829,260 @@ interface RunSummary {
|
|
|
4783
4829
|
readonly cancelled?: true;
|
|
4784
4830
|
}
|
|
4785
4831
|
|
|
4832
|
+
declare const RUN_HISTORY_TRIGGERS: readonly ["translate", "retranslate"];
|
|
4833
|
+
/**
|
|
4834
|
+
* What produced a {@link RunHistoryRecord}: `translate` for a {@link translate} run (which is also
|
|
4835
|
+
* what {@link watch}, the Studio translate-pending action and the `translation.translatePending`
|
|
4836
|
+
* MCP tool run), `retranslate` for one {@link retranslateEntry} call or one
|
|
4837
|
+
* {@link retranslateEntries} batch.
|
|
4838
|
+
*/
|
|
4839
|
+
type RunHistoryTrigger = (typeof RUN_HISTORY_TRIGGERS)[number];
|
|
4840
|
+
/** Every {@link RunCostBasis}. */
|
|
4841
|
+
declare const RUN_COST_BASES: readonly ["usage", "source-characters"];
|
|
4842
|
+
/**
|
|
4843
|
+
* Where a run's cost figure comes from: `usage` is the token usage the provider reported, priced at
|
|
4844
|
+
* the rate on file; `source-characters` is an estimate for a machine-translation provider that
|
|
4845
|
+
* reports no usage, the source characters of the keys sent to it, priced at the rate on file.
|
|
4846
|
+
*/
|
|
4847
|
+
type RunCostBasis = (typeof RUN_COST_BASES)[number];
|
|
4848
|
+
declare const RUN_COST_CAVEATS: readonly ["SOURCE_DUPLICATES_NOT_DEDUPLICATED", "TRANSPORT_RETRIES_NOT_COUNTED", "USAGE_PARTIAL"];
|
|
4849
|
+
/**
|
|
4850
|
+
* What a cost figure leaves out. `SOURCE_DUPLICATES_NOT_DEDUPLICATED` and
|
|
4851
|
+
* `TRANSPORT_RETRIES_NOT_COUNTED` mark a `source-characters` estimate, with the meaning the same
|
|
4852
|
+
* code has on a run estimate; keys the provider failed on are not counted either, and the locale's
|
|
4853
|
+
* `providerFailures` says how many. `USAGE_PARTIAL` marks a `usage` figure that is a lower bound,
|
|
4854
|
+
* whether or not a rate was found: at least one locale sent keys and reported no tokens, so the
|
|
4855
|
+
* amount, when there is one, and the recorded token count cover only what was reported. A locale that reported usage for some of its sub-batches but not all cannot be told
|
|
4856
|
+
* apart, and shows no mark.
|
|
4857
|
+
*/
|
|
4858
|
+
type RunCostCaveat = (typeof RUN_COST_CAVEATS)[number];
|
|
4859
|
+
/** Every {@link RunHistoryUnavailableReason}. */
|
|
4860
|
+
declare const RUN_HISTORY_UNAVAILABLE_REASONS: readonly ["unreadable", "too-large"];
|
|
4861
|
+
/**
|
|
4862
|
+
* Why the whole run-history file could not be read, which {@link runHistory} reports instead of an
|
|
4863
|
+
* error: `unreadable` when something exists at the path but the process could not read it as a
|
|
4864
|
+
* regular file, `too-large` when it is over 8 MiB. A missing file is not unavailable, it is an
|
|
4865
|
+
* empty history, and a line that is not valid UTF-8 is one unreadable record, not an unavailable
|
|
4866
|
+
* file.
|
|
4867
|
+
*/
|
|
4868
|
+
type RunHistoryUnavailableReason = (typeof RUN_HISTORY_UNAVAILABLE_REASONS)[number];
|
|
4869
|
+
/**
|
|
4870
|
+
* The zod schema for a {@link RunHistoryResult}, the result of {@link runHistory}. Published as
|
|
4871
|
+
* `run-history-result.json`.
|
|
4872
|
+
*/
|
|
4873
|
+
declare const runHistoryResultSchema: z.ZodObject<{
|
|
4874
|
+
records: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
4875
|
+
version: z.ZodLiteral<1>;
|
|
4876
|
+
at: z.ZodISODateTime;
|
|
4877
|
+
trigger: z.ZodEnum<{
|
|
4878
|
+
translate: "translate";
|
|
4879
|
+
retranslate: "retranslate";
|
|
4880
|
+
}>;
|
|
4881
|
+
provider: z.ZodString;
|
|
4882
|
+
model: z.ZodOptional<z.ZodString>;
|
|
4883
|
+
entries: z.ZodOptional<z.ZodNumber>;
|
|
4884
|
+
usage: z.ZodOptional<z.ZodObject<{
|
|
4885
|
+
inputTokens: z.ZodNumber;
|
|
4886
|
+
outputTokens: z.ZodNumber;
|
|
4887
|
+
}, z.core.$strip>>;
|
|
4888
|
+
cost: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4889
|
+
pricing: z.ZodLiteral<"priced">;
|
|
4890
|
+
basis: z.ZodEnum<{
|
|
4891
|
+
usage: "usage";
|
|
4892
|
+
"source-characters": "source-characters";
|
|
4893
|
+
}>;
|
|
4894
|
+
rateKey: z.ZodString;
|
|
4895
|
+
currency: z.ZodString;
|
|
4896
|
+
asOf: z.ZodISODate;
|
|
4897
|
+
amount: z.ZodNumber;
|
|
4898
|
+
caveats: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
4899
|
+
SOURCE_DUPLICATES_NOT_DEDUPLICATED: "SOURCE_DUPLICATES_NOT_DEDUPLICATED";
|
|
4900
|
+
TRANSPORT_RETRIES_NOT_COUNTED: "TRANSPORT_RETRIES_NOT_COUNTED";
|
|
4901
|
+
USAGE_PARTIAL: "USAGE_PARTIAL";
|
|
4902
|
+
}>>>>;
|
|
4903
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
4904
|
+
pricing: z.ZodEnum<{
|
|
4905
|
+
"no-rate-on-file": "no-rate-on-file";
|
|
4906
|
+
"rate-unit-mismatch": "rate-unit-mismatch";
|
|
4907
|
+
"no-usage": "no-usage";
|
|
4908
|
+
}>;
|
|
4909
|
+
basis: z.ZodEnum<{
|
|
4910
|
+
usage: "usage";
|
|
4911
|
+
"source-characters": "source-characters";
|
|
4912
|
+
}>;
|
|
4913
|
+
rateKey: z.ZodString;
|
|
4914
|
+
caveats: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
4915
|
+
SOURCE_DUPLICATES_NOT_DEDUPLICATED: "SOURCE_DUPLICATES_NOT_DEDUPLICATED";
|
|
4916
|
+
TRANSPORT_RETRIES_NOT_COUNTED: "TRANSPORT_RETRIES_NOT_COUNTED";
|
|
4917
|
+
USAGE_PARTIAL: "USAGE_PARTIAL";
|
|
4918
|
+
}>>>>;
|
|
4919
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
4920
|
+
pricing: z.ZodLiteral<"not-billed">;
|
|
4921
|
+
rateKey: z.ZodString;
|
|
4922
|
+
caveats: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
4923
|
+
SOURCE_DUPLICATES_NOT_DEDUPLICATED: "SOURCE_DUPLICATES_NOT_DEDUPLICATED";
|
|
4924
|
+
TRANSPORT_RETRIES_NOT_COUNTED: "TRANSPORT_RETRIES_NOT_COUNTED";
|
|
4925
|
+
USAGE_PARTIAL: "USAGE_PARTIAL";
|
|
4926
|
+
}>>>>;
|
|
4927
|
+
}, z.core.$strip>], "pricing">;
|
|
4928
|
+
locales: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
4929
|
+
locale: z.ZodString;
|
|
4930
|
+
status: z.ZodEnum<{
|
|
4931
|
+
failed: "failed";
|
|
4932
|
+
succeeded: "succeeded";
|
|
4933
|
+
partial: "partial";
|
|
4934
|
+
}>;
|
|
4935
|
+
translated: z.ZodDefault<z.ZodNumber>;
|
|
4936
|
+
cacheHits: z.ZodDefault<z.ZodNumber>;
|
|
4937
|
+
fuzzyHits: z.ZodDefault<z.ZodNumber>;
|
|
4938
|
+
generated: z.ZodDefault<z.ZodNumber>;
|
|
4939
|
+
pruned: z.ZodDefault<z.ZodNumber>;
|
|
4940
|
+
integrityMismatches: z.ZodDefault<z.ZodNumber>;
|
|
4941
|
+
providerFailures: z.ZodDefault<z.ZodNumber>;
|
|
4942
|
+
usage: z.ZodOptional<z.ZodObject<{
|
|
4943
|
+
inputTokens: z.ZodNumber;
|
|
4944
|
+
outputTokens: z.ZodNumber;
|
|
4945
|
+
}, z.core.$strip>>;
|
|
4946
|
+
coverage: z.ZodOptional<z.ZodObject<{
|
|
4947
|
+
missing: z.ZodNumber;
|
|
4948
|
+
stale: z.ZodNumber;
|
|
4949
|
+
upToDate: z.ZodNumber;
|
|
4950
|
+
}, z.core.$strip>>;
|
|
4951
|
+
}, z.core.$strip>>>;
|
|
4952
|
+
localesOmitted: z.ZodOptional<z.ZodNumber>;
|
|
4953
|
+
coverageUnavailable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
4954
|
+
}, z.core.$strip>>>;
|
|
4955
|
+
total: z.ZodNumber;
|
|
4956
|
+
unreadableRecords: z.ZodNumber;
|
|
4957
|
+
unavailable: z.ZodOptional<z.ZodEnum<{
|
|
4958
|
+
unreadable: "unreadable";
|
|
4959
|
+
"too-large": "too-large";
|
|
4960
|
+
}>>;
|
|
4961
|
+
}, z.core.$strip>;
|
|
4962
|
+
/**
|
|
4963
|
+
* How far a locale is translated, measured by a {@link check} pass after the run: the same three
|
|
4964
|
+
* counts {@link LocaleCheckSummary} reports.
|
|
4965
|
+
*/
|
|
4966
|
+
interface RunHistoryCoverage {
|
|
4967
|
+
/** Source keys with a non-blank value and no translation in the locale yet. */
|
|
4968
|
+
readonly missing: number;
|
|
4969
|
+
/** Keys whose source text changed since the locale was last translated. */
|
|
4970
|
+
readonly stale: number;
|
|
4971
|
+
/** Keys whose translation still matches the source recorded in the lock-file. */
|
|
4972
|
+
readonly upToDate: number;
|
|
4973
|
+
}
|
|
4974
|
+
/** One locale's part of a {@link RunHistoryRecord}: counts only, never a key name or a text. */
|
|
4975
|
+
interface RunHistoryLocale {
|
|
4976
|
+
/** The target locale. */
|
|
4977
|
+
readonly locale: string;
|
|
4978
|
+
/** How the locale finished, as in {@link LocaleSummary.status}. */
|
|
4979
|
+
readonly status: "succeeded" | "partial" | "failed";
|
|
4980
|
+
/** Keys that received a new value from the provider. */
|
|
4981
|
+
readonly translated: number;
|
|
4982
|
+
/** Keys served from the translation memory instead of the provider. */
|
|
4983
|
+
readonly cacheHits: number;
|
|
4984
|
+
/** Keys reused from the translation memory for a changed source string. */
|
|
4985
|
+
readonly fuzzyHits: number;
|
|
4986
|
+
/** Plural forms generated for the target language. */
|
|
4987
|
+
readonly generated: number;
|
|
4988
|
+
/** Orphaned keys removed from the locale. */
|
|
4989
|
+
readonly pruned: number;
|
|
4990
|
+
/** Keys whose translation the integrity gate refused. */
|
|
4991
|
+
readonly integrityMismatches: number;
|
|
4992
|
+
/** Keys the provider failed to translate. */
|
|
4993
|
+
readonly providerFailures: number;
|
|
4994
|
+
/** Token usage for this locale, absent when the provider reports none. */
|
|
4995
|
+
readonly usage?: UsageSummary | undefined;
|
|
4996
|
+
/**
|
|
4997
|
+
* Coverage measured after the run. Absent for a locale that was not measured, including every
|
|
4998
|
+
* locale of a record with `coverageUnavailable`.
|
|
4999
|
+
*/
|
|
5000
|
+
readonly coverage?: RunHistoryCoverage | undefined;
|
|
5001
|
+
}
|
|
5002
|
+
/**
|
|
5003
|
+
* What a run cost, frozen when the record was written from the `rates` the config held then.
|
|
5004
|
+
* `pricing` says whether a rate was found; only `priced` carries `currency`, `asOf` and `amount`.
|
|
5005
|
+
* A `source-characters` figure is an estimate, never an invoice: show it as one.
|
|
5006
|
+
*/
|
|
5007
|
+
type RunHistoryCost = {
|
|
5008
|
+
/** A rate for the provider and model was on file and applied. */
|
|
5009
|
+
readonly pricing: "priced";
|
|
5010
|
+
/** Where the quantity comes from. */
|
|
5011
|
+
readonly basis: RunCostBasis;
|
|
5012
|
+
/** The `provider/model` or bare provider id the rate was looked up under. */
|
|
5013
|
+
readonly rateKey: string;
|
|
5014
|
+
/** The three-letter currency code of the rate card at the time. */
|
|
5015
|
+
readonly currency: string;
|
|
5016
|
+
/** The `asOf` date of the rate card at the time, as `YYYY-MM-DD`. */
|
|
5017
|
+
readonly asOf: string;
|
|
5018
|
+
/** The cost in `currency`. */
|
|
5019
|
+
readonly amount: number;
|
|
5020
|
+
/**
|
|
5021
|
+
* What a `source-characters` figure leaves out, or `USAGE_PARTIAL` when part of the usage
|
|
5022
|
+
* went unreported. Absent for a complete `usage` figure.
|
|
5023
|
+
*/
|
|
5024
|
+
readonly caveats?: readonly RunCostCaveat[] | undefined;
|
|
5025
|
+
} | {
|
|
5026
|
+
/**
|
|
5027
|
+
* Why no figure exists: no rate on file, a rate in the wrong unit, or keys were sent to a
|
|
5028
|
+
* token-billed provider that reported no usage (`no-usage`). Show it as unknown, never as
|
|
5029
|
+
* free.
|
|
5030
|
+
*/
|
|
5031
|
+
readonly pricing: "no-rate-on-file" | "rate-unit-mismatch" | "no-usage";
|
|
5032
|
+
/** Where the quantity would have come from. */
|
|
5033
|
+
readonly basis: RunCostBasis;
|
|
5034
|
+
/** The `provider/model` or bare provider id looked up. */
|
|
5035
|
+
readonly rateKey: string;
|
|
5036
|
+
/**
|
|
5037
|
+
* What a `source-characters` figure leaves out, or `USAGE_PARTIAL` when part of the usage
|
|
5038
|
+
* went unreported. Absent for a complete `usage` figure.
|
|
5039
|
+
*/
|
|
5040
|
+
readonly caveats?: readonly RunCostCaveat[] | undefined;
|
|
5041
|
+
} | {
|
|
5042
|
+
/** The provider is self-hosted or `none`, so no API bills for the run. */
|
|
5043
|
+
readonly pricing: "not-billed";
|
|
5044
|
+
/** The `provider/model` or bare provider id looked up. */
|
|
5045
|
+
readonly rateKey: string;
|
|
5046
|
+
/**
|
|
5047
|
+
* `USAGE_PARTIAL` when part of the reported token usage is missing, so the recorded token
|
|
5048
|
+
* count is a lower bound. Absent otherwise.
|
|
5049
|
+
*/
|
|
5050
|
+
readonly caveats?: readonly RunCostCaveat[] | undefined;
|
|
5051
|
+
};
|
|
5052
|
+
/**
|
|
5053
|
+
* One finished run in the local run history. It holds counts, usage and cost only: no key name and
|
|
5054
|
+
* no translation text, which is why the history file can sit in `.verbatra-local` and never needs
|
|
5055
|
+
* committing.
|
|
5056
|
+
*/
|
|
5057
|
+
interface RunHistoryRecord {
|
|
5058
|
+
/** The record format version, `1`. */
|
|
5059
|
+
readonly version: 1;
|
|
5060
|
+
/** When the record was written, an ISO 8601 UTC timestamp. */
|
|
5061
|
+
readonly at: string;
|
|
5062
|
+
/** What produced the run. */
|
|
5063
|
+
readonly trigger: RunHistoryTrigger;
|
|
5064
|
+
/** The configured provider's id. */
|
|
5065
|
+
readonly provider: string;
|
|
5066
|
+
/** The configured model, when the provider has one. */
|
|
5067
|
+
readonly model?: string | undefined;
|
|
5068
|
+
/**
|
|
5069
|
+
* The number of keys a `retranslate` record covers: one for {@link retranslateEntry}, and for
|
|
5070
|
+
* {@link retranslateEntries} the number of entries attempted, that is, whose provider call was
|
|
5071
|
+
* made, whether it answered, was refused by the integrity gate or failed. Absent for `translate`.
|
|
5072
|
+
*/
|
|
5073
|
+
readonly entries?: number | undefined;
|
|
5074
|
+
/** Token usage of the whole run, absent when the provider reports none or nothing was sent. */
|
|
5075
|
+
readonly usage?: UsageSummary | undefined;
|
|
5076
|
+
/** What the run cost, frozen at write. */
|
|
5077
|
+
readonly cost: RunHistoryCost;
|
|
5078
|
+
/** The locales the run touched, with their counts. */
|
|
5079
|
+
readonly locales: readonly RunHistoryLocale[];
|
|
5080
|
+
/** How many locales were left out of `locales` to keep the record small. Absent when none. */
|
|
5081
|
+
readonly localesOmitted?: number | undefined;
|
|
5082
|
+
/** `true` when the coverage pass after the run failed, so no locale carries `coverage`. */
|
|
5083
|
+
readonly coverageUnavailable?: true | undefined;
|
|
5084
|
+
}
|
|
5085
|
+
|
|
4786
5086
|
/**
|
|
4787
5087
|
* Where a finished run stands against its token budget.
|
|
4788
5088
|
*
|
|
@@ -4857,6 +5157,18 @@ interface IncompletePlural {
|
|
|
4857
5157
|
readonly missing: readonly PluralCategory[];
|
|
4858
5158
|
}
|
|
4859
5159
|
|
|
5160
|
+
/**
|
|
5161
|
+
* Why a result holds values to the config's `maxLength` budgets alone although
|
|
5162
|
+
* `verbatra.limits.json` exists. Returned as `limitsNotice` by every call that reads the limits
|
|
5163
|
+
* file when the file cannot be used; the file is left as it is.
|
|
5164
|
+
*/
|
|
5165
|
+
interface LimitsFileNotice {
|
|
5166
|
+
/** Always `LIMITS_FILE_IGNORED`. */
|
|
5167
|
+
readonly code: "LIMITS_FILE_IGNORED";
|
|
5168
|
+
/** What is wrong with the file, never a path or a value. */
|
|
5169
|
+
readonly message: string;
|
|
5170
|
+
}
|
|
5171
|
+
|
|
4860
5172
|
/**
|
|
4861
5173
|
* The two severities of a quality-check finding, lowest last. An `error` is a value the
|
|
4862
5174
|
* write-time integrity gate would refuse; a `warning` is a review reason a translation run would
|
|
@@ -4937,6 +5249,8 @@ interface CheckQaSummary {
|
|
|
4937
5249
|
* against such a source, so these keys are skipped in every locale until the source is fixed.
|
|
4938
5250
|
*/
|
|
4939
5251
|
readonly invalidSourceKeys: readonly string[];
|
|
5252
|
+
/** Present when `verbatra.limits.json` could not be used, so `MAX_LENGTH_EXCEEDED` was judged against the config's budgets alone. */
|
|
5253
|
+
readonly limitsNotice?: LimitsFileNotice;
|
|
4940
5254
|
}
|
|
4941
5255
|
|
|
4942
5256
|
/** One locale's counts in a {@link CheckSummary}. */
|
|
@@ -5151,6 +5465,10 @@ interface CheckDeps {
|
|
|
5151
5465
|
* locale and the resolved path. A caller that maps SDK codes should be ready for an unrecognized
|
|
5152
5466
|
* error from a target file.
|
|
5153
5467
|
*
|
|
5468
|
+
* With `qa` set, a `verbatra.limits.json` that cannot be used is ignored, so only the config's
|
|
5469
|
+
* `maxLength` budgets apply, and `qa.limitsNotice` in the result says so; {@link doctor} names the
|
|
5470
|
+
* problem.
|
|
5471
|
+
*
|
|
5154
5472
|
* @param input - The config and the optional locale filter.
|
|
5155
5473
|
* @param deps - Optional adapter registry and file-system overrides.
|
|
5156
5474
|
* @returns Per-locale counts and the project-wide in-sync verdict.
|
|
@@ -5278,8 +5596,9 @@ interface CheckFileDeps {
|
|
|
5278
5596
|
/**
|
|
5279
5597
|
* Checks one locale file, the fast path for validating a file right after it was edited by hand
|
|
5280
5598
|
* or by an agent. It reads that file and, for a target locale, the source locale file, and
|
|
5281
|
-
* nothing else
|
|
5282
|
-
*
|
|
5599
|
+
* nothing else but the project's `verbatra.limits.json`, which it reads for the `maxLength` budgets:
|
|
5600
|
+
* no other locale, no lock-file, no provenance file, no source code,
|
|
5601
|
+
* and no provider. It writes nothing and needs no API key.
|
|
5283
5602
|
*
|
|
5284
5603
|
* The file is resolved against the config's `files.pattern` and `files.localeStyle` to the locale
|
|
5285
5604
|
* it holds. A file that cannot be parsed is reported as a {@link QaSyntaxFinding}, with the line
|
|
@@ -5290,6 +5609,9 @@ interface CheckFileDeps {
|
|
|
5290
5609
|
* syntax alone, since there is nothing to hold it against; its keys whose value is not a valid ICU
|
|
5291
5610
|
* message are listed in `qa.invalidSourceKeys`.
|
|
5292
5611
|
*
|
|
5612
|
+
* A `verbatra.limits.json` that cannot be used is ignored, so only the config's `maxLength`
|
|
5613
|
+
* budgets apply, and the result's `qa.limitsNotice` says so; {@link doctor} names the problem.
|
|
5614
|
+
*
|
|
5293
5615
|
* @param input - The config, the file, and the optional severity floor.
|
|
5294
5616
|
* @param deps - Optional adapter registry and file-system overrides.
|
|
5295
5617
|
* @returns The file's role, one locale result (one per target locale for a catalogue), and totals.
|
|
@@ -5394,6 +5716,10 @@ declare const checkFileSummarySchema: z.ZodObject<{
|
|
|
5394
5716
|
errors: z.ZodNumber;
|
|
5395
5717
|
warnings: z.ZodNumber;
|
|
5396
5718
|
invalidSourceKeys: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
5719
|
+
limitsNotice: z.ZodExactOptional<z.ZodObject<{
|
|
5720
|
+
code: z.ZodLiteral<"LIMITS_FILE_IGNORED">;
|
|
5721
|
+
message: z.ZodString;
|
|
5722
|
+
}, z.core.$strip>>;
|
|
5397
5723
|
}, z.core.$strip>;
|
|
5398
5724
|
}, z.core.$strip>;
|
|
5399
5725
|
|
|
@@ -5500,6 +5826,10 @@ declare const checkSummarySchema: z.ZodObject<{
|
|
|
5500
5826
|
errors: z.ZodNumber;
|
|
5501
5827
|
warnings: z.ZodNumber;
|
|
5502
5828
|
invalidSourceKeys: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
5829
|
+
limitsNotice: z.ZodExactOptional<z.ZodObject<{
|
|
5830
|
+
code: z.ZodLiteral<"LIMITS_FILE_IGNORED">;
|
|
5831
|
+
message: z.ZodString;
|
|
5832
|
+
}, z.core.$strip>>;
|
|
5503
5833
|
}, z.core.$strip>>;
|
|
5504
5834
|
review: z.ZodExactOptional<z.ZodObject<{
|
|
5505
5835
|
reviewed: z.ZodBoolean;
|
|
@@ -5532,7 +5862,10 @@ declare const checkSummarySchema: z.ZodObject<{
|
|
|
5532
5862
|
}, z.core.$strip>>;
|
|
5533
5863
|
}, z.core.$strip>;
|
|
5534
5864
|
|
|
5535
|
-
/**
|
|
5865
|
+
/**
|
|
5866
|
+
* The {@link DataFlowManifest.version} this build writes. A renamed or removed field raises it; an
|
|
5867
|
+
* added enum member or optional field does not.
|
|
5868
|
+
*/
|
|
5536
5869
|
declare const DATA_FLOW_MANIFEST_VERSION = 1;
|
|
5537
5870
|
/** Whether the provider is a prompt-driven LLM, a machine-translation API, or `none`. */
|
|
5538
5871
|
type DataFlowProviderKind = "llm" | "machine-translation" | "none";
|
|
@@ -5673,8 +6006,12 @@ interface DataFlowLocale {
|
|
|
5673
6006
|
}
|
|
5674
6007
|
/** One file or directory verbatra writes on the local disk. */
|
|
5675
6008
|
interface DataFlowLocalFile {
|
|
5676
|
-
/**
|
|
5677
|
-
|
|
6009
|
+
/**
|
|
6010
|
+
* Which file: the lock file, the provenance file, the length limits file, the translation memory,
|
|
6011
|
+
* or the local state directory, which holds the run status, the run history (counts, token usage
|
|
6012
|
+
* and cost per run, no key name and no text) and the write locks.
|
|
6013
|
+
*/
|
|
6014
|
+
readonly id: "lock" | "provenance" | "limits" | "cache" | "local-state";
|
|
5678
6015
|
/** The project-relative path it is written to, with `/` separators. */
|
|
5679
6016
|
readonly path: string;
|
|
5680
6017
|
/** Whether it holds source text, or text derived from it. */
|
|
@@ -6497,6 +6834,11 @@ interface LocaleCapabilityReport {
|
|
|
6497
6834
|
* left behind after the config respelled it `pt-BR`, says whether the next {@link translate} run
|
|
6498
6835
|
* carries it over to the configured spelling, and suggests removing it or respelling the
|
|
6499
6836
|
* configured locale otherwise. It is `warn` when it names one or cannot read that state.
|
|
6837
|
+
* - `limits`: informational, never fails. Reads `verbatra.limits.json`, the file of per-key length
|
|
6838
|
+
* limits that sits beside the lock file. It is `warn` when the file cannot be used (a run ignores
|
|
6839
|
+
* it and a limit cannot be set until it is fixed), when a limit names a key the source does not
|
|
6840
|
+
* have, when the config's `maxLength` overrides a limit, or when the source could not be read to
|
|
6841
|
+
* check the keys. It is `pass` when the file is absent or empty.
|
|
6500
6842
|
* - `locales`: the configured provider supports the source locale and every target locale, judged
|
|
6501
6843
|
* against the language table verbatra ships for a machine-translation provider (see
|
|
6502
6844
|
* {@link LocaleSupport}). It fails when a locale is `unsupported`, exactly the case
|
|
@@ -6513,7 +6855,7 @@ interface LocaleCapabilityReport {
|
|
|
6513
6855
|
* source locale file could not be read for the counts. It runs only when
|
|
6514
6856
|
* {@link DoctorInput.dataFlow} is set.
|
|
6515
6857
|
*/
|
|
6516
|
-
type DoctorCheckId = "config" | "format-adapter" | "provider" | "api-key" | "network-policy" | "source-file" | "plural-rules" | "plural-completeness" | "locale-codes" | "locale-state" | "locales" | "untranslated-literals" | "data-flow";
|
|
6858
|
+
type DoctorCheckId = "config" | "format-adapter" | "provider" | "api-key" | "network-policy" | "source-file" | "plural-rules" | "plural-completeness" | "locale-codes" | "locale-state" | "limits" | "locales" | "untranslated-literals" | "data-flow";
|
|
6517
6859
|
/**
|
|
6518
6860
|
* The verdict on one {@link DoctorCheck}.
|
|
6519
6861
|
*
|
|
@@ -6767,6 +7109,7 @@ declare const doctorResultSchema: z.ZodObject<{
|
|
|
6767
7109
|
provider: "provider";
|
|
6768
7110
|
locales: "locales";
|
|
6769
7111
|
config: "config";
|
|
7112
|
+
limits: "limits";
|
|
6770
7113
|
"format-adapter": "format-adapter";
|
|
6771
7114
|
"api-key": "api-key";
|
|
6772
7115
|
"network-policy": "network-policy";
|
|
@@ -7136,6 +7479,17 @@ type RetranslateEntryResult = {
|
|
|
7136
7479
|
* when nothing was flagged. The value is written either way; these are advisory.
|
|
7137
7480
|
*/
|
|
7138
7481
|
readonly reviewReasons: readonly ReviewReasonCode[];
|
|
7482
|
+
/**
|
|
7483
|
+
* Present when `verbatra.limits.json` could not be used, so `reviewReasons` was judged against
|
|
7484
|
+
* the config's `maxLength` budgets alone.
|
|
7485
|
+
*/
|
|
7486
|
+
readonly limitsNotice?: LimitsFileNotice;
|
|
7487
|
+
/**
|
|
7488
|
+
* Tokens the provider reported for this call, absent when it reports none (DeepL, Google
|
|
7489
|
+
* Cloud Translation, LibreTranslate). Present on a refused result too, since the provider was
|
|
7490
|
+
* billed before the integrity gate ran.
|
|
7491
|
+
*/
|
|
7492
|
+
readonly usage?: UsageSummary;
|
|
7139
7493
|
} | {
|
|
7140
7494
|
/** The value was refused; nothing was written and the previous translation is intact. */
|
|
7141
7495
|
readonly accepted: false;
|
|
@@ -7154,6 +7508,17 @@ type RetranslateEntryResult = {
|
|
|
7154
7508
|
readonly details?: readonly string[];
|
|
7155
7509
|
/** The rejected value, echoed back so a UI can show what was refused. */
|
|
7156
7510
|
readonly value: string;
|
|
7511
|
+
/**
|
|
7512
|
+
* Present when `verbatra.limits.json` could not be used, so the provider was given the
|
|
7513
|
+
* config's `maxLength` budgets alone.
|
|
7514
|
+
*/
|
|
7515
|
+
readonly limitsNotice?: LimitsFileNotice;
|
|
7516
|
+
/**
|
|
7517
|
+
* Tokens the provider reported for this call, absent when it reports none (DeepL, Google
|
|
7518
|
+
* Cloud Translation, LibreTranslate). Present on a refused result too, since the provider was
|
|
7519
|
+
* billed before the integrity gate ran.
|
|
7520
|
+
*/
|
|
7521
|
+
readonly usage?: UsageSummary;
|
|
7157
7522
|
};
|
|
7158
7523
|
/**
|
|
7159
7524
|
* Re-runs the configured provider for a single key and saves the result. This is the paid
|
|
@@ -7183,6 +7548,10 @@ type RetranslateEntryResult = {
|
|
|
7183
7548
|
* adapter codes to its own copy. A caller that maps SDK codes should be ready for an unrecognized
|
|
7184
7549
|
* error from a target file on either path.
|
|
7185
7550
|
*
|
|
7551
|
+
* A `verbatra.limits.json` that cannot be used is ignored, so the value is held to the config's
|
|
7552
|
+
* `maxLength` budgets only, and the result's `limitsNotice` says so; {@link doctor} names the
|
|
7553
|
+
* problem.
|
|
7554
|
+
*
|
|
7186
7555
|
* It spends outside the token budget. `maxTokens` and `budgetBehavior` bound a {@link translate}
|
|
7187
7556
|
* run, and this is its own single-key path with its own provider, so a configured ceiling neither
|
|
7188
7557
|
* withholds this call nor counts it. A caller that exposes retranslation to users, as the Studio
|
|
@@ -7837,6 +8206,17 @@ declare const extractResultSchema: z.ZodObject<{
|
|
|
7837
8206
|
dryRun: z.ZodBoolean;
|
|
7838
8207
|
}, z.core.$strip>;
|
|
7839
8208
|
|
|
8209
|
+
/** The kind of value a message argument takes, as far as verbatra can tell from the message. */
|
|
8210
|
+
type MessageArgumentType = "string" | "number" | "date" | "unknown" | "date-or-string";
|
|
8211
|
+
/** One named argument of a message. */
|
|
8212
|
+
interface NamedMessageArgument {
|
|
8213
|
+
/** The argument's name as written in the message. */
|
|
8214
|
+
readonly name: string;
|
|
8215
|
+
/** The value type the argument takes. */
|
|
8216
|
+
readonly type: MessageArgumentType;
|
|
8217
|
+
/** True when some arm of the message omits the argument, so a caller may leave it out. */
|
|
8218
|
+
readonly optional?: boolean;
|
|
8219
|
+
}
|
|
7840
8220
|
/**
|
|
7841
8221
|
* Why verbatra declined to describe a message's arguments rather than guessing at them.
|
|
7842
8222
|
*
|
|
@@ -7848,6 +8228,31 @@ declare const extractResultSchema: z.ZodObject<{
|
|
|
7848
8228
|
* of 64 or more (such as `%0$s` or `{64}`).
|
|
7849
8229
|
*/
|
|
7850
8230
|
type UnresolvedArgumentReason = "invalid-message-syntax" | "mixed-argument-styles" | "argument-index-out-of-range";
|
|
8231
|
+
/**
|
|
8232
|
+
* The arguments a message takes, by style: `none`, `named` (`{name}`), `positional` (`{0}` or
|
|
8233
|
+
* `%s`), or `unresolved` when verbatra declined to describe them, with the reason.
|
|
8234
|
+
*/
|
|
8235
|
+
type MessageArguments = {
|
|
8236
|
+
/** The message takes no arguments. */
|
|
8237
|
+
readonly style: "none";
|
|
8238
|
+
} | {
|
|
8239
|
+
/** The message takes named arguments, such as `{name}`. */
|
|
8240
|
+
readonly style: "named";
|
|
8241
|
+
/** The arguments, in the order they first appear. */
|
|
8242
|
+
readonly named: readonly NamedMessageArgument[];
|
|
8243
|
+
} | {
|
|
8244
|
+
/** The message takes numbered or unnumbered arguments, such as `{0}` or `%s`. */
|
|
8245
|
+
readonly style: "positional";
|
|
8246
|
+
/** The value type of each argument, by zero-based position. */
|
|
8247
|
+
readonly positional: readonly MessageArgumentType[];
|
|
8248
|
+
/** The position from which every later argument is optional. Absent when none are. */
|
|
8249
|
+
readonly optionalFrom?: number;
|
|
8250
|
+
} | {
|
|
8251
|
+
/** verbatra declined to describe the arguments. */
|
|
8252
|
+
readonly style: "unresolved";
|
|
8253
|
+
/** Why the arguments could not be described. */
|
|
8254
|
+
readonly reason: UnresolvedArgumentReason;
|
|
8255
|
+
};
|
|
7851
8256
|
|
|
7852
8257
|
/**
|
|
7853
8258
|
* Where {@link generateTypes} writes its declaration when the caller names no path: a `.d.ts` at
|
|
@@ -8042,8 +8447,12 @@ interface GitExecFileResult {
|
|
|
8042
8447
|
}
|
|
8043
8448
|
/**
|
|
8044
8449
|
* An argument-array process runner, never a shell string, mirroring the shape of
|
|
8045
|
-
* `util.promisify(child_process.execFile)`. {@link localeHistory}
|
|
8046
|
-
* Inject your own to sandbox
|
|
8450
|
+
* `util.promisify(child_process.execFile)`. {@link localeHistory}, {@link keyHistory},
|
|
8451
|
+
* {@link localeGitStatus} and {@link localeGitDiff} call it only to run `git`. Inject your own to sandbox those calls or to
|
|
8452
|
+
* serve the answers from somewhere else. The default runner passes git a minimal environment with
|
|
8453
|
+
* no inherited `GIT_*` variable. A runner of your own must do the same, and must honour the
|
|
8454
|
+
* timeout and output limits: only the default runner guarantees them. It need not set
|
|
8455
|
+
* `GIT_NO_LAZY_FETCH`, since the arguments already carry `--no-lazy-fetch` on a git that knows it.
|
|
8047
8456
|
*
|
|
8048
8457
|
* @param file - The executable to run, resolved on `PATH`.
|
|
8049
8458
|
* @param args - The arguments, passed as a list so no value is ever interpreted by a shell.
|
|
@@ -8058,15 +8467,283 @@ type GitExecFile = (file: string, args: readonly string[], options: {
|
|
|
8058
8467
|
/** The most bytes of standard output or error to accept before the process is killed. */
|
|
8059
8468
|
readonly maxBuffer: number;
|
|
8060
8469
|
}) => Promise<GitExecFileResult>;
|
|
8470
|
+
/** How long each git command run by {@link localeGitStatus} and {@link localeGitDiff} may take, in milliseconds. */
|
|
8471
|
+
declare const LOCALE_GIT_TIMEOUT_MS = 10000;
|
|
8472
|
+
/** The most output {@link localeGitStatus} and {@link localeGitDiff} accept from one git command, in bytes: 1 MiB. */
|
|
8473
|
+
declare const LOCALE_GIT_MAX_OUTPUT_BYTES = 1048576;
|
|
8474
|
+
|
|
8475
|
+
/**
|
|
8476
|
+
* Why {@link localeGitStatus} or {@link localeGitDiff} could not read the repository:
|
|
8477
|
+
*
|
|
8478
|
+
* - `git-missing`: no `git` executable was found.
|
|
8479
|
+
* - `not-a-repository`: the project is not inside a git work tree.
|
|
8480
|
+
* - `bare-repository`: the project folder holds a bare repository of its own, which verbatra does
|
|
8481
|
+
* not open (`safe.bareRepository=explicit`), so a repository planted in a downloaded folder is refused.
|
|
8482
|
+
* - `dubious-ownership`: git refused the repository because another user owns it (`safe.directory`).
|
|
8483
|
+
* - `timeout`: a git command ran longer than {@link LOCALE_GIT_TIMEOUT_MS} and was stopped.
|
|
8484
|
+
* - `output-too-large`: a git command wrote more than {@link LOCALE_GIT_MAX_OUTPUT_BYTES}, or a
|
|
8485
|
+
* committed locale file is larger than {@link LOCALE_GIT_BLOB_MAX_BYTES}.
|
|
8486
|
+
* - `unsafe-config`: the repository configures more content filters than verbatra switches off, or
|
|
8487
|
+
* one whose name cannot be passed to git safely, so no command was run against it.
|
|
8488
|
+
* - `git-too-old`: the repository is a partial clone and git is older than 2.45, which cannot be told
|
|
8489
|
+
* not to fetch missing objects from the remote, so no command was run against it.
|
|
8490
|
+
* - `git-failed`: git failed in a way none of the other reasons names, such as a corrupt index.
|
|
8491
|
+
* - `custom-adapter`: ({@link localeGitDiff} only) the format is a `custom:` adapter, or the call
|
|
8492
|
+
* was given an adapter registry, so the committed file cannot be read through a private
|
|
8493
|
+
* in-memory file system.
|
|
8494
|
+
* - `revision-unreadable`: ({@link localeGitDiff} only) the committed locale file is not a regular
|
|
8495
|
+
* file or could not be parsed.
|
|
8496
|
+
* - `working-file-unreadable`: ({@link localeGitDiff} only) the locale file on disk is a symbolic
|
|
8497
|
+
* link or sits behind one, or could not be parsed.
|
|
8498
|
+
* - `outside-project`: a configured locale file lies outside the project directory, for example
|
|
8499
|
+
* with a `files.pattern` that starts with `../`, so the call cannot say what changed in it and
|
|
8500
|
+
* does not report a partial list as a complete one.
|
|
8501
|
+
*/
|
|
8502
|
+
type LocaleGitUnavailableReason = (typeof LOCALE_GIT_UNAVAILABLE_REASONS)[number];
|
|
8503
|
+
/**
|
|
8504
|
+
* The {@link LocaleGitUnavailableReason}s that name a repository that could not be read: all of
|
|
8505
|
+
* them except the ones only {@link localeGitDiff} and {@link localeGitStatus} give about a locale
|
|
8506
|
+
* file (`custom-adapter`, `revision-unreadable`, `working-file-unreadable` and `outside-project`).
|
|
8507
|
+
*/
|
|
8508
|
+
type LocaleGitRepositoryUnavailableReason = Exclude<LocaleGitUnavailableReason, "custom-adapter" | "revision-unreadable" | "working-file-unreadable" | "outside-project">;
|
|
8509
|
+
/** Every {@link LocaleGitUnavailableReason}, in the order the documentation lists them. */
|
|
8510
|
+
declare const LOCALE_GIT_UNAVAILABLE_REASONS: readonly ["git-missing", "not-a-repository", "bare-repository", "dubious-ownership", "timeout", "output-too-large", "unsafe-config", "git-too-old", "git-failed", "custom-adapter", "revision-unreadable", "working-file-unreadable", "outside-project"];
|
|
8511
|
+
|
|
8512
|
+
/**
|
|
8513
|
+
* How git sees one watched file against `HEAD` and the index:
|
|
8514
|
+
*
|
|
8515
|
+
* - `modified`: the file changed, including a change of file type, and a file taken out of the index
|
|
8516
|
+
* that is still on disk (a staged deletion together with an untracked or ignored file).
|
|
8517
|
+
* - `added`: the file is new in the index and not in `HEAD`.
|
|
8518
|
+
* - `deleted`: the file is gone from the working tree or the index.
|
|
8519
|
+
* - `untracked`: git does not track the file yet.
|
|
8520
|
+
* - `conflicted`: the file has unresolved merge conflicts.
|
|
8521
|
+
*/
|
|
8522
|
+
type LocaleGitFileState = (typeof LOCALE_GIT_FILE_STATES)[number];
|
|
8523
|
+
/** Every {@link LocaleGitFileState}, in the order the documentation lists them. */
|
|
8524
|
+
declare const LOCALE_GIT_FILE_STATES: readonly ["modified", "added", "deleted", "untracked", "conflicted"];
|
|
8525
|
+
/** One changed file in a {@link LocaleGitStatusResult}. */
|
|
8526
|
+
interface LocaleGitFile {
|
|
8527
|
+
/** The file's path relative to the project directory, with `/` separators. */
|
|
8528
|
+
readonly path: string;
|
|
8529
|
+
/**
|
|
8530
|
+
* The locales whose data lives in this file: one for a one-file-per-locale format, every
|
|
8531
|
+
* configured locale for a shared catalogue such as `apple-xcstrings`, none for
|
|
8532
|
+
* `verbatra.lock.json` and `verbatra.provenance.json`.
|
|
8533
|
+
*/
|
|
8534
|
+
readonly locales: readonly string[];
|
|
8535
|
+
/** How git sees the file. */
|
|
8536
|
+
readonly state: LocaleGitFileState;
|
|
8537
|
+
}
|
|
8538
|
+
/**
|
|
8539
|
+
* The result of {@link localeGitStatus}: `available: false` with a reason when the repository could
|
|
8540
|
+
* not be read, otherwise the branch and the changed files.
|
|
8541
|
+
*/
|
|
8542
|
+
type LocaleGitStatusResult = {
|
|
8543
|
+
/** `false`: the repository could not be read. */
|
|
8544
|
+
readonly available: false;
|
|
8545
|
+
/** Why the repository could not be read. */
|
|
8546
|
+
readonly reason: LocaleGitUnavailableReason;
|
|
8547
|
+
} | {
|
|
8548
|
+
/** `true`: the repository was read. */
|
|
8549
|
+
readonly available: true;
|
|
8550
|
+
/** The checked-out branch, also on a branch with no commits yet. `null` on a detached `HEAD`. */
|
|
8551
|
+
readonly branch: string | null;
|
|
8552
|
+
/** The watched files that differ from `HEAD`, in config order; clean files are not listed. */
|
|
8553
|
+
readonly files: readonly LocaleGitFile[];
|
|
8554
|
+
};
|
|
8555
|
+
/** Input for {@link localeGitStatus}. */
|
|
8556
|
+
interface LocaleGitStatusInput {
|
|
8557
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
8558
|
+
readonly config: VerbatraConfig;
|
|
8559
|
+
/** Directory the `files.pattern` is resolved against and git runs in. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory; pass `cwd` from {@link resolveProjectRoot} for a copied config. */
|
|
8560
|
+
readonly cwd?: string;
|
|
8561
|
+
}
|
|
8562
|
+
/** Injectable dependencies for {@link localeGitStatus}. Every field has a working default. */
|
|
8563
|
+
interface LocaleGitStatusDeps {
|
|
8564
|
+
/** Runs `git`. Defaults to a real `child_process.execFile`. */
|
|
8565
|
+
readonly execFile?: GitExecFile;
|
|
8566
|
+
}
|
|
8567
|
+
/**
|
|
8568
|
+
* Lists which locale files, `verbatra.lock.json` and `verbatra.provenance.json` differ from the
|
|
8569
|
+
* last commit, each with its state, and names the checked-out branch. It writes nothing, calls no
|
|
8570
|
+
* provider and takes no path from the caller: the watched files come from the config.
|
|
8571
|
+
*
|
|
8572
|
+
* The default runner starts git as an argument list, never through a shell, with a minimal
|
|
8573
|
+
* environment (`PATH`, `HOME` and the Windows system variables, no `GIT_*` variable and no
|
|
8574
|
+
* `XDG_CONFIG_HOME`, so the global git configuration is read from `HOME` alone) and with optional
|
|
8575
|
+
* locks, `core.fsmonitor`, bare-repository discovery, submodule inspection, lazy fetching from a
|
|
8576
|
+
* partial clone's remote and every content filter the repository configures switched off. Lazy
|
|
8577
|
+
* fetching is switched off with `--no-lazy-fetch`, which needs git 2.45 or newer: on an older git a
|
|
8578
|
+
* partial clone is refused with `git-too-old`. Paths are matched literally and follow a `--`
|
|
8579
|
+
* separator, so a path that starts with a dash is not read as an option; a path beyond the project
|
|
8580
|
+
* directory is never passed. Every command is killed after {@link LOCALE_GIT_TIMEOUT_MS} and may
|
|
8581
|
+
* write at most {@link LOCALE_GIT_MAX_OUTPUT_BYTES}. A runner you inject through `execFile` gets
|
|
8582
|
+
* the same arguments but must supply the environment and the limits itself. The tests cover the routes a repository's own configuration
|
|
8583
|
+
* could use to make git run a command: filter drivers, `core.fsmonitor`, aliases, pagers, hook
|
|
8584
|
+
* paths, text conversion drivers, a promisor remote's command and a bare repository planted in the
|
|
8585
|
+
* folder. That is not a promise that opening a project is safe: a `verbatra.config.ts` is code
|
|
8586
|
+
* verbatra runs. The branch name is stripped of control and bidirectional formatting characters.
|
|
8587
|
+
* Renames are reported as a deleted and an added file. A file taken out of the index that is still on
|
|
8588
|
+
* disk is `modified`. A file behind a symbolic link or inside a submodule is never listed, and the
|
|
8589
|
+
* call does not say so. The `apple-strings` format also watches each locale's `.stringsdict` file,
|
|
8590
|
+
* listed with the same locales as its `.strings` file.
|
|
8591
|
+
*
|
|
8592
|
+
* @param input - The config and the project directory.
|
|
8593
|
+
* @param deps - Optional process runner override.
|
|
8594
|
+
* @returns The branch and the changed files, or `available: false` with a
|
|
8595
|
+
* {@link LocaleGitUnavailableReason} when git is missing, the project is not in a work tree, git
|
|
8596
|
+
* refused the repository's ownership, the repository configures a filter verbatra cannot switch off,
|
|
8597
|
+
* or a command timed out, wrote too much or failed.
|
|
8598
|
+
*
|
|
8599
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
8600
|
+
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
8601
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
8602
|
+
*
|
|
8603
|
+
* @example
|
|
8604
|
+
* ```ts
|
|
8605
|
+
* import { loadConfig, localeGitStatus } from "@verbatra/sdk";
|
|
8606
|
+
*
|
|
8607
|
+
* const config = await loadConfig();
|
|
8608
|
+
* const status = await localeGitStatus({ config });
|
|
8609
|
+
* if (status.available) {
|
|
8610
|
+
* for (const file of status.files) {
|
|
8611
|
+
* console.log(file.state, file.path);
|
|
8612
|
+
* }
|
|
8613
|
+
* }
|
|
8614
|
+
* ```
|
|
8615
|
+
*/
|
|
8616
|
+
declare function localeGitStatus(input: LocaleGitStatusInput, deps?: LocaleGitStatusDeps): Promise<LocaleGitStatusResult>;
|
|
8617
|
+
|
|
8618
|
+
/** How git sees the file: a {@link LocaleGitFileState}, or `unchanged` when it matches `HEAD`. */
|
|
8619
|
+
type LocaleGitDiffState = LocaleGitFileState | "unchanged";
|
|
8620
|
+
/** A key present on only one side of a {@link localeGitDiff}, with its text. */
|
|
8621
|
+
interface LocaleGitDiffEntry {
|
|
8622
|
+
/** The key. */
|
|
8623
|
+
readonly key: string;
|
|
8624
|
+
/** The key's text, cut to {@link LOCALE_GIT_DIFF_MAX_VALUE_CHARS} characters. */
|
|
8625
|
+
readonly value: string;
|
|
8626
|
+
}
|
|
8627
|
+
/** A key present on both sides of a {@link localeGitDiff} whose text differs. */
|
|
8628
|
+
interface LocaleGitDiffChange {
|
|
8629
|
+
/** The key. */
|
|
8630
|
+
readonly key: string;
|
|
8631
|
+
/** The text at `HEAD`, cut to {@link LOCALE_GIT_DIFF_MAX_VALUE_CHARS} characters. */
|
|
8632
|
+
readonly before: string;
|
|
8633
|
+
/** The text in the working tree, cut to {@link LOCALE_GIT_DIFF_MAX_VALUE_CHARS} characters. */
|
|
8634
|
+
readonly after: string;
|
|
8635
|
+
}
|
|
8636
|
+
/**
|
|
8637
|
+
* The result of {@link localeGitDiff}: `available: false` with a reason when the comparison could
|
|
8638
|
+
* not be made, otherwise the key-level difference between `HEAD` and the working tree.
|
|
8639
|
+
*/
|
|
8640
|
+
type LocaleGitDiffResult = {
|
|
8641
|
+
/** `false`: the comparison could not be made. */
|
|
8642
|
+
readonly available: false;
|
|
8643
|
+
/** Why the comparison could not be made. */
|
|
8644
|
+
readonly reason: LocaleGitUnavailableReason;
|
|
8645
|
+
} | {
|
|
8646
|
+
/** `true`: the comparison was made. */
|
|
8647
|
+
readonly available: true;
|
|
8648
|
+
/** The locale's file path relative to the project directory, with `/` separators. */
|
|
8649
|
+
readonly path: string;
|
|
8650
|
+
/** How git sees the file. A `conflicted` file carries no difference, and neither does an `unchanged` one. */
|
|
8651
|
+
readonly state: LocaleGitDiffState;
|
|
8652
|
+
/** Keys in the working tree and not at `HEAD`, in working-tree order. */
|
|
8653
|
+
readonly added: readonly LocaleGitDiffEntry[];
|
|
8654
|
+
/** Keys at `HEAD` and not in the working tree, in `HEAD` order. */
|
|
8655
|
+
readonly removed: readonly LocaleGitDiffEntry[];
|
|
8656
|
+
/** Keys on both sides with different text, in working-tree order. */
|
|
8657
|
+
readonly changed: readonly LocaleGitDiffChange[];
|
|
8658
|
+
/** `true` when more than {@link LOCALE_GIT_DIFF_MAX_ENTRIES} keys differ or a text was cut, so the lists are incomplete. */
|
|
8659
|
+
readonly truncated: boolean;
|
|
8660
|
+
};
|
|
8661
|
+
/** Input for {@link localeGitDiff}. */
|
|
8662
|
+
interface LocaleGitDiffInput {
|
|
8663
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
8664
|
+
readonly config: VerbatraConfig;
|
|
8665
|
+
/** The source locale or a configured target locale to compare. */
|
|
8666
|
+
readonly locale: string;
|
|
8667
|
+
/** Directory the `files.pattern` is resolved against and git runs in. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory; pass `cwd` from {@link resolveProjectRoot} for a copied config. */
|
|
8668
|
+
readonly cwd?: string;
|
|
8669
|
+
}
|
|
8670
|
+
/**
|
|
8671
|
+
* Injectable dependencies for {@link localeGitDiff}. Passing an `adapterRegistry` makes the call
|
|
8672
|
+
* return `custom-adapter`: the committed file is parsed by the built-in adapters over a private
|
|
8673
|
+
* in-memory file system, which a registry of your own cannot be given.
|
|
8674
|
+
*/
|
|
8675
|
+
interface LocaleGitDiffDeps {
|
|
8676
|
+
/** Runs `git`. Defaults to a real `child_process.execFile`. */
|
|
8677
|
+
readonly execFile?: GitExecFile;
|
|
8678
|
+
/** Present only to be refused: any value makes the result `custom-adapter`. */
|
|
8679
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
8680
|
+
}
|
|
8681
|
+
/** The most differing keys {@link localeGitDiff} lists in total; the rest set `truncated`. */
|
|
8682
|
+
declare const LOCALE_GIT_DIFF_MAX_ENTRIES = 500;
|
|
8683
|
+
/** The longest text {@link localeGitDiff} returns for one value, in characters; a longer one is cut and sets `truncated`. */
|
|
8684
|
+
declare const LOCALE_GIT_DIFF_MAX_VALUE_CHARS = 2000;
|
|
8685
|
+
/**
|
|
8686
|
+
* Compares one locale's file at `HEAD` with the file on disk, key by key: the keys added, the keys
|
|
8687
|
+
* removed, and the keys whose text changed, each with its text. It writes nothing, calls no
|
|
8688
|
+
* provider and takes no path from the caller: the file comes from the config and the locale.
|
|
8689
|
+
*
|
|
8690
|
+
* The committed file is read with `git cat-file blob`, checked to be a regular file no larger than
|
|
8691
|
+
* {@link LOCALE_GIT_BLOB_MAX_BYTES} first, and parsed by the built-in adapter for the configured
|
|
8692
|
+
* format over an in-memory file system. Both sides are compared as parsed keys, never as text, and
|
|
8693
|
+
* git never runs a diff, a text conversion driver or an external diff. The command safeguards of
|
|
8694
|
+
* {@link localeGitStatus} apply, including the minimal environment and the refusal to fetch lazily:
|
|
8695
|
+
* a committed file missing from a partial clone reads as `revision-unreadable`. What is compared
|
|
8696
|
+
* follows what is there: a file absent at `HEAD` compares against nothing, and a file absent on disk
|
|
8697
|
+
* compares to nothing, whatever git's status code says. A `conflicted` or `unchanged` file is not
|
|
8698
|
+
* compared and lists no difference. The file on disk is read only when it is a regular file and the
|
|
8699
|
+
* real path of its directory is the project directory's real path plus the path written in the
|
|
8700
|
+
* config, so no parent directory is a symbolic link; the comparison is exact apart from Unicode
|
|
8701
|
+
* normalization and never ignores case, and a directory that cannot be inspected is refused rather
|
|
8702
|
+
* than read as empty. For `apple-strings` the
|
|
8703
|
+
* `.stringsdict` file is read with the `.strings` file on both sides, and the state reported is the
|
|
8704
|
+
* `.strings` file's, else the `.stringsdict` file's. At most {@link LOCALE_GIT_DIFF_MAX_ENTRIES}
|
|
8705
|
+
* keys are listed, and each key and text is cut to {@link LOCALE_GIT_DIFF_MAX_VALUE_CHARS}
|
|
8706
|
+
* characters, either of which sets `truncated`, so the result stays bounded. The keys and texts are
|
|
8707
|
+
* the file's own and untrusted: show them as text.
|
|
8708
|
+
*
|
|
8709
|
+
* A locale whose file is shared with others, as in `apple-xcstrings`, is compared for that locale
|
|
8710
|
+
* alone. A `custom:` format, or a call that passes an `adapterRegistry`, returns `custom-adapter`
|
|
8711
|
+
* because a custom adapter cannot be run against a private in-memory file system.
|
|
8712
|
+
*
|
|
8713
|
+
* @param input - The config, the locale and the project directory.
|
|
8714
|
+
* @param deps - Optional process runner override, and an adapter registry that is refused.
|
|
8715
|
+
* @returns The difference, or `available: false` with a {@link LocaleGitUnavailableReason}.
|
|
8716
|
+
*
|
|
8717
|
+
* @throws {@link SdkError} `UNKNOWN_LOCALE`: the locale is neither the source nor a configured
|
|
8718
|
+
* target locale.
|
|
8719
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
8720
|
+
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
8721
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
8722
|
+
*
|
|
8723
|
+
* @example
|
|
8724
|
+
* ```ts
|
|
8725
|
+
* import { loadConfig, localeGitDiff } from "@verbatra/sdk";
|
|
8726
|
+
*
|
|
8727
|
+
* const config = await loadConfig();
|
|
8728
|
+
* const diff = await localeGitDiff({ config, locale: "de" });
|
|
8729
|
+
* if (diff.available) {
|
|
8730
|
+
* for (const change of diff.changed) {
|
|
8731
|
+
* console.log(change.key, change.before, "->", change.after);
|
|
8732
|
+
* }
|
|
8733
|
+
* }
|
|
8734
|
+
* ```
|
|
8735
|
+
*/
|
|
8736
|
+
declare function localeGitDiff(input: LocaleGitDiffInput, deps?: LocaleGitDiffDeps): Promise<LocaleGitDiffResult>;
|
|
8737
|
+
|
|
8061
8738
|
/** One commit that touched a locale file, as {@link localeHistory} lists it. */
|
|
8062
8739
|
interface LocaleHistoryCommit {
|
|
8063
8740
|
/** The full commit hash. */
|
|
8064
8741
|
readonly hash: string;
|
|
8065
|
-
/** The author's name as git records it, after `.mailmap
|
|
8742
|
+
/** The author's name as git records it, after `.mailmap`, with anything shaped like an API key replaced by `[REDACTED]`, cut to 200 characters. Never the email address. */
|
|
8066
8743
|
readonly author: string;
|
|
8067
8744
|
/** The author date in strict ISO 8601. */
|
|
8068
8745
|
readonly authorDate: string;
|
|
8069
|
-
/** The first line of the commit message. */
|
|
8746
|
+
/** The first line of the commit message, with anything shaped like an API key replaced by `[REDACTED]`, cut to 500 characters. */
|
|
8070
8747
|
readonly subject: string;
|
|
8071
8748
|
/** The watched locale files the commit touched, relative to the repository root. */
|
|
8072
8749
|
readonly touchedPaths: readonly string[];
|
|
@@ -8076,12 +8753,17 @@ interface LocaleHistoryCommit {
|
|
|
8076
8753
|
*
|
|
8077
8754
|
* - `git-missing`: no `git` executable was found.
|
|
8078
8755
|
* - `not-a-repository`: the project is not inside a git repository.
|
|
8756
|
+
* - `bare-repository`: the project folder holds a bare repository of its own, which is not opened.
|
|
8757
|
+
* - `dubious-ownership`: git refused the repository because another user owns it.
|
|
8079
8758
|
* - `timeout`: `git log` ran longer than {@link LOCALE_HISTORY_TIMEOUT_MS} and was stopped.
|
|
8080
8759
|
* - `output-too-large`: `git log` wrote more than {@link LOCALE_HISTORY_MAX_OUTPUT_BYTES}.
|
|
8760
|
+
* - `unsafe-config`: the repository configures more content filters than can be switched off, or
|
|
8761
|
+
* one whose name cannot be passed to git safely.
|
|
8762
|
+
* - `git-too-old`: the repository is a partial clone and git is older than 2.45.
|
|
8081
8763
|
*/
|
|
8082
8764
|
type LocaleHistoryUnavailableReason = (typeof LOCALE_HISTORY_UNAVAILABLE_REASONS)[number];
|
|
8083
8765
|
/** Every {@link LocaleHistoryUnavailableReason}, in the order the documentation lists them. */
|
|
8084
|
-
declare const LOCALE_HISTORY_UNAVAILABLE_REASONS: readonly ["git-missing", "not-a-repository", "timeout", "output-too-large"];
|
|
8766
|
+
declare const LOCALE_HISTORY_UNAVAILABLE_REASONS: readonly ["git-missing", "not-a-repository", "bare-repository", "dubious-ownership", "timeout", "output-too-large", "unsafe-config", "git-too-old"];
|
|
8085
8767
|
/**
|
|
8086
8768
|
* The result of {@link localeHistory}: `available: false` with a reason when the history could not
|
|
8087
8769
|
* be read, otherwise the commits, newest first.
|
|
@@ -8096,6 +8778,8 @@ type LocaleHistoryResult = {
|
|
|
8096
8778
|
readonly available: true;
|
|
8097
8779
|
/** The commits that touched the locale files, newest first. */
|
|
8098
8780
|
readonly commits: readonly LocaleHistoryCommit[];
|
|
8781
|
+
/** `true` when more than 256 distinct keys, one key longer than 4096 characters, or keys adding up to more than 65,536 UTF-16 code units turned up in author names and subjects, so every non-empty `subject` and `author` was replaced by `[REDACTED]` (empty text stays empty). Absent otherwise. */
|
|
8782
|
+
readonly truncated?: true;
|
|
8099
8783
|
};
|
|
8100
8784
|
/** How long {@link localeHistory} lets `git log` run before stopping it, in milliseconds. */
|
|
8101
8785
|
declare const LOCALE_HISTORY_TIMEOUT_MS = 10000;
|
|
@@ -8106,6 +8790,97 @@ declare const LOCALE_HISTORY_LIMIT_DEFAULT = 50;
|
|
|
8106
8790
|
/** The most commits {@link localeHistory} lists, whatever `limit` asks for. */
|
|
8107
8791
|
declare const LOCALE_HISTORY_LIMIT_CAP = 200;
|
|
8108
8792
|
|
|
8793
|
+
/** The largest committed locale file {@link localeGitDiff} reads, in bytes: 8 MiB. */
|
|
8794
|
+
declare const LOCALE_GIT_BLOB_MAX_BYTES = 8388608;
|
|
8795
|
+
|
|
8796
|
+
/** Which argument a preview row varies, or `none` for a message with nothing to vary. */
|
|
8797
|
+
type IcuPreviewAxis = "plural" | "ordinal" | "select" | "none";
|
|
8798
|
+
/**
|
|
8799
|
+
* Why a message could not be previewed.
|
|
8800
|
+
*
|
|
8801
|
+
* - `too-long`: the message is over 20,000 characters.
|
|
8802
|
+
* - `too-complex`: the message nests deeper than 16 braces or has more than 256 `{` and `<` characters.
|
|
8803
|
+
* - `invalid-message`: the message does not parse as ICU.
|
|
8804
|
+
* - `unsupported-locale`: this runtime's CLDR data does not know the locale, or it is malformed.
|
|
8805
|
+
* - `too-large`: the first row alone would render more than 100,000 characters or 5,000 segments.
|
|
8806
|
+
*/
|
|
8807
|
+
type IcuPreviewFailure = "too-long" | "too-complex" | "invalid-message" | "unsupported-locale" | "too-large";
|
|
8808
|
+
/** One rendering of a message with one argument varied. Arguments that enclose it are held at the arm that contains it; `category` repeats when the same arm appears in several places. */
|
|
8809
|
+
interface IcuPreviewRow {
|
|
8810
|
+
/** What the row varies: a cardinal plural, an ordinal plural, a select, or `none`. */
|
|
8811
|
+
readonly axis: IcuPreviewAxis;
|
|
8812
|
+
/** The argument the row varies, or `null` when the message has none to vary. */
|
|
8813
|
+
readonly argument: string | null;
|
|
8814
|
+
/** The plural category, an exact arm such as `=0`, or the select option the row shows; for a row showing a value you supplied, the arm that value selects. `null` when the message has nothing to vary. */
|
|
8815
|
+
readonly category: string | null;
|
|
8816
|
+
/** The value the varied argument took in this row. `null` when the message has nothing to vary. */
|
|
8817
|
+
readonly sample: string | number | null;
|
|
8818
|
+
/** True for the row that shows a value you supplied in `args` for this argument rather than one of its arms. */
|
|
8819
|
+
readonly supplied: boolean;
|
|
8820
|
+
/** The enclosing arguments this row holds at the arm that contains the varied argument, by name. Empty when the varied argument is not nested. */
|
|
8821
|
+
readonly held: Readonly<Record<string, string | number>>;
|
|
8822
|
+
/** The rendered message. Plain text runs only: never markup to interpret. */
|
|
8823
|
+
readonly segments: readonly IcuSegment[];
|
|
8824
|
+
}
|
|
8825
|
+
/** Input for {@link previewIcuMessage}. */
|
|
8826
|
+
interface IcuPreviewInput {
|
|
8827
|
+
/** The resolved project config. Only its `format` is read. */
|
|
8828
|
+
readonly config: VerbatraConfig;
|
|
8829
|
+
/** The locale the message is rendered for. A locale this runtime's CLDR data does not know is refused as `unsupported-locale`. */
|
|
8830
|
+
readonly locale: string;
|
|
8831
|
+
/** The message text. Untrusted: a value over 20,000 characters, nested deeper than 16 braces, or with more than 256 `{` and `<` characters is refused rather than parsed. */
|
|
8832
|
+
readonly value: string;
|
|
8833
|
+
/** Sample values for the message's arguments, by name. Numbers drive plural and number arguments, and a number given for a date argument is read as milliseconds since the epoch. Names the message does not use are ignored. A value for a plural, ordinal or select argument adds one row showing it for each axis it drives, at the first place it reaches an arm of that argument (a place that agrees with your other values comes first), and in the ordinary rows is replaced by the arm each row shows. A number text such as `"5"` reads as the number, as the runtime does. */
|
|
8834
|
+
readonly args?: Readonly<Record<string, string | number>>;
|
|
8835
|
+
}
|
|
8836
|
+
/**
|
|
8837
|
+
* What {@link previewIcuMessage} found.
|
|
8838
|
+
*
|
|
8839
|
+
* - `supported: false`: the configured format does not use ICU message syntax, so there is nothing
|
|
8840
|
+
* to preview.
|
|
8841
|
+
* - `valid: false`: the message was refused, with the reason.
|
|
8842
|
+
* - `valid: true`: the message's arguments and its renderings.
|
|
8843
|
+
*/
|
|
8844
|
+
type IcuPreviewResult = {
|
|
8845
|
+
readonly supported: false;
|
|
8846
|
+
readonly reason: "not-icu";
|
|
8847
|
+
} | {
|
|
8848
|
+
readonly supported: true;
|
|
8849
|
+
readonly valid: false;
|
|
8850
|
+
readonly reason: IcuPreviewFailure;
|
|
8851
|
+
} | {
|
|
8852
|
+
readonly supported: true;
|
|
8853
|
+
readonly valid: true;
|
|
8854
|
+
/** The message's arguments with the types verbatra infers for them. */
|
|
8855
|
+
readonly arguments: MessageArguments;
|
|
8856
|
+
/** One row per plural category, exact arm, or select option, varying one argument at a time. At most 24. */
|
|
8857
|
+
readonly rows: readonly IcuPreviewRow[];
|
|
8858
|
+
/** True when a reachable arm has no row because the preview needed more than 24 rows or ran out of its shared 100,000-character or 5,000-segment output budget. Arms no input can reach do not set it. */
|
|
8859
|
+
readonly truncated: boolean;
|
|
8860
|
+
};
|
|
8861
|
+
/**
|
|
8862
|
+
* Renders an ICU message for a locale, one row per arm: each plural category, exact arm and select
|
|
8863
|
+
* option, and each place one of them appears.
|
|
8864
|
+
*
|
|
8865
|
+
* Previews only the formats whose messages use ICU syntax, `next-intl-json` and `arb`; any other
|
|
8866
|
+
* format, including a `custom:` one, answers `supported: false`. The message is untrusted text and
|
|
8867
|
+
* the call never throws on it: an over-long, over-nested, malformed or otherwise unusable message,
|
|
8868
|
+
* or an unknown locale, comes back as `valid: false` with a reason. Numbers and dates are formatted
|
|
8869
|
+
* with this runtime's Node CLDR data, dates at a fixed instant in UTC unless a number in `args` sets the instant, so the text can differ from
|
|
8870
|
+
* what an application's own runtime prints. Nothing is read from or written to disk.
|
|
8871
|
+
*
|
|
8872
|
+
* Each row varies one argument and holds the others at `args` or a default. A row for an argument
|
|
8873
|
+
* nested inside another argument's arm also holds that enclosing argument at the arm, so the row
|
|
8874
|
+
* shows the arm it names; the `args` value for an argument a row varies or holds this way is
|
|
8875
|
+
* replaced in that row, and a value you give for a plural, ordinal or select argument adds one row of its own for each axis that argument drives, a plural, an ordinal or a select, placed after that axis's rows and marked `supplied`; its `category` is the arm the value selects at the first place it reaches one, and a value that reaches no arm of an axis adds no row for it. Text that is not a number selects `other` in a plural, where `#` stays `#`. `held` lists the enclosing arguments a row holds, so nested rows can be told apart. The supplied rows count toward the 24 rows and the output budget. An arm that appears in several places gets a row for each place, and rows with
|
|
8876
|
+
* the same label and the same text collapse into one. The rows share one output budget; when it runs
|
|
8877
|
+
* out, or more than 24 rows exist, the rest are left out and `truncated` is set.
|
|
8878
|
+
*
|
|
8879
|
+
* @param input - The config, locale, message and optional sample values.
|
|
8880
|
+
* @returns The preview, or why there is nothing to preview.
|
|
8881
|
+
*/
|
|
8882
|
+
declare function previewIcuMessage(input: IcuPreviewInput): IcuPreviewResult;
|
|
8883
|
+
|
|
8109
8884
|
/** Input for {@link keyValue}. */
|
|
8110
8885
|
interface KeyValueInput {
|
|
8111
8886
|
/** The resolved project config, normally from {@link loadConfig}. */
|
|
@@ -8207,8 +8982,12 @@ interface KeyContextGlossaryNotice {
|
|
|
8207
8982
|
interface KeyContext extends KeyValueResult {
|
|
8208
8983
|
/** The glossary terms whose source occurs in the source text, as that locale is held to them. */
|
|
8209
8984
|
readonly glossary: LocaleGlossary;
|
|
8210
|
-
/** The key's
|
|
8985
|
+
/** The key's `maxLength` budget in characters, from the config or from `verbatra.limits.json`, absent when neither sets one. */
|
|
8211
8986
|
readonly maxLength?: number;
|
|
8987
|
+
/** Where `maxLength` comes from: the config wins over the limits file. Present exactly when `maxLength` is. */
|
|
8988
|
+
readonly maxLengthSource?: MaxLengthSource;
|
|
8989
|
+
/** Present when `verbatra.limits.json` could not be used, so `maxLength` is the config's alone. Its code is `LIMITS_FILE_IGNORED`. */
|
|
8990
|
+
readonly limitsNotice?: LimitsFileNotice;
|
|
8212
8991
|
/** How the input's `draft` uses the applying terms, absent when no draft was given. */
|
|
8213
8992
|
readonly draftCheck?: GlossaryDraftCheck;
|
|
8214
8993
|
/** Present when the glossary could not be read; the glossary part is then empty. */
|
|
@@ -8217,7 +8996,7 @@ interface KeyContext extends KeyValueResult {
|
|
|
8217
8996
|
/**
|
|
8218
8997
|
* Reads what a translator needs to write one key in one target locale: the key's current source
|
|
8219
8998
|
* and target text with provenance and description (as {@link keyValue} reports them), the glossary
|
|
8220
|
-
* terms that apply to the source text, the key's `maxLength` budget, and, when a draft is given,
|
|
8999
|
+
* terms that apply to the source text, the key's `maxLength` budget (from the config, else from `verbatra.limits.json`), and, when a draft is given,
|
|
8221
9000
|
* how that draft uses the applying terms. It writes nothing and calls no provider.
|
|
8222
9001
|
*
|
|
8223
9002
|
* Glossary values pass through secret redaction before they are matched. A glossary that cannot be
|
|
@@ -8256,6 +9035,210 @@ interface KeyContext extends KeyValueResult {
|
|
|
8256
9035
|
*/
|
|
8257
9036
|
declare function keyContext(input: KeyContextInput, deps?: KeyContextDeps): Promise<KeyContext>;
|
|
8258
9037
|
|
|
9038
|
+
/** How a {@link KeyHistorySegment} relates the older text to the newer one. */
|
|
9039
|
+
type KeyHistorySegmentKind = "equal" | "added" | "removed";
|
|
9040
|
+
/** One run of text in a word-level difference between two values. */
|
|
9041
|
+
interface KeyHistorySegment {
|
|
9042
|
+
/** `equal` text is in both values, `removed` only in the older one, `added` only in the newer one. */
|
|
9043
|
+
readonly kind: KeyHistorySegmentKind;
|
|
9044
|
+
/** The text of the run. It is the value's own text and untrusted: show it as text, never as markup. */
|
|
9045
|
+
readonly text: string;
|
|
9046
|
+
}
|
|
9047
|
+
|
|
9048
|
+
/** The longest value {@link keyHistory} returns, in characters. A longer one is counted in `unreadableRevisions` instead. */
|
|
9049
|
+
declare const KEY_HISTORY_MAX_VALUE_CHARS = 4096;
|
|
9050
|
+
/** The longest key {@link keyHistory} accepts, in characters. */
|
|
9051
|
+
declare const KEY_HISTORY_MAX_KEY_CHARS = 1024;
|
|
9052
|
+
/** How long after its start {@link keyHistory} still begins a new read, in milliseconds. A read already running is not cut short. */
|
|
9053
|
+
declare const KEY_HISTORY_DEADLINE_MS = 30000;
|
|
9054
|
+
/**
|
|
9055
|
+
* Why a {@link keyHistory} answer may be incomplete, in the order they are listed:
|
|
9056
|
+
* `commit-limit` (older commits exist than the limit examines), `shallow-clone`,
|
|
9057
|
+
* `unreadable-revision` (a commit's file could not be read or parsed, held a value that is too
|
|
9058
|
+
* long, or had a log line that did not parse), `file-too-large` (a commit's file was above the
|
|
9059
|
+
* size cap for its format), `byte-budget` (the files read in one call reached their total size
|
|
9060
|
+
* budget), `deadline` (the time ran out), `source-unreadable` (the source file could not be read in
|
|
9061
|
+
* full), `records-unreadable` (a lock-file or provenance file could not be read in full) and
|
|
9062
|
+
* `scrub-cap` (more than 256 distinct keys, one key longer than 4096 characters, or keys adding up to more than 65,536 UTF-16 code units turned up: the answer then replaces every non-empty value, diff segment, subject and author name with `[REDACTED]`, leaves empty text empty, and sets `valueRedacted` on every revision).
|
|
9063
|
+
*/
|
|
9064
|
+
declare const KEY_HISTORY_TRUNCATION_REASONS: readonly ["commit-limit", "shallow-clone", "unreadable-revision", "file-too-large", "byte-budget", "deadline", "source-unreadable", "records-unreadable", "scrub-cap"];
|
|
9065
|
+
/** One member of {@link KEY_HISTORY_TRUNCATION_REASONS}. */
|
|
9066
|
+
type KeyHistoryTruncation = (typeof KEY_HISTORY_TRUNCATION_REASONS)[number];
|
|
9067
|
+
/**
|
|
9068
|
+
* One commit in which a key's value changed, as {@link keyHistory} lists it.
|
|
9069
|
+
*/
|
|
9070
|
+
interface KeyRevision {
|
|
9071
|
+
/** The full commit hash. */
|
|
9072
|
+
readonly commit: string;
|
|
9073
|
+
/** The author date in strict ISO 8601. */
|
|
9074
|
+
readonly authorDate: string;
|
|
9075
|
+
/** The author's name after `.mailmap`, never the email address, scrubbed with {@link redact} before it is cut to 200 characters. */
|
|
9076
|
+
readonly author: string;
|
|
9077
|
+
/** The first line of the commit message, scrubbed with {@link redact} before it is cut to 500 characters. */
|
|
9078
|
+
readonly subject: string;
|
|
9079
|
+
/** The key's value in that commit. Untrusted: show it as text. Anything shaped like an API key is replaced by `[REDACTED]`, and so is any other text equal to a key that {@link redact} replaced in a value, subject or author name elsewhere in the same answer. */
|
|
9080
|
+
readonly value: string;
|
|
9081
|
+
/**
|
|
9082
|
+
* Which write path produced the value, read from `verbatra.provenance.json` as committed with it:
|
|
9083
|
+
* a stored origin, `unrecorded` when that file holds no record for the key, or `external` when
|
|
9084
|
+
* its record describes a different value. Absent when that file could not be read or parsed, is
|
|
9085
|
+
* above 4 MiB, lay past the 128 MiB a call reads of lock and provenance files, or when the time
|
|
9086
|
+
* ran out before it was.
|
|
9087
|
+
*/
|
|
9088
|
+
readonly origin?: KeyOrigin;
|
|
9089
|
+
/**
|
|
9090
|
+
* Whether the content hash of the key's current source entry (text, description, meaning,
|
|
9091
|
+
* plural flag and placeholders) differs from the hash the lock-file recorded for the key in that
|
|
9092
|
+
* commit. `unknown` when the lock-file, its entry for the key or the current source entry is not
|
|
9093
|
+
* available, or when the lock-file was above its size limit, did not parse or the time ran out
|
|
9094
|
+
* before it was read. Unlike `origin`, which compares the value with the provenance record and
|
|
9095
|
+
* is absent when that file cannot be used, this never depends on the value. Restoring a revision
|
|
9096
|
+
* whose source entry changed makes it count as up to date.
|
|
9097
|
+
*/
|
|
9098
|
+
readonly sourceChanged: boolean | "unknown";
|
|
9099
|
+
/**
|
|
9100
|
+
* `true` when {@link redact} changed the value, which then holds `[REDACTED]` where a key
|
|
9101
|
+
* was. Such a value is not the stored text: do not offer it for restore.
|
|
9102
|
+
*/
|
|
9103
|
+
readonly valueRedacted?: true;
|
|
9104
|
+
/** The word-level difference from the previous value of the key, both sides scrubbed with {@link redact}; the whole value when the key first appears. */
|
|
9105
|
+
readonly diff: readonly KeyHistorySegment[];
|
|
9106
|
+
}
|
|
9107
|
+
/** A value in the working tree that is not committed yet. */
|
|
9108
|
+
interface KeyWorkingTreeValue {
|
|
9109
|
+
/** The key's value on disk. Untrusted: show it as text. */
|
|
9110
|
+
readonly value: string;
|
|
9111
|
+
/** `true` when {@link redact} changed the value: it is not the stored text, so do not offer it for restore. */
|
|
9112
|
+
readonly valueRedacted?: true;
|
|
9113
|
+
/** The word-level difference from the value at `HEAD`, both sides scrubbed with {@link redact}; the whole value when `HEAD` has none. */
|
|
9114
|
+
readonly diff: readonly KeyHistorySegment[];
|
|
9115
|
+
}
|
|
9116
|
+
/**
|
|
9117
|
+
* The result of {@link keyHistory}: `available: false` with a reason when the history could not be
|
|
9118
|
+
* read, otherwise the revisions, newest first.
|
|
9119
|
+
*/
|
|
9120
|
+
type KeyHistoryResult = {
|
|
9121
|
+
/** `false`: the history could not be read. */
|
|
9122
|
+
readonly available: false;
|
|
9123
|
+
/** Why the history could not be read. */
|
|
9124
|
+
readonly reason: LocaleGitUnavailableReason;
|
|
9125
|
+
} | {
|
|
9126
|
+
/** `true`: the history was read. */
|
|
9127
|
+
readonly available: true;
|
|
9128
|
+
/** The commits in which the key's value changed, newest first. */
|
|
9129
|
+
readonly revisions: readonly KeyRevision[];
|
|
9130
|
+
/** The value on disk, present only when it differs from the value at `HEAD`. */
|
|
9131
|
+
readonly workingTree?: KeyWorkingTreeValue;
|
|
9132
|
+
/** `true` when the value on disk could not be compared with `HEAD`, so `workingTree` is absent: the file on disk does not parse, is a symbolic link or is above its size limit, its value is longer than {@link KEY_HISTORY_MAX_VALUE_CHARS}, the copy at `HEAD` could not be read (it is above its size limit, does not parse or was not reached), or the time ran out. */
|
|
9133
|
+
readonly workingTreeUnreadable?: true;
|
|
9134
|
+
/** `true` when the answer may leave history out or leave a field unknown because something was not read in full: older commits were not examined (the commit limit, the size budget of the call or the time), the clone is shallow, more than 256 distinct keys, one key longer than 4096 characters, or keys adding up to more than 65,536 UTF-16 code units turned up, so every non-empty value, diff segment, subject and author name was replaced by `[REDACTED]`, a commit could not be read or parsed, was above its size limit or held a value that is too long, or a lock-file, provenance file or the source file could not be read, parsed or was above its size limit. `false` means every commit and record examined was read; the file on disk is reported only by `workingTreeUnreadable`. */
|
|
9135
|
+
readonly truncated: boolean;
|
|
9136
|
+
/** Why `truncated` is `true`: every member of {@link KEY_HISTORY_TRUNCATION_REASONS} that applies, in that order. Empty exactly when `truncated` is `false`. */
|
|
9137
|
+
readonly truncatedBy: readonly KeyHistoryTruncation[];
|
|
9138
|
+
/** How many examined commits held the locale file in a state that could not be read or whose value was too long. */
|
|
9139
|
+
readonly unreadableRevisions: number;
|
|
9140
|
+
};
|
|
9141
|
+
/** Input for {@link keyHistory}. */
|
|
9142
|
+
interface KeyHistoryInput {
|
|
9143
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
9144
|
+
readonly config: VerbatraConfig;
|
|
9145
|
+
/** Directory the `files.pattern` is resolved against and git runs in. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory; pass `cwd` from {@link resolveProjectRoot} for a copied config. */
|
|
9146
|
+
readonly cwd?: string;
|
|
9147
|
+
/** A configured target locale. */
|
|
9148
|
+
readonly locale: string;
|
|
9149
|
+
/** The key, at most {@link KEY_HISTORY_MAX_KEY_CHARS} characters. It is compared with parsed keys and never passed to git. */
|
|
9150
|
+
readonly key: string;
|
|
9151
|
+
/**
|
|
9152
|
+
* The most commits to examine. Rounded down and clamped to between 1 and
|
|
9153
|
+
* {@link LOCALE_HISTORY_LIMIT_CAP}; defaults to {@link LOCALE_HISTORY_LIMIT_DEFAULT}.
|
|
9154
|
+
*/
|
|
9155
|
+
readonly limit?: number;
|
|
9156
|
+
}
|
|
9157
|
+
/** Injectable dependencies for {@link keyHistory}. Every field has a working default. */
|
|
9158
|
+
interface KeyHistoryDeps {
|
|
9159
|
+
/** Runs `git`. Defaults to a real `child_process.execFile`. */
|
|
9160
|
+
readonly execFile?: GitExecFile;
|
|
9161
|
+
}
|
|
9162
|
+
/**
|
|
9163
|
+
* Lists the git commits in which one key's value changed in one target locale, newest first, each
|
|
9164
|
+
* with its author, date, subject, the value, where the value came from and a word-level
|
|
9165
|
+
* difference from the key's previous value. When the value on disk differs from the one at `HEAD`
|
|
9166
|
+
* it is returned as `workingTree`. It writes nothing and calls no provider.
|
|
9167
|
+
*
|
|
9168
|
+
* The locale file's commits come from `git log --first-parent` on that file alone (and its
|
|
9169
|
+
* `.stringsdict` file for `apple-strings`), so a change brought in by a merge appears on the merge
|
|
9170
|
+
* commit. Each commit's file is read with `git cat-file blob` over the safeguards of
|
|
9171
|
+
* {@link localeGitDiff}, parsed by the built-in adapter over an in-memory file system, and a
|
|
9172
|
+
* commit is listed only when the key's value differs from the value in the commit right before it
|
|
9173
|
+
* in the file's history, which must have been read. A commit that removes the key is not listed.
|
|
9174
|
+
* A value is compared exactly, so a change of whitespace alone is a revision. `origin` comes
|
|
9175
|
+
* from the provenance file and `sourceChanged` from the lock-file as committed with the
|
|
9176
|
+
* revision. At most {@link LOCALE_HISTORY_LIMIT_CAP} commits are examined,
|
|
9177
|
+
* {@link LOCALE_HISTORY_LIMIT_DEFAULT} by default, four files are read at a time, and after
|
|
9178
|
+
* {@link KEY_HISTORY_DEADLINE_MS} no further commit is examined and no commit file read starts (the file on disk is still read); the
|
|
9179
|
+
* `git log` call, a size listing and a read already running keep their own 10 second limit. A revision whose records were not read has no `origin` and `sourceChanged`
|
|
9180
|
+
* `"unknown"`.
|
|
9181
|
+
*
|
|
9182
|
+
* `truncated` is `true` whenever anything the call examined was skipped, unreadable, above a size
|
|
9183
|
+
* limit, past a budget or stopped by the deadline: older commits exist that were not examined, the
|
|
9184
|
+
* repository is a shallow clone, a commit could not be read or parsed, held a value that is too
|
|
9185
|
+
* long or had a log line that did not parse, the lock file, the provenance file or the source file
|
|
9186
|
+
* could not be read, parsed or was above its size limit, or the deadline passed. A commit is
|
|
9187
|
+
* listed as a change only when the commit before it was read, so a commit whose older neighbour
|
|
9188
|
+
* could not be read is not claimed as the key's change; `truncated` says so.
|
|
9189
|
+
*
|
|
9190
|
+
* What is read is bounded by sizes git reports before anything is parsed, so the same repository
|
|
9191
|
+
* gets the same byte-limit and budget decisions on every machine; a git call that times out, the
|
|
9192
|
+
* deadline and the provider keys in the environment (which decide what {@link redact} changes)
|
|
9193
|
+
* can still change an answer. A locale file above 512 KiB for `yaml` and the XML
|
|
9194
|
+
* formats (`xliff`, `android-xml`, `resx`, `apple-strings`) or above 4 MiB for the other formats
|
|
9195
|
+
* is skipped without being parsed, and the two files of an `apple-strings` commit count as their
|
|
9196
|
+
* sum. In one call the locale files read add up to at most 16 MiB for those formats and 128 MiB
|
|
9197
|
+
* for the others: past that, older commits are not examined. A lock file or provenance file above
|
|
9198
|
+
* 4 MiB is not read, and together they add up to at most 128 MiB per call: past that, older
|
|
9199
|
+
* revisions have no `origin` and `sourceChanged` is `"unknown"`. The source file follows the cap
|
|
9200
|
+
* of the locale files, and `sourceChanged` is `"unknown"` when it is above it. A commit skipped
|
|
9201
|
+
* for its size, or that cannot be read or parsed, counts in `unreadableRevisions`; a commit past
|
|
9202
|
+
* the budget is not examined and does not. Parsing yields to the event loop between files. The
|
|
9203
|
+
* file on disk follows the same cap; when it cannot be compared with `HEAD` the answer still lists
|
|
9204
|
+
* the revisions, has no `workingTree` and sets `workingTreeUnreadable`. That also happens when
|
|
9205
|
+
* `HEAD`'s own copy could not be read or the time ran out.
|
|
9206
|
+
*
|
|
9207
|
+
* Every value and both sides of every difference pass {@link redact}: a value that changes is
|
|
9208
|
+
* returned with `[REDACTED]` for the key and flagged `valueRedacted`, and must not be offered
|
|
9209
|
+
* for restore.
|
|
9210
|
+
*
|
|
9211
|
+
* Limits: renames are not followed, so history before a locale file was renamed is not listed;
|
|
9212
|
+
* edits that were never committed, other than the one on disk, are not seen; a key renamed in
|
|
9213
|
+
* the source looks like a new key. A file shared by locales, as in `apple-xcstrings`, is read for
|
|
9214
|
+
* the requested locale only. A `custom:` format answers `custom-adapter`. Author names and
|
|
9215
|
+
* subjects lose control and bidirectional formatting characters.
|
|
9216
|
+
*
|
|
9217
|
+
* @param input - The config, the locale, the key, the project directory and the commit limit.
|
|
9218
|
+
* @param deps - Optional process runner override.
|
|
9219
|
+
* @returns The revisions, or `available: false` with a {@link LocaleGitUnavailableReason}.
|
|
9220
|
+
*
|
|
9221
|
+
* @throws {@link SdkError} `UNKNOWN_LOCALE`: the locale is not a configured target locale.
|
|
9222
|
+
* @throws {@link SdkError} `UNKNOWN_KEY`: the key is empty or longer than {@link KEY_HISTORY_MAX_KEY_CHARS}.
|
|
9223
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
9224
|
+
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
9225
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
9226
|
+
*
|
|
9227
|
+
* @example
|
|
9228
|
+
* ```ts
|
|
9229
|
+
* import { keyHistory, loadConfig } from "@verbatra/sdk";
|
|
9230
|
+
*
|
|
9231
|
+
* const config = await loadConfig();
|
|
9232
|
+
* const history = await keyHistory({ config, locale: "de", key: "cart.title" });
|
|
9233
|
+
* if (history.available) {
|
|
9234
|
+
* for (const revision of history.revisions) {
|
|
9235
|
+
* console.log(revision.authorDate, revision.author, revision.value);
|
|
9236
|
+
* }
|
|
9237
|
+
* }
|
|
9238
|
+
* ```
|
|
9239
|
+
*/
|
|
9240
|
+
declare function keyHistory(input: KeyHistoryInput, deps?: KeyHistoryDeps): Promise<KeyHistoryResult>;
|
|
9241
|
+
|
|
8259
9242
|
/**
|
|
8260
9243
|
* One key's placeholder, ICU, ICU-arm, and inline-markup verdict in a {@link LocaleKeyIntegrity}
|
|
8261
9244
|
* report.
|
|
@@ -8404,16 +9387,21 @@ interface LocaleHistoryDeps {
|
|
|
8404
9387
|
* bidirectional formatting characters are removed from the author and the subject, and a commit
|
|
8405
9388
|
* whose metadata does not parse as a full hash, an ISO date, an author and a subject is left out.
|
|
8406
9389
|
* Renames are not followed, so history from before a locale file was renamed is not listed. Every
|
|
8407
|
-
* locale path is resolved inside `cwd
|
|
8408
|
-
*
|
|
8409
|
-
*
|
|
8410
|
-
*
|
|
9390
|
+
* locale path is resolved inside `cwd`, a path that would leave `cwd` is dropped, and the rest follow
|
|
9391
|
+
* a `--` separator, so a config value is never read as a git option. `git log` runs with the same
|
|
9392
|
+
* safeguards as {@link localeGitStatus}: a minimal environment with no inherited `GIT_*` variable,
|
|
9393
|
+
* no bare-repository discovery, no lazy fetching from a partial clone's remote, `core.fsmonitor` and
|
|
9394
|
+
* every configured content filter off. Commit signature display is off and terminal prompts are
|
|
9395
|
+
* disabled; the command is killed after {@link LOCALE_HISTORY_TIMEOUT_MS} and may write at most
|
|
9396
|
+
* {@link LOCALE_HISTORY_MAX_OUTPUT_BYTES}.
|
|
8411
9397
|
*
|
|
8412
9398
|
* @param input - The config, the project directory, and the optional commit limit.
|
|
8413
9399
|
* @param deps - Optional process runner override.
|
|
8414
9400
|
* @returns The commits, or `available: false` with a {@link LocaleHistoryUnavailableReason} when
|
|
8415
|
-
* git is missing, `cwd` is not inside a git repository
|
|
8416
|
-
*
|
|
9401
|
+
* git is missing, `cwd` is not inside a git repository or holds a bare one, git refused the
|
|
9402
|
+
* repository's ownership, the repository configures a content filter that cannot be switched off,
|
|
9403
|
+
* a partial clone needs a newer git, or `git log` timed out or wrote too much. Any other git
|
|
9404
|
+
* failure, such as a branch with no commits yet, reads as an empty history.
|
|
8417
9405
|
*
|
|
8418
9406
|
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
8419
9407
|
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
@@ -8744,6 +9732,76 @@ interface LocaleValuesPageInput extends LocaleValuesInput {
|
|
|
8744
9732
|
*/
|
|
8745
9733
|
declare function localeValuesPage(input: LocaleValuesPageInput, deps?: LocaleValuesDeps): Promise<LocaleValuesPage>;
|
|
8746
9734
|
|
|
9735
|
+
/** The files that hold one locale's data. */
|
|
9736
|
+
interface LocaleWatchFiles {
|
|
9737
|
+
/** The locale. */
|
|
9738
|
+
readonly locale: string;
|
|
9739
|
+
/** The absolute path of the locale's file, then the files next to it that hold part of its data, such as the `.stringsdict` file of `apple-strings`. */
|
|
9740
|
+
readonly paths: readonly string[];
|
|
9741
|
+
}
|
|
9742
|
+
/**
|
|
9743
|
+
* The files git rewrites when the checked-out commit changes: `available: false` with a reason when
|
|
9744
|
+
* the project is not in a readable work tree, otherwise their absolute paths.
|
|
9745
|
+
*/
|
|
9746
|
+
type LocaleWatchGitPaths = {
|
|
9747
|
+
/** `false`: the repository could not be read. */
|
|
9748
|
+
readonly available: false;
|
|
9749
|
+
/** Why the repository could not be read. */
|
|
9750
|
+
readonly reason: LocaleGitRepositoryUnavailableReason;
|
|
9751
|
+
} | {
|
|
9752
|
+
/** `true`: the repository was read. */
|
|
9753
|
+
readonly available: true;
|
|
9754
|
+
/** Absolute paths of this work tree's index, `HEAD` and `HEAD` reflog, in that order. */
|
|
9755
|
+
readonly paths: readonly string[];
|
|
9756
|
+
};
|
|
9757
|
+
/** The result of {@link localeWatchPaths}. */
|
|
9758
|
+
interface LocaleWatchPathsResult {
|
|
9759
|
+
/** Every configured locale with its files, source locale first. */
|
|
9760
|
+
readonly locales: readonly LocaleWatchFiles[];
|
|
9761
|
+
/** The files git rewrites on a commit, a branch switch, a reset or a staging operation. */
|
|
9762
|
+
readonly git: LocaleWatchGitPaths;
|
|
9763
|
+
}
|
|
9764
|
+
/** Input for {@link localeWatchPaths}. */
|
|
9765
|
+
interface LocaleWatchPathsInput {
|
|
9766
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
9767
|
+
readonly config: VerbatraConfig;
|
|
9768
|
+
/** Directory the `files.pattern` is resolved against and git runs in. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory; pass `cwd` from {@link resolveProjectRoot} for a copied config. */
|
|
9769
|
+
readonly cwd?: string;
|
|
9770
|
+
}
|
|
9771
|
+
/** Injectable dependencies for {@link localeWatchPaths}. Every field has a working default. */
|
|
9772
|
+
interface LocaleWatchPathsDeps {
|
|
9773
|
+
/** Runs `git`. Defaults to a real `child_process.execFile`. */
|
|
9774
|
+
readonly execFile?: GitExecFile;
|
|
9775
|
+
}
|
|
9776
|
+
/**
|
|
9777
|
+
* Names the files a watcher needs to notice that what {@link localeGitStatus} reports has changed:
|
|
9778
|
+
* each configured locale's file with the files next to it that hold part of its data (the
|
|
9779
|
+
* `.stringsdict` file of `apple-strings`), and the files git rewrites when a commit, a branch
|
|
9780
|
+
* switch, a reset or a staging operation moves the checked-out state. It reads paths and writes
|
|
9781
|
+
* nothing; git is asked where this work tree keeps its index, `HEAD` and `HEAD` reflog, which also
|
|
9782
|
+
* answers for a linked work tree and a repository whose git directory lives elsewhere. The command
|
|
9783
|
+
* safeguards of {@link localeGitStatus} apply. A project outside a work tree still gets its locale
|
|
9784
|
+
* files, with `git.available: false`.
|
|
9785
|
+
*
|
|
9786
|
+
* @param input - The config and the project directory.
|
|
9787
|
+
* @param deps - Optional process runner override.
|
|
9788
|
+
* @returns The locale files and the git paths.
|
|
9789
|
+
*
|
|
9790
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
9791
|
+
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
9792
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
9793
|
+
*
|
|
9794
|
+
* @example
|
|
9795
|
+
* ```ts
|
|
9796
|
+
* import { loadConfig, localeWatchPaths } from "@verbatra/sdk";
|
|
9797
|
+
*
|
|
9798
|
+
* const config = await loadConfig();
|
|
9799
|
+
* const watch = await localeWatchPaths({ config });
|
|
9800
|
+
* console.log(watch.locales, watch.git);
|
|
9801
|
+
* ```
|
|
9802
|
+
*/
|
|
9803
|
+
declare function localeWatchPaths(input: LocaleWatchPathsInput, deps?: LocaleWatchPathsDeps): Promise<LocaleWatchPathsResult>;
|
|
9804
|
+
|
|
8747
9805
|
/** One locale's lock-file baseline and the drift measured against it. */
|
|
8748
9806
|
interface LockLocaleState {
|
|
8749
9807
|
/** The target locale this entry describes. */
|
|
@@ -9408,6 +10466,68 @@ type ReviewQueueResult = {
|
|
|
9408
10466
|
*/
|
|
9409
10467
|
declare function reviewQueue(input: ReviewQueueInput, deps?: ReviewQueueDeps): Promise<ReviewQueueResult>;
|
|
9410
10468
|
|
|
10469
|
+
/** How many records {@link runHistory} returns when `limit` is left out. */
|
|
10470
|
+
declare const RUN_HISTORY_DEFAULT_LIMIT = 50;
|
|
10471
|
+
/** The most records {@link runHistory} returns, whatever `limit` asks for. */
|
|
10472
|
+
declare const RUN_HISTORY_MAX_LIMIT = 200;
|
|
10473
|
+
/** Input for {@link runHistory}. */
|
|
10474
|
+
interface RunHistoryInput {
|
|
10475
|
+
/**
|
|
10476
|
+
* Directory holding the `.verbatra-local` directory. Defaults to the process working directory,
|
|
10477
|
+
* even when the config was found in a parent directory: pass the root {@link resolveProjectRoot}
|
|
10478
|
+
* returns.
|
|
10479
|
+
*/
|
|
10480
|
+
readonly cwd?: string;
|
|
10481
|
+
/**
|
|
10482
|
+
* How many of the newest records to return. A value below 1 returns one record, a value above
|
|
10483
|
+
* 200 returns 200, and a value that is not a number returns the default of 50.
|
|
10484
|
+
*/
|
|
10485
|
+
readonly limit?: number;
|
|
10486
|
+
}
|
|
10487
|
+
/** Injectable dependencies for {@link runHistory}. Every field has a working default. */
|
|
10488
|
+
interface RunHistoryDeps {
|
|
10489
|
+
/** File-system port. Defaults to the real file system. */
|
|
10490
|
+
readonly fs?: SdkFs;
|
|
10491
|
+
}
|
|
10492
|
+
/** The outcome of {@link runHistory}. */
|
|
10493
|
+
interface RunHistoryResult {
|
|
10494
|
+
/** The newest records first, at most `limit` of them. */
|
|
10495
|
+
readonly records: readonly RunHistoryRecord[];
|
|
10496
|
+
/** How many readable records the file holds, which can exceed the number returned. */
|
|
10497
|
+
readonly total: number;
|
|
10498
|
+
/**
|
|
10499
|
+
* How many lines of the file could not be read: not JSON, not the record shape, over 16 KiB, or
|
|
10500
|
+
* written by a newer verbatra. They are left out of `records`, and the next recorded run rewrites
|
|
10501
|
+
* the file without them.
|
|
10502
|
+
*/
|
|
10503
|
+
readonly unreadableRecords: number;
|
|
10504
|
+
/**
|
|
10505
|
+
* Set when the whole file could not be read, so `records` is empty for that reason and not
|
|
10506
|
+
* because no run was recorded. Absent when the file was read, or does not exist yet.
|
|
10507
|
+
*/
|
|
10508
|
+
readonly unavailable?: RunHistoryUnavailableReason | undefined;
|
|
10509
|
+
}
|
|
10510
|
+
/**
|
|
10511
|
+
* Reads the local run history that finished {@link translate}, {@link watch},
|
|
10512
|
+
* {@link retranslateEntry} and {@link retranslateEntries} runs leave in
|
|
10513
|
+
* `.verbatra-local/run-history.jsonl`: per run the time, trigger, provider, token usage, the cost
|
|
10514
|
+
* frozen at the rates the config held then, and per locale the counts and, when measured, the
|
|
10515
|
+
* coverage. It writes nothing and calls no provider.
|
|
10516
|
+
*
|
|
10517
|
+
* A record holds counts only, never a key name or a translation. A dry run is not recorded, and
|
|
10518
|
+
* neither is a run that left no trace: every locale succeeded and nothing was translated, served
|
|
10519
|
+
* from the cache, reused, generated, pruned, refused or failed, and no tokens were spent. A run
|
|
10520
|
+
* that failed or was refused records too. The file keeps the newest 1,000 records. The read is
|
|
10521
|
+
* total: a missing file is an empty history, an unreadable or oversized (over 8 MiB) file is an
|
|
10522
|
+
* empty history with `unavailable` set, and a single bad line, one that is not valid UTF-8
|
|
10523
|
+
* included, is dropped and counted in `unreadableRecords`, so this call throws nothing.
|
|
10524
|
+
*
|
|
10525
|
+
* @param input - The optional working directory and record limit.
|
|
10526
|
+
* @param deps - Optional file-system override.
|
|
10527
|
+
* @returns The newest records, how many the file holds, and how many lines could not be read.
|
|
10528
|
+
*/
|
|
10529
|
+
declare function runHistory(input?: RunHistoryInput, deps?: RunHistoryDeps): Promise<RunHistoryResult>;
|
|
10530
|
+
|
|
9411
10531
|
/**
|
|
9412
10532
|
* One locale's entry in a persisted {@link RunStatusFile}. It is a deliberately narrow projection
|
|
9413
10533
|
* of {@link LocaleSummary}: only the parts a later session still needs, namely the outcome, the
|
|
@@ -9549,6 +10669,87 @@ declare function runStatus(input?: RunStatusInput, deps?: RunStatusDeps): Promis
|
|
|
9549
10669
|
*/
|
|
9550
10670
|
declare function assertTargetLocale(config: Pick<VerbatraConfig, "targetLocales">, locale: string): void;
|
|
9551
10671
|
|
|
10672
|
+
/** Input for {@link setKeyLengthLimit}. */
|
|
10673
|
+
interface SetKeyLengthLimitInput {
|
|
10674
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
10675
|
+
readonly config: VerbatraConfig;
|
|
10676
|
+
/** Directory the `files.pattern` and `verbatra.limits.json` are resolved against. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory. */
|
|
10677
|
+
readonly cwd?: string;
|
|
10678
|
+
/** The key to limit. Must exist in the source resource, and the config's `maxLength` must not set it. */
|
|
10679
|
+
readonly key: string;
|
|
10680
|
+
/** The most characters a value of the key may have, a whole number of at least 1, or `null` to remove the key's entry from the limits file. */
|
|
10681
|
+
readonly maxLength: number | null;
|
|
10682
|
+
/**
|
|
10683
|
+
* How long, in milliseconds, to wait for the project's limits write lock before failing with
|
|
10684
|
+
* `LOCK_CONTENDED`. Defaults to ten minutes.
|
|
10685
|
+
*/
|
|
10686
|
+
readonly lockAcquireTimeoutMs?: number;
|
|
10687
|
+
}
|
|
10688
|
+
/** Injectable dependencies for {@link setKeyLengthLimit}. Every field has a working default. */
|
|
10689
|
+
interface SetKeyLengthLimitDeps {
|
|
10690
|
+
/** Format-adapter registry to resolve the configured format. Defaults to the built-in registry. */
|
|
10691
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
10692
|
+
/** File-system port. Defaults to the real file system. */
|
|
10693
|
+
readonly fs?: SdkFs;
|
|
10694
|
+
}
|
|
10695
|
+
/** What {@link setKeyLengthLimit} did. */
|
|
10696
|
+
interface SetKeyLengthLimitResult {
|
|
10697
|
+
/** The key the call was about. */
|
|
10698
|
+
readonly key: string;
|
|
10699
|
+
/** The limit the file now holds for the key, `null` when it holds none. */
|
|
10700
|
+
readonly maxLength: number | null;
|
|
10701
|
+
/** `false` when the file already held exactly this and nothing was written. */
|
|
10702
|
+
readonly changed: boolean;
|
|
10703
|
+
}
|
|
10704
|
+
/**
|
|
10705
|
+
* Sets, changes, or removes one key's length limit in `verbatra.limits.json`, the file beside the
|
|
10706
|
+
* lock file that holds limits the config does not. A limit is advisory: a value over it is flagged
|
|
10707
|
+
* `MAX_LENGTH_EXCEEDED` for review and never refused.
|
|
10708
|
+
*
|
|
10709
|
+
* The key must exist in the source resource, and a limit for a key the config's own `maxLength`
|
|
10710
|
+
* sets is refused, because the config wins and the file could not change anything for it. Passing
|
|
10711
|
+
* `null` removes the key's entry from the file, whatever the config says, also for a key that has
|
|
10712
|
+
* since left the source or while the source cannot be read, so a stale or shadowed entry can be
|
|
10713
|
+
* cleaned up. The file is written sorted, with a final newline.
|
|
10714
|
+
*
|
|
10715
|
+
* The whole read-modify-write runs under a project-wide limits lock, so two concurrent calls, from
|
|
10716
|
+
* this process or another, are serialized and neither update is lost, and the file is replaced
|
|
10717
|
+
* atomically. A call that leaves the file as it is succeeds and writes nothing. A file that cannot
|
|
10718
|
+
* be read as a limits file is never overwritten.
|
|
10719
|
+
*
|
|
10720
|
+
* @param input - The config, the key, and the limit or `null`.
|
|
10721
|
+
* @param deps - Optional adapter registry and file-system overrides.
|
|
10722
|
+
* @returns The key, the limit the file holds for it afterwards, and whether anything was written.
|
|
10723
|
+
*
|
|
10724
|
+
* @throws {@link SdkError} `LENGTH_LIMIT_INVALID`: the key is empty or longer than 1024 characters,
|
|
10725
|
+
* the limit is not a whole number from 1 to `Number.MAX_SAFE_INTEGER` or `null`, the limit is a
|
|
10726
|
+
* number and the config's `maxLength` sets the key, or the write would take the file past 10,000
|
|
10727
|
+
* entries or 1 MiB. The first three are thrown before anything is read or locked.
|
|
10728
|
+
* @throws {@link SdkError} `LOCK_TIMEOUT_INVALID`: `lockAcquireTimeoutMs` is not a whole number of
|
|
10729
|
+
* milliseconds of at least 0. Thrown before anything is read or locked.
|
|
10730
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`: no adapter is registered for the configured format.
|
|
10731
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
10732
|
+
* cannot be combined, or the locale has no valid path spelling under that style.
|
|
10733
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
10734
|
+
* @throws {@link SdkError} `SOURCE_UNREADABLE`: the source locale file does not exist.
|
|
10735
|
+
* @throws {@link SdkError} `SOURCE_INVALID`: the source locale file could not be parsed.
|
|
10736
|
+
* @throws {@link SdkError} `UNKNOWN_KEY`: the key is not present in the source resource and the
|
|
10737
|
+
* file holds no entry of that name to remove.
|
|
10738
|
+
* @throws {@link SdkError} `LOCK_CONTENDED`: the project's limits write lock could not be acquired
|
|
10739
|
+
* before the timeout elapsed, could not be reclaimed from an abandoned holder, or was taken over by
|
|
10740
|
+
* another process before the file was written.
|
|
10741
|
+
* @throws {@link SdkError} `RUN_CANCELLED`: {@link releaseHeldLocks} was running when the call
|
|
10742
|
+
* went to take the write lock, so that lock was refused.
|
|
10743
|
+
* @throws {@link SdkError} `LIMITS_FILE_UNUSABLE`: the limits file cannot be used (not a
|
|
10744
|
+
* regular file, over 1 MiB, not UTF-8 or JSON, another shape, a newer version, or more than 10,000 entries). Nothing
|
|
10745
|
+
* is overwritten.
|
|
10746
|
+
* @throws {@link SdkError} `LIMITS_FILE_UNWRITABLE`: the limits file exists but the process may not read
|
|
10747
|
+
* it (a permissions problem), or it or the limits lock could not be written, or the lock could not be
|
|
10748
|
+
* released after the limit was saved, which the message says. A write failure carries the
|
|
10749
|
+
* file-system error as its `cause`.
|
|
10750
|
+
*/
|
|
10751
|
+
declare function setKeyLengthLimit(input: SetKeyLengthLimitInput, deps?: SetKeyLengthLimitDeps): Promise<SetKeyLengthLimitResult>;
|
|
10752
|
+
|
|
9552
10753
|
/**
|
|
9553
10754
|
* The zod 4 schema for a {@link LocaleSummary}, one locale of a {@link RunSummary}. `parse`
|
|
9554
10755
|
* accepts fields it does not list and strips them from its result.
|
|
@@ -9602,6 +10803,7 @@ declare const localeSummarySchema: z.ZodObject<{
|
|
|
9602
10803
|
}, z.core.$strip>, z.ZodObject<{
|
|
9603
10804
|
code: z.ZodEnum<{
|
|
9604
10805
|
PLURAL_CATEGORIES_INCOMPLETE: "PLURAL_CATEGORIES_INCOMPLETE";
|
|
10806
|
+
LIMITS_FILE_IGNORED: "LIMITS_FILE_IGNORED";
|
|
9605
10807
|
SUB_BATCH_FAILED: "SUB_BATCH_FAILED";
|
|
9606
10808
|
BLANK_ROW_BASELINE_RETAINED: "BLANK_ROW_BASELINE_RETAINED";
|
|
9607
10809
|
HANDOFF_REVIEWS_RECORDED: "HANDOFF_REVIEWS_RECORDED";
|
|
@@ -9743,6 +10945,7 @@ declare const runSummarySchema: z.ZodObject<{
|
|
|
9743
10945
|
}, z.core.$strip>, z.ZodObject<{
|
|
9744
10946
|
code: z.ZodEnum<{
|
|
9745
10947
|
PLURAL_CATEGORIES_INCOMPLETE: "PLURAL_CATEGORIES_INCOMPLETE";
|
|
10948
|
+
LIMITS_FILE_IGNORED: "LIMITS_FILE_IGNORED";
|
|
9746
10949
|
SUB_BATCH_FAILED: "SUB_BATCH_FAILED";
|
|
9747
10950
|
BLANK_ROW_BASELINE_RETAINED: "BLANK_ROW_BASELINE_RETAINED";
|
|
9748
10951
|
HANDOFF_REVIEWS_RECORDED: "HANDOFF_REVIEWS_RECORDED";
|
|
@@ -10827,6 +12030,308 @@ declare function resolveDryRun(input: {
|
|
|
10827
12030
|
*/
|
|
10828
12031
|
declare function translate(input: TranslateInput, deps?: TranslateDeps): Promise<RunSummary>;
|
|
10829
12032
|
|
|
12033
|
+
/**
|
|
12034
|
+
* What {@link previewValueReplace} says about one value. `ready` and `stale-source` can be applied.
|
|
12035
|
+
* `stale-source` marks a key whose source text changed since its translation was recorded: a
|
|
12036
|
+
* replacement still applies, but the key stays reported as out of date. `gate-refused` carries the
|
|
12037
|
+
* integrity rule the replaced value would break. `pinned` is a key matching the config's
|
|
12038
|
+
* `pinnedKeys`. `protected` is a value a person wrote, imported, or changed outside verbatra, or
|
|
12039
|
+
* any value when the provenance file cannot be read. `no-source-entry` is a key with no source
|
|
12040
|
+
* text to check the new value against, such as an orphan or a generated plural form. `unchanged`
|
|
12041
|
+
* is a value the replacement would leave as it is. `too-long` is a value the replacement would
|
|
12042
|
+
* grow past 20,000 characters; it is not an integrity refusal and carries no `reason`.
|
|
12043
|
+
*/
|
|
12044
|
+
type ValueReplaceStatus = "ready" | "stale-source" | "gate-refused" | "pinned" | "protected" | "no-source-entry" | "unchanged" | "too-long";
|
|
12045
|
+
/** One matched value in a {@link ValueReplacePreview}. */
|
|
12046
|
+
interface ValueReplacePreviewEntry {
|
|
12047
|
+
/** The target locale the value is in. */
|
|
12048
|
+
readonly locale: string;
|
|
12049
|
+
/** The key. */
|
|
12050
|
+
readonly key: string;
|
|
12051
|
+
/** Whether and how the replacement would apply. */
|
|
12052
|
+
readonly status: ValueReplaceStatus;
|
|
12053
|
+
/**
|
|
12054
|
+
* Present, and `true`, only on a `pinned` entry whose value is also protected (a person wrote,
|
|
12055
|
+
* imported, or changed it outside verbatra, or the provenance file cannot be read). Such a key is
|
|
12056
|
+
* applied only when both `includePinned` and `includeProtected` are set. Absent otherwise.
|
|
12057
|
+
*/
|
|
12058
|
+
readonly protected?: true;
|
|
12059
|
+
/** The integrity rule the replaced value would break. Present only for `gate-refused`. */
|
|
12060
|
+
readonly reason?: IntegrityGateReason;
|
|
12061
|
+
/** What is behind a `gate-refused` reason, as {@link EditEntryResult} reports it. Absent otherwise. */
|
|
12062
|
+
readonly details?: readonly string[];
|
|
12063
|
+
/**
|
|
12064
|
+
* The hash of the current value, the one the provenance record stores. Pass it back in
|
|
12065
|
+
* {@link ApplyValueReplaceInput.entries} so {@link applyValueReplace} can tell whether the value
|
|
12066
|
+
* changed since this preview. It is not the salted marker {@link approveEntry} takes, and it is
|
|
12067
|
+
* blind to a change that only differs in Unicode normalization or line endings.
|
|
12068
|
+
*/
|
|
12069
|
+
readonly valueHash: string;
|
|
12070
|
+
/** Up to 200 characters of the current value around the first match. */
|
|
12071
|
+
readonly before: string;
|
|
12072
|
+
/** Up to 200 characters of the replaced value from the same position. Empty when the replaced value would exceed 20,000 characters. */
|
|
12073
|
+
readonly after: string;
|
|
12074
|
+
/** True when `before` or `after` is shorter than the value it comes from. */
|
|
12075
|
+
readonly excerptCut: boolean;
|
|
12076
|
+
}
|
|
12077
|
+
/** The result of {@link previewValueReplace}. */
|
|
12078
|
+
interface ValueReplacePreview {
|
|
12079
|
+
/** Matched values, by locale in the config's `targetLocales` order whatever order `locales` names them in, and by key in file order, at most 1,000. */
|
|
12080
|
+
readonly entries: readonly ValueReplacePreviewEntry[];
|
|
12081
|
+
/** True when more values matched than the 1,000 listed. */
|
|
12082
|
+
readonly truncated: boolean;
|
|
12083
|
+
/** How many of {@link ValueReplacePreview.entries} have each status. */
|
|
12084
|
+
readonly counts: Readonly<Record<ValueReplaceStatus, number>>;
|
|
12085
|
+
/**
|
|
12086
|
+
* True when the lock file is corrupt, oversized, or from a newer verbatra, so no value could be
|
|
12087
|
+
* compared with its recorded source text and none is reported as `stale-source`. Absent
|
|
12088
|
+
* otherwise, including when there is no lock file.
|
|
12089
|
+
*/
|
|
12090
|
+
readonly baselineUnavailable?: true;
|
|
12091
|
+
}
|
|
12092
|
+
interface ValueReplaceFindInput {
|
|
12093
|
+
/** The resolved project config, normally from {@link loadConfig}. */
|
|
12094
|
+
readonly config: VerbatraConfig;
|
|
12095
|
+
/** Directory the `files.pattern` is resolved against. Defaults to the project root of the config object {@link loadConfig} returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from {@link resolveProjectRoot}. */
|
|
12096
|
+
readonly cwd?: string;
|
|
12097
|
+
/** The text to find, matched literally in target values only: 1 to 20,000 characters, with no unpaired surrogate. */
|
|
12098
|
+
readonly find: string;
|
|
12099
|
+
/** The text to put in its place, inserted exactly as given, with no unpaired surrogate. `$&`, `$1` and the like have no special meaning. */
|
|
12100
|
+
readonly replace: string;
|
|
12101
|
+
/** Whether letter case must match. Defaults to `true`. */
|
|
12102
|
+
readonly caseSensitive?: boolean;
|
|
12103
|
+
}
|
|
12104
|
+
/** Input for {@link previewValueReplace}. */
|
|
12105
|
+
interface PreviewValueReplaceInput extends ValueReplaceFindInput {
|
|
12106
|
+
/** The target locales to search. Defaults to every configured target locale. */
|
|
12107
|
+
readonly locales?: readonly string[];
|
|
12108
|
+
}
|
|
12109
|
+
/** One value to change in {@link ApplyValueReplaceInput.entries}. */
|
|
12110
|
+
interface ValueReplaceEntryRef {
|
|
12111
|
+
/** The target locale the value is in. */
|
|
12112
|
+
readonly locale: string;
|
|
12113
|
+
/** The key. */
|
|
12114
|
+
readonly key: string;
|
|
12115
|
+
/** The `valueHash` {@link previewValueReplace} returned for the value. */
|
|
12116
|
+
readonly valueHash: string;
|
|
12117
|
+
}
|
|
12118
|
+
/** Input for {@link applyValueReplace}. */
|
|
12119
|
+
interface ApplyValueReplaceInput extends ValueReplaceFindInput {
|
|
12120
|
+
/** The values to change, as {@link previewValueReplace} listed them. Their locales must be configured target locales. */
|
|
12121
|
+
readonly entries: readonly ValueReplaceEntryRef[];
|
|
12122
|
+
/** Also change keys that match the config's `pinnedKeys`. Ignored when `actor` is `agent`. Defaults to `false`. */
|
|
12123
|
+
readonly includePinned?: boolean;
|
|
12124
|
+
/** Also change values a person wrote, imported, or changed outside verbatra. Defaults to `false`. */
|
|
12125
|
+
readonly includeProtected?: boolean;
|
|
12126
|
+
/**
|
|
12127
|
+
* Who is making the change, recorded as the origin of every changed value in the provenance
|
|
12128
|
+
* file. The calling surface asserts it; nothing verifies it.
|
|
12129
|
+
*/
|
|
12130
|
+
readonly actor: EditEntryActor;
|
|
12131
|
+
/** Called while waiting on another process's write lock for a locale. */
|
|
12132
|
+
readonly onLockWait?: LockWaitListener;
|
|
12133
|
+
/** How long, in milliseconds, to wait for each locale's write lock before failing with `LOCK_CONTENDED`. Defaults to ten minutes. */
|
|
12134
|
+
readonly lockAcquireTimeoutMs?: number;
|
|
12135
|
+
}
|
|
12136
|
+
/** Injectable dependencies for {@link previewValueReplace} and {@link applyValueReplace}. Every field has a working default. */
|
|
12137
|
+
interface ValueReplaceDeps {
|
|
12138
|
+
/** Format-adapter registry to resolve the configured format. Defaults to the built-in registry. */
|
|
12139
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
12140
|
+
/** File-system port. Defaults to the real file system. */
|
|
12141
|
+
readonly fs?: SdkFs;
|
|
12142
|
+
}
|
|
12143
|
+
/** Why {@link applyValueReplace} left a value alone. */
|
|
12144
|
+
type ValueReplaceSkipReason = "pinned" | "protected" | "no-source-entry" | "unchanged" | "duplicate-entry" | "locale-failed";
|
|
12145
|
+
/** A locale {@link applyValueReplace} could not finish. */
|
|
12146
|
+
interface ValueReplaceLocaleFailure {
|
|
12147
|
+
/** The locale that failed. */
|
|
12148
|
+
readonly locale: string;
|
|
12149
|
+
/** The failure's own code where it has one, and `LOCALE_FAILED` otherwise. */
|
|
12150
|
+
readonly code: string;
|
|
12151
|
+
/** What went wrong, with file paths relative to the project. Never carries a translation value. */
|
|
12152
|
+
readonly message: string;
|
|
12153
|
+
/**
|
|
12154
|
+
* True when the failure came after the locale file was written, while the lock file or the
|
|
12155
|
+
* provenance file was updated or the write lock was released. The accepted values are then on disk
|
|
12156
|
+
* and reported `applied`, and the lock file or provenance record may lag behind them, so review the
|
|
12157
|
+
* locale before any retry. Absent when nothing was written for the locale.
|
|
12158
|
+
*/
|
|
12159
|
+
readonly fileWritten?: true;
|
|
12160
|
+
}
|
|
12161
|
+
/** What {@link applyValueReplace} did with one entry. */
|
|
12162
|
+
type ValueReplaceOutcome = {
|
|
12163
|
+
readonly locale: string;
|
|
12164
|
+
readonly key: string;
|
|
12165
|
+
readonly status: "applied";
|
|
12166
|
+
/** True when the key's source text had changed since its translation was recorded, so it still reads as out of date. */
|
|
12167
|
+
readonly staleSource: boolean;
|
|
12168
|
+
} | {
|
|
12169
|
+
readonly locale: string;
|
|
12170
|
+
readonly key: string;
|
|
12171
|
+
readonly status: "skipped";
|
|
12172
|
+
readonly reason: ValueReplaceSkipReason;
|
|
12173
|
+
} | {
|
|
12174
|
+
readonly locale: string;
|
|
12175
|
+
readonly key: string;
|
|
12176
|
+
readonly status: "refused";
|
|
12177
|
+
/** The integrity rule the replaced value broke. */
|
|
12178
|
+
readonly reason: IntegrityGateReason;
|
|
12179
|
+
readonly details?: readonly string[];
|
|
12180
|
+
} | {
|
|
12181
|
+
readonly locale: string;
|
|
12182
|
+
readonly key: string;
|
|
12183
|
+
/** The value no longer matches the `valueHash`, no longer contains the text, or is gone. Nothing was written. */
|
|
12184
|
+
readonly status: "changed";
|
|
12185
|
+
} | {
|
|
12186
|
+
readonly locale: string;
|
|
12187
|
+
readonly key: string;
|
|
12188
|
+
/** The replaced value would be longer than 20,000 characters. Nothing was written. */
|
|
12189
|
+
readonly status: "too-long";
|
|
12190
|
+
};
|
|
12191
|
+
/** The result of {@link applyValueReplace}. */
|
|
12192
|
+
interface ApplyValueReplaceResult {
|
|
12193
|
+
/** One outcome per entry passed, in the same order. */
|
|
12194
|
+
readonly outcomes: readonly ValueReplaceOutcome[];
|
|
12195
|
+
/** How many outcomes have each status. */
|
|
12196
|
+
readonly counts: Readonly<Record<ValueReplaceOutcome["status"], number>>;
|
|
12197
|
+
/** The locales that failed, in the order they were processed. Empty when every locale finished. */
|
|
12198
|
+
readonly localeFailures: readonly ValueReplaceLocaleFailure[];
|
|
12199
|
+
}
|
|
12200
|
+
/**
|
|
12201
|
+
* Lists the values that a literal find-and-replace would change, and says for each whether it
|
|
12202
|
+
* would apply. It reads target locale values only, never the source locale, writes nothing, and
|
|
12203
|
+
* calls no provider.
|
|
12204
|
+
*
|
|
12205
|
+
* Matching is literal and compares UTF-16 text as it is stored: no pattern syntax, no Unicode
|
|
12206
|
+
* normalization, and no line-ending translation, so an NFD `find` does not match an NFC value and
|
|
12207
|
+
* `\n` does not match `\r\n`. With `caseSensitive: false` letters are compared by their lower-case
|
|
12208
|
+
* form, one character at a time. A match never starts or ends inside a surrogate pair. The
|
|
12209
|
+
* replacement is inserted as given.
|
|
12210
|
+
*
|
|
12211
|
+
* Every candidate value is held to the same integrity gate as an edit, against its current source
|
|
12212
|
+
* text, so a replacement that drops a placeholder, breaks markup or ICU syntax, blanks the value,
|
|
12213
|
+
* or runs away into a repetition-dominated value is listed as `gate-refused`. For the ICU formats
|
|
12214
|
+
* (next-intl and ARB) the replacement is also refused as `gate-refused` with the reason `icu` when
|
|
12215
|
+
* it changes what an argument does: an argument's type, a number or date style or skeleton, or how
|
|
12216
|
+
* many `#` a plural arm holds, compared with the current value, or with the source text when the
|
|
12217
|
+
* current value is not valid ICU. An argument renamed away from the source text is refused as
|
|
12218
|
+
* `placeholder`. The `details` list each difference, prefixed `-` for what the compared value had
|
|
12219
|
+
* and `+` for what the replaced value has. A replaced value longer than 20,000 characters is listed as `too-long`, which is not an
|
|
12220
|
+
* integrity refusal and carries no `reason`. Keys that
|
|
12221
|
+
* match `pinnedKeys`, and values a person wrote, imported, or changed outside verbatra, are listed
|
|
12222
|
+
* as `pinned` and `protected` whatever the config's `humanEdits` says (a key that is both is
|
|
12223
|
+
* listed as `pinned` with `protected: true`), and every value counts as
|
|
12224
|
+
* protected when the provenance file cannot be read, which includes a file from a newer verbatra:
|
|
12225
|
+
* that file is never rewritten, and a value changed with `includeProtected` gets no record in it. A
|
|
12226
|
+
* key whose source text changed since its translation was recorded is `stale-source`, and its
|
|
12227
|
+
* replacement is checked against the current source text.
|
|
12228
|
+
*
|
|
12229
|
+
* At most 1,000 matched values are listed, `truncated` says when there were more, and each
|
|
12230
|
+
* excerpt is at most 200 characters. The preview is advisory: {@link applyValueReplace} decides
|
|
12231
|
+
* again, under the write lock, from the values on disk at that moment.
|
|
12232
|
+
*
|
|
12233
|
+
* @param input - The config, locales, and the find and replace text.
|
|
12234
|
+
* @param deps - Optional adapter registry and file-system overrides.
|
|
12235
|
+
* @returns The matched values with a status each, a truncation flag, and counts per status.
|
|
12236
|
+
*
|
|
12237
|
+
* @throws {@link SdkError} `FIND_TEXT_INVALID`: `find` is empty or longer than 20,000 characters, or
|
|
12238
|
+
* `find` or `replace` holds an unpaired surrogate.
|
|
12239
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`: no adapter is registered for the configured format.
|
|
12240
|
+
* @throws {@link SdkError} `UNKNOWN_LOCALE`: a requested locale is not a configured target locale.
|
|
12241
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
12242
|
+
* cannot be combined, or a configured locale has no valid path spelling under that style.
|
|
12243
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
12244
|
+
* @throws {@link SdkError} `SOURCE_UNREADABLE`: the source locale file does not exist.
|
|
12245
|
+
* @throws {@link SdkError} `SOURCE_INVALID`: the source locale file could not be parsed.
|
|
12246
|
+
* @throws `AdapterError`: the adapter refused a target locale file because it is malformed. Its
|
|
12247
|
+
* own code is preserved rather than remapped onto an {@link SdkErrorCode}.
|
|
12248
|
+
*
|
|
12249
|
+
* @example
|
|
12250
|
+
* ```ts
|
|
12251
|
+
* import { loadConfig, previewValueReplace } from "@verbatra/sdk";
|
|
12252
|
+
*
|
|
12253
|
+
* const config = await loadConfig();
|
|
12254
|
+
* const preview = await previewValueReplace({ config, find: "Colour", replace: "Color" });
|
|
12255
|
+
* const ready = preview.entries.filter((entry) => entry.status === "ready");
|
|
12256
|
+
* ```
|
|
12257
|
+
*/
|
|
12258
|
+
declare function previewValueReplace(input: PreviewValueReplaceInput, deps?: ValueReplaceDeps): Promise<ValueReplacePreview>;
|
|
12259
|
+
/**
|
|
12260
|
+
* Replaces literal text in the target values the caller picked from a {@link previewValueReplace}
|
|
12261
|
+
* result. For each entry the server recomputes the new value from `find` and `replace` over the
|
|
12262
|
+
* value currently on disk, inside the locale's write lock; it never takes a computed value from
|
|
12263
|
+
* the caller, so a stale or forged preview cannot write anything the replacement would not.
|
|
12264
|
+
*
|
|
12265
|
+
* Under the lock every entry is decided again. A value whose `valueHash` no longer matches, or
|
|
12266
|
+
* that no longer contains the text, or is gone, is `changed` and nothing is written for it. The
|
|
12267
|
+
* hash ignores Unicode normalization and line endings, so a value that differs from the preview
|
|
12268
|
+
* only that way is replaced when the text still matches, and is `changed` when it no longer does.
|
|
12269
|
+
* A key with no source text, and a replacement that leaves the value as it is, are `skipped`. A
|
|
12270
|
+
* pinned key is `skipped` unless `includePinned` is set and `actor` is `human`; an agent never
|
|
12271
|
+
* changes a pinned key. A value that is protected as {@link previewValueReplace} describes it is
|
|
12272
|
+
* `skipped` unless `includeProtected` is set, and this holds whatever `humanEdits` the config
|
|
12273
|
+
* sets, so a key that is both pinned and protected needs both options. A value the integrity gate
|
|
12274
|
+
* refuses is `refused`, with its reason. Everything else is written.
|
|
12275
|
+
*
|
|
12276
|
+
* Locales are processed one after another, each under its own write lock, with one write of the
|
|
12277
|
+
* locale file, one update of the lock-file and provenance file, and one translation-memory update
|
|
12278
|
+
* for all of that locale's values. A key whose source text changed since its translation was
|
|
12279
|
+
* recorded keeps its old lock-file hash, so {@link check} still reports it out of date, and its
|
|
12280
|
+
* value is not added to the translation memory. Every written value gets a fresh provenance
|
|
12281
|
+
* record with `actor` as its origin and no review decision, whatever it had before.
|
|
12282
|
+
*
|
|
12283
|
+
* A locale that fails does not stop the others. Failures that only one locale's own processing
|
|
12284
|
+
* can cause, such as `LOCK_CONTENDED` when its write lock is not free within `lockAcquireTimeoutMs`,
|
|
12285
|
+
* `TARGET_UNWRITABLE`, `LOCALE_STATE_NOT_CARRIED_OVER`, `RUN_CANCELLED`, `SOURCE_UNREADABLE` and
|
|
12286
|
+
* `SOURCE_INVALID` (the source file is read before any locale is touched and again under each locale's
|
|
12287
|
+
* lock), or an `AdapterError` from its file, are recorded in `localeFailures`. An entry the
|
|
12288
|
+
* integrity gate refused still comes back `refused`, and one a check had settled before the failure
|
|
12289
|
+
* keeps its outcome; the rest come back `skipped` with the reason `locale-failed`, and nothing was
|
|
12290
|
+
* written for them. When the failure came after the locale file was written, such as a failed lock
|
|
12291
|
+
* file or provenance update or a write lock that could not be released, the failure carries `fileWritten: true` and the
|
|
12292
|
+
* accepted entries come back `applied`: their values are on disk and the lock file or provenance may
|
|
12293
|
+
* lag, so review the locale before any retry. Do not run a replacement again whose `find` occurs in
|
|
12294
|
+
* its `replace` without checking, because it would change the written values a second time. The
|
|
12295
|
+
* wait for the lock file's own guard uses the default of ten minutes, not `lockAcquireTimeoutMs`.
|
|
12296
|
+
*
|
|
12297
|
+
* Entries are grouped by locale in the order each locale first appears in `entries`. When the same
|
|
12298
|
+
* `locale` and `key` appear more than once, the first one decides: it is processed whatever its
|
|
12299
|
+
* `valueHash` is, and every later one is `skipped` with the reason `duplicate-entry`.
|
|
12300
|
+
*
|
|
12301
|
+
* @param input - The config, the find and replace text, the entries, and the actor.
|
|
12302
|
+
* @param deps - Optional adapter registry and file-system overrides.
|
|
12303
|
+
* @returns One outcome per entry, in order, counts per status, and the locales that failed.
|
|
12304
|
+
*
|
|
12305
|
+
* @throws {@link SdkError} `FIND_TEXT_INVALID`: `find` is empty or longer than 20,000 characters, or
|
|
12306
|
+
* `find` or `replace` holds an unpaired surrogate.
|
|
12307
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`: no adapter is registered for the configured format.
|
|
12308
|
+
* @throws {@link SdkError} `UNKNOWN_LOCALE`: an entry names a locale that is not a configured target
|
|
12309
|
+
* locale. Thrown before anything is written.
|
|
12310
|
+
* @throws {@link SdkError} `LOCALE_LAYOUT_INVALID`: the `files.pattern` and `files.localeStyle`
|
|
12311
|
+
* cannot be combined, or a locale has no valid path spelling under that style.
|
|
12312
|
+
* @throws {@link SdkError} `LOCALE_PATH_COLLISION`: two configured locales resolve to the same path.
|
|
12313
|
+
* @throws {@link SdkError} `LOCK_TIMEOUT_INVALID`: `lockAcquireTimeoutMs` is not a whole number of
|
|
12314
|
+
* milliseconds of at least 0. Thrown before anything is read or locked.
|
|
12315
|
+
* @throws {@link SdkError} `LOCK_FILE_INVALID`: the lock-file is corrupt, oversized, or at an
|
|
12316
|
+
* unsupported version. Checked before anything is written.
|
|
12317
|
+
* @throws {@link SdkError} `PROVENANCE_FILE_INVALID`: the provenance file is corrupt, oversized, or
|
|
12318
|
+
* structurally wrong. Checked before anything is written.
|
|
12319
|
+
*
|
|
12320
|
+
* @example
|
|
12321
|
+
* ```ts
|
|
12322
|
+
* import { applyValueReplace, loadConfig, previewValueReplace } from "@verbatra/sdk";
|
|
12323
|
+
*
|
|
12324
|
+
* const config = await loadConfig();
|
|
12325
|
+
* const criteria = { config, find: "Colour", replace: "Color" };
|
|
12326
|
+
* const preview = await previewValueReplace(criteria);
|
|
12327
|
+
* const entries = preview.entries
|
|
12328
|
+
* .filter((entry) => entry.status === "ready")
|
|
12329
|
+
* .map(({ locale, key, valueHash }) => ({ locale, key, valueHash }));
|
|
12330
|
+
* const result = await applyValueReplace({ ...criteria, entries, actor: "human" });
|
|
12331
|
+
* ```
|
|
12332
|
+
*/
|
|
12333
|
+
declare function applyValueReplace(input: ApplyValueReplaceInput, deps?: ValueReplaceDeps): Promise<ApplyValueReplaceResult>;
|
|
12334
|
+
|
|
10830
12335
|
/**
|
|
10831
12336
|
* The two XLIFF handoff shapes: `xliff2` writes XLIFF 2.0 and `xliff12` writes XLIFF 1.2, for a
|
|
10832
12337
|
* CAT tool that does not read 2.0 yet. On import both read either version, which is taken from the
|
|
@@ -10930,6 +12435,12 @@ interface ExportWorkbookResult {
|
|
|
10930
12435
|
* newer verbatra (`unavailable`). The export itself succeeds either way.
|
|
10931
12436
|
*/
|
|
10932
12437
|
readonly provenanceMarkers?: ProvenanceMarkers;
|
|
12438
|
+
/**
|
|
12439
|
+
* Present when `verbatra.limits.json` could not be used, so the `max-length-exceeded` review
|
|
12440
|
+
* reasons in the handoff were judged against the config's `maxLength` budgets alone. The export
|
|
12441
|
+
* itself succeeds.
|
|
12442
|
+
*/
|
|
12443
|
+
readonly limitsNotice?: LimitsFileNotice;
|
|
10933
12444
|
}
|
|
10934
12445
|
/**
|
|
10935
12446
|
* Writes the strings awaiting translation to a handoff a human translator can work in: a styled
|
|
@@ -10966,6 +12477,9 @@ interface ExportWorkbookResult {
|
|
|
10966
12477
|
* written surfaces as `EXPORT_UNWRITABLE`, never as a raw file-system error. An existing file at
|
|
10967
12478
|
* the output path is replaced.
|
|
10968
12479
|
*
|
|
12480
|
+
* A `verbatra.limits.json` that cannot be used is ignored, so only the config's `maxLength`
|
|
12481
|
+
* budgets apply, and the result's `limitsNotice` says so; {@link doctor} names the problem.
|
|
12482
|
+
*
|
|
10969
12483
|
* @param input - The config, output path, config and glossary paths to protect, locale filter, and
|
|
10970
12484
|
* handoff format.
|
|
10971
12485
|
* @param deps - Optional adapter registry and file-system overrides.
|
|
@@ -11008,6 +12522,10 @@ declare const exportWorkbookResultSchema: z.ZodObject<{
|
|
|
11008
12522
|
written: "written";
|
|
11009
12523
|
unavailable: "unavailable";
|
|
11010
12524
|
}>>;
|
|
12525
|
+
limitsNotice: z.ZodExactOptional<z.ZodObject<{
|
|
12526
|
+
code: z.ZodLiteral<"LIMITS_FILE_IGNORED">;
|
|
12527
|
+
message: z.ZodString;
|
|
12528
|
+
}, z.core.$strip>>;
|
|
11011
12529
|
}, z.core.$strip>;
|
|
11012
12530
|
|
|
11013
12531
|
/** Input for {@link importWorkbook}. */
|
|
@@ -11076,10 +12594,12 @@ interface ImportWorkbookDeps {
|
|
|
11076
12594
|
* Imported values are held to the same integrity gate as provider output, so a translator who drops
|
|
11077
12595
|
* a placeholder, breaks inline markup or breaks ICU syntax has that row refused rather than
|
|
11078
12596
|
* written, and a row whose source text changed since the export is refused the same way. A row
|
|
11079
|
-
* holding exactly `[[CLEAR]]` empties that key's translation.
|
|
11080
|
-
*
|
|
11081
|
-
*
|
|
11082
|
-
*
|
|
12597
|
+
* holding exactly `[[CLEAR]]` empties that key's translation. In a CSV, TSV or xlsx file, a filled
|
|
12598
|
+
* row equal to the value an up-to-date key already holds is left alone and reported unchanged once
|
|
12599
|
+
* it passes the same gate. Each locale takes its write lock, and the lock-file and translation
|
|
12600
|
+
* memory are updated exactly as in a {@link translate} run, so an imported translation counts as up
|
|
12601
|
+
* to date afterwards. Each accepted row is recorded in the provenance file with the origin
|
|
12602
|
+
* `import`.
|
|
11083
12603
|
*
|
|
11084
12604
|
* Damage is contained rather than fatal: a blank row keeps the existing translation and its
|
|
11085
12605
|
* baseline, an unreadable row is reported as a {@link MalformedRowReport}, and a repeated key is
|
|
@@ -11828,5 +13348,5 @@ interface WatchController {
|
|
|
11828
13348
|
*/
|
|
11829
13349
|
declare function watch(input: WatchInput, deps?: WatchDeps): Promise<WatchController>;
|
|
11830
13350
|
|
|
11831
|
-
export { AdapterError, AdapterRegistry, BatchInterruptedError, CACHE_FILE_NAME, DATA_FLOW_MANIFEST_VERSION, DEFAULT_DELIMITED_PATH, DEFAULT_EXCHANGE_FORMAT, DEFAULT_TMX_PATH, DEFAULT_TYPES_PATH, DEFAULT_WORKBOOK_PATH, EXCHANGE_FORMATS, INTEGRITY_GATE_REASONS, JSON_SCHEMA_BASE_URL, KNOWN_ERROR_CODES, LOCALE_HISTORY_LIMIT_CAP, LOCALE_HISTORY_LIMIT_DEFAULT, LOCALE_HISTORY_MAX_OUTPUT_BYTES, LOCALE_HISTORY_TIMEOUT_MS, LOCALE_HISTORY_UNAVAILABLE_REASONS, LOCALE_VALUES_QUERY_MAX_LENGTH, LOCK_FILE_NAME, MACHINE_CLASS_ORIGINS, PAGE_CURSOR_MAX_LENGTH, PAGE_LIMIT_CAP, PAGE_LIMIT_DEFAULT, PROVENANCE_BUCKETS, PROVENANCE_FILE_NAME, PSEUDO_MODES, ProviderError, QA_SEVERITIES, REVIEW_REASON_CODES, RUN_STATUS_UNAVAILABLE_REASONS, SDK_JSON_SCHEMAS, SdkError, approveEntries, approveEntry, approveLocale, assertMachineTranslationEnabled, assertTargetLocale, budgetStanding, check, checkFile, checkFileSummarySchema, checkSummarySchema, configCandidatePaths, createDefaultRegistry, createFlatFileAdapter, createLocalePathResolver, createTreeFileAdapter, createValueMarker, dataFlow, dataFlowManifestSchema, declareProviderKeyEnvVar, defineConfig, detectProject, diff, diffLocaleSnapshots, diffSummarySchema, doctor, doctorResultSchema, editConfiguredGlossaryTerm, editEntry, errorHint, exportTmx, exportTmxResultSchema, exportWorkbook, exportWorkbookResultSchema, extract, extractResultSchema, generateTypes, generateTypesResultSchema, glossaryDraftCheck, glossaryForLocale, glossaryHits, importTmx, importTmxResultSchema, importWorkbook, isCustomFormatId, isMachineTranslationEnabled, jsonSchemaUrl, keyContext, keyIntegrity, keyOriginSchema, keyProvenanceSchema, keyValue, loadConfig, loadConfigWithMeta, loadLockFile, loadProvenance, localeHistory, localeIntegrity, localeSummarySchema, localeValues, localeValuesPage, lockState, lockWaitEventSchema, nodeAdapterFs, normalizeGlossary, progressEventSchema, projectRelativeMessage, provenanceReport, provenanceReportPage, provenanceReportResultSchema, provenanceSummarySchema, pseudolocalize, pseudolocalizeResultSchema, readCurrentGlossary, readGlossaryFile, readLocaleFileSnapshot, redact, redactGlossary, rejectEntries, rejectEntry, releaseHeldLocks, renderJsonSchemas, renderOutputJsonSchema, resolveDryRun, resolveProjectRoot, retranslateEntries, retranslateEntry, reviewQueue, runStatus, runSummarySchema, scaffoldingMetadata, sharedGlossaryTranslations, tmxErrorLocation, translate, updateGlossaryTerm, verbatraConfigSchema, watch };
|
|
11832
|
-
export type { AdapterErrorCode, AdapterFs, AdapterResolution, AddedKey, ApproveLocaleDeps, ApproveLocaleInput, ApproveLocaleResult, AuthoringConfig, AuthoringConfigFor, BatchEntry, BatchEntryFailure, BatchEntrySkipped, BatchFinishedEvent, BillingUnit, BoundedBytesRead, BoundedFileRead, BoundedReadOutcome, BudgetBehavior, BudgetStanding, BuildWriteTree, ChangeDetectedEvent, CharacterRate, CharacterRunQuantity, CheckDeps, CheckFileDeps, CheckFileFinding, CheckFileInput, CheckFileRole, CheckFileSummary, CheckInput, CheckQaSummary, CheckReviewCode, CheckReviewSummary, CheckSensitiveSummary, CheckSummary, CompareBranchArms, ComparePlaceholders, ComputeInvalidIcuKeys, ConfigCandidateOptions, ConfigSource, CreateProvider, CreateProviderContext, CreateProviderHooks, CreateWatcher, CustomFormatId, DataFlowAgentSurface, DataFlowApiKey, DataFlowCounts, DataFlowDeps, DataFlowDestination, DataFlowField, DataFlowInput, DataFlowLocalFile, DataFlowLocale, DataFlowManifest, DataFlowNetwork, DataFlowOtherRequest, DataFlowProvider, DataFlowProviderKind, DataFlowSent, DataFlowVerdict, DeriveDescriptions, DeriveEntry, DetectProjectDeps, DetectProjectInput, DetectedFormat, DetectedFormatSource, DetectedLocaleLayout, DetectionAmbiguity, DetectionConfidence, DiffDeps, DiffInput, DiffSummary, DirectoryEntry, DoNotTranslateTerm, DoctorCheck, DoctorCheckId, DoctorCheckStatus, DoctorDeps, DoctorInput, DoctorResult, DuplicateKeyReport, EditConfiguredGlossaryTermInput, EditEntryActor, EditEntryDeps, EditEntryInput, EditEntryResult, EstimateCaveatCode, EstimateIdentity, EstimatePricing, ExchangeFormat, ExportTmxDeps, ExportTmxInput, ExportTmxLocaleCount, ExportTmxResult, ExportWorkbookDeps, ExportWorkbookInput, ExportWorkbookResult, ExtractDeps, ExtractInput, ExtractPlaceholders, ExtractResult, ExtractionConfig, FileQaReport, FlatFileAdapterOptions, FlatParseOutcome, FlatParseResult, FormatAdapter, FormatId, FuzzyCacheHit, GenerateTypesDeps, GenerateTypesInput, GenerateTypesResult, GitExecFile, GitExecFileResult, Glossary, GlossaryConfig, GlossaryDefinition, GlossaryDoNotTranslateDefinition, GlossaryDraftCheck, GlossaryDraftCheckInput, GlossaryDraftDoNotTranslateCheck, GlossaryDraftTermCheck, GlossaryFileDeps, GlossaryFileInput, GlossaryHitsInput, GlossaryInput, GlossaryProvenance, GlossaryTerm, GlossaryTermDefinition, HumanEditsPolicy, IdleEvent, ImportTmxDeps, ImportTmxInput, ImportTmxLocaleResult, ImportTmxResult, ImportWorkbookDeps, ImportWorkbookInput, IncompletePlural, InconsistencyGroup, InconsistentTranslation, IntegrityGateReason, IntegrityRefusal, JsonLeaf, JsonRecord, JsonSchemaDocument, JsonSchemaObject, JsonTree, KeyConflict, KeyContext, KeyContextDeps, KeyContextGlossaryNotice, KeyContextInput, KeyIntegrityDeps, KeyIntegrityEntry, KeyIntegrityInput, KeyMode, KeyOrigin, KeyProvenance, KeyReviewState, KeyValueDeps, KeyValueInput, KeyValuePair, KeyValueResult, LanguageTableRefresh, LanguageTableRefreshStatus, LiteralFinding, LiteralScan, LiteralSuppressionReason, LoadConfigOptions, LoadLockFileDeps, LoadLockFileInput, LoadProvenanceDeps, LoadProvenanceInput, LoadedConfig, LocaleCapability, LocaleCapabilityReport, LocaleCapabilityWarning, LocaleCapabilityWarningCode, LocaleCheckSummary, LocaleDiff, LocaleEstimate, LocaleEstimateQuantity, LocaleFileCheck, LocaleFileSnapshot, LocaleFinishedEvent, LocaleGlossary, LocaleGlossaryTerm, LocaleHistoryCommit, LocaleHistoryDeps, LocaleHistoryInput, LocaleHistoryResult, LocaleHistoryUnavailableReason, LocaleIntegrityDeps, LocaleIntegrityInput, LocaleKeyIntegrity, LocaleNotice, LocalePathResolver, LocalePathResolverConfig, LocalePlannedEvent, LocaleQaReport, LocaleResource, LocaleReviewReport, LocaleSnapshotDelta, LocaleStartedEvent, LocaleStyle, LocaleSummary, LocaleSupport, LocaleValues, LocaleValuesDeps, LocaleValuesInput, LocaleValuesPage, LocaleValuesPageEntry, LocaleValuesPageInput, LocaleValuesPageLocale, LockFile, LockHolder, LockLocaleState, LockStateDeps, LockStateInput, LockStateResult, LockWaitEvent, LockWaitListener, MachineClassOrigin, MalformedRowReport, ModelRate, NeedsReviewEntry, NetworkPolicy, NetworkRule, OrderedRecord, OrderedValue, PlaceholderComparator, PlaceholderExtractor, PlaceholderIntegrityResult, PluralCategories, PluralCategory, PluralCategoryLookup, PluralRuleType, PossiblyDynamicKey, PricedLocaleEstimate, PricedRunEstimate, ProgressEvent, ProgressListener, ProjectDetection, ProtectedKey, ProtectionReason, ProvenanceBucket, ProvenanceFile, ProvenanceMarkers, ProvenanceOrigin, ProvenanceRecord, ProvenanceReport, ProvenanceReportDeps, ProvenanceReportEntry, ProvenanceReportInput, ProvenanceReportLocale, ProvenanceReportPage, ProvenanceReportPageInput, ProvenanceReportPageLocale, ProvenanceReportPageResult, ProvenanceReportResult, ProvenanceReviewState, ProvenanceSummary, ProviderBilling, ProviderConfig, ProviderErrorCode, ProviderId, ProviderKind, ProviderNetwork, ProviderNotice, ProviderNoticeCode, ProviderRetry, ProviderRetryEvent, ProviderRetryListener, PseudoMode, PseudolocalizeDeps, PseudolocalizeInput, PseudolocalizeResult, QaFinding, QaIntegrityFinding, QaReviewFinding, QaSeverity, QaSyntaxFinding, RateCard, ReadCurrentGlossaryInput, ReadLocaleFileSnapshotDeps, ReadLocaleFileSnapshotInput, ReadResult, RedactedGlossary, RepairEvent, ResolveOptions, RetranslateBatchOutcome, RetranslateEntriesInput, RetranslateEntriesResult, RetranslateEntryDeps, RetranslateEntryInput, RetranslateEntryResult, ReviewBatchEntry, ReviewBatchOutcome, ReviewDecisionDeps, ReviewDecisionInput, ReviewDecisionResult, ReviewEntriesInput, ReviewEntriesResult, ReviewFlag, ReviewQueueDeps, ReviewQueueEntry, ReviewQueueInput, ReviewQueueLocale, ReviewQueueResult, ReviewReasonCode, RunBudget, RunEstimate, RunEstimateQuantity, RunFinishedEvent, RunStatusDeps, RunStatusFile, RunStatusInput, RunStatusLocale, RunStatusResult, RunStatusUnavailableReason, RunSummary, RunTranslate, ScaffoldableProviderId, ScanDiagnostic, ScanDiagnosticReason, ScanProgressEvent, ScanProgressListener, SdkErrorCode, SdkFs, SdkNotice, SdkNoticeCode, SensitiveField, SensitiveFindingSource, SensitiveKeyFinding, Sniff, SourceExtractor, SourceFramework, SourceLocaleCapability, SourceLocation, SplitRetryEvent, SubBatchProgressEvent, SuggestionStatus, SupportedFormat, SuppressedLiteral, SyntaxPosition, TmxErrorLocation, TmxLanguageReport, TmxOrigin, TmxRejectionCounts, TmxRejectionReason, TmxReview, TmxUnitRefusal, TokenRate, TokenRunQuantity, Tone, TranslateDeps, TranslateInput, TranslateRequest, TranslateResult, TranslationEntry, TranslationMemory, TranslationProvider, TreeFileAdapterOptions, UnpricedLocaleEstimate, UnpricedRunEstimate, UnresolvedArgumentReason, UnresolvedMessage, UnusedKey, UnusedKeysNotRun, UnusedKeysNotRunReason, UnusedKeysPrefixSite, UnusedKeysReport, UnusedKeysScan, UnusedKeysSite, UnusedKeysUnreliability, UnusedKeysUnreliableReason, UpdateGlossaryTermInput, Usage, UsageSummary, ValidateMessage, ValidateTree, ValueMarker, VerbatraConfig, VerbatraConfigInput, WatchController, WatchDeps, WatchInput, WatchRunResult, Watcher, WriteContext, WritingEvent, XliffFormat };
|
|
13351
|
+
export { AdapterError, AdapterRegistry, BatchInterruptedError, CACHE_FILE_NAME, DATA_FLOW_MANIFEST_VERSION, DEFAULT_DELIMITED_PATH, DEFAULT_EXCHANGE_FORMAT, DEFAULT_TMX_PATH, DEFAULT_TYPES_PATH, DEFAULT_WORKBOOK_PATH, EXCHANGE_FORMATS, INTEGRITY_GATE_REASONS, JSON_SCHEMA_BASE_URL, KEY_HISTORY_DEADLINE_MS, KEY_HISTORY_MAX_KEY_CHARS, KEY_HISTORY_MAX_VALUE_CHARS, KEY_HISTORY_TRUNCATION_REASONS, KNOWN_ERROR_CODES, LOCALE_GIT_BLOB_MAX_BYTES, LOCALE_GIT_DIFF_MAX_ENTRIES, LOCALE_GIT_DIFF_MAX_VALUE_CHARS, LOCALE_GIT_FILE_STATES, LOCALE_GIT_MAX_OUTPUT_BYTES, LOCALE_GIT_TIMEOUT_MS, LOCALE_GIT_UNAVAILABLE_REASONS, LOCALE_HISTORY_LIMIT_CAP, LOCALE_HISTORY_LIMIT_DEFAULT, LOCALE_HISTORY_MAX_OUTPUT_BYTES, LOCALE_HISTORY_TIMEOUT_MS, LOCALE_HISTORY_UNAVAILABLE_REASONS, LOCALE_VALUES_QUERY_MAX_LENGTH, LOCK_FILE_NAME, MACHINE_CLASS_ORIGINS, PAGE_CURSOR_MAX_LENGTH, PAGE_LIMIT_CAP, PAGE_LIMIT_DEFAULT, PROVENANCE_BUCKETS, PROVENANCE_FILE_NAME, PSEUDO_MODES, ProviderError, QA_SEVERITIES, REVIEW_REASON_CODES, RUN_COST_BASES, RUN_HISTORY_DEFAULT_LIMIT, RUN_HISTORY_MAX_LIMIT, RUN_HISTORY_UNAVAILABLE_REASONS, RUN_STATUS_UNAVAILABLE_REASONS, SDK_JSON_SCHEMAS, SdkError, applyValueReplace, approveEntries, approveEntry, approveLocale, assertMachineTranslationEnabled, assertTargetLocale, budgetStanding, check, checkFile, checkFileSummarySchema, checkSummarySchema, configCandidatePaths, createDefaultRegistry, createFlatFileAdapter, createLocalePathResolver, createTreeFileAdapter, createValueMarker, dataFlow, dataFlowManifestSchema, declareProviderKeyEnvVar, defineConfig, detectProject, diff, diffLocaleSnapshots, diffSummarySchema, doctor, doctorResultSchema, editConfiguredGlossaryTerm, editEntry, errorHint, exportTmx, exportTmxResultSchema, exportWorkbook, exportWorkbookResultSchema, extract, extractResultSchema, generateTypes, generateTypesResultSchema, glossaryDraftCheck, glossaryForLocale, glossaryHits, importTmx, importTmxResultSchema, importWorkbook, isCustomFormatId, isMachineTranslationEnabled, jsonSchemaUrl, keyContext, keyHistory, keyIntegrity, keyOriginSchema, keyProvenanceSchema, keyValue, loadConfig, loadConfigWithMeta, loadLockFile, loadProvenance, localeGitDiff, localeGitStatus, localeHistory, localeIntegrity, localeSummarySchema, localeValues, localeValuesPage, localeWatchPaths, lockState, lockWaitEventSchema, nodeAdapterFs, normalizeGlossary, previewIcuMessage, previewValueReplace, progressEventSchema, projectRelativeMessage, provenanceReport, provenanceReportPage, provenanceReportResultSchema, provenanceSummarySchema, pseudolocalize, pseudolocalizeResultSchema, readCurrentGlossary, readGlossaryFile, readLocaleFileSnapshot, redact, redactGlossary, rejectEntries, rejectEntry, releaseHeldLocks, renderJsonSchemas, renderOutputJsonSchema, resolveDryRun, resolveProjectRoot, retranslateEntries, retranslateEntry, reviewQueue, runHistory, runHistoryResultSchema, runStatus, runSummarySchema, scaffoldingMetadata, setKeyLengthLimit, sharedGlossaryTranslations, tmxErrorLocation, translate, updateGlossaryTerm, verbatraConfigSchema, watch };
|
|
13352
|
+
export type { AdapterErrorCode, AdapterFs, AdapterResolution, AddedKey, ApplyValueReplaceInput, ApplyValueReplaceResult, ApproveLocaleDeps, ApproveLocaleInput, ApproveLocaleResult, AuthoringConfig, AuthoringConfigFor, BatchEntry, BatchEntryFailure, BatchEntrySkipped, BatchFinishedEvent, BillingUnit, BoundedBytesRead, BoundedFileRead, BoundedReadOutcome, BudgetBehavior, BudgetStanding, BuildWriteTree, ChangeDetectedEvent, CharacterRate, CharacterRunQuantity, CheckDeps, CheckFileDeps, CheckFileFinding, CheckFileInput, CheckFileRole, CheckFileSummary, CheckInput, CheckQaSummary, CheckReviewCode, CheckReviewSummary, CheckSensitiveSummary, CheckSummary, CompareBranchArms, ComparePlaceholders, ComputeInvalidIcuKeys, ConfigCandidateOptions, ConfigSource, CreateProvider, CreateProviderContext, CreateProviderHooks, CreateWatcher, CustomFormatId, DataFlowAgentSurface, DataFlowApiKey, DataFlowCounts, DataFlowDeps, DataFlowDestination, DataFlowField, DataFlowInput, DataFlowLocalFile, DataFlowLocale, DataFlowManifest, DataFlowNetwork, DataFlowOtherRequest, DataFlowProvider, DataFlowProviderKind, DataFlowSent, DataFlowVerdict, DeriveDescriptions, DeriveEntry, DetectProjectDeps, DetectProjectInput, DetectedFormat, DetectedFormatSource, DetectedLocaleLayout, DetectionAmbiguity, DetectionConfidence, DiffDeps, DiffInput, DiffSummary, DirectoryEntry, DoNotTranslateTerm, DoctorCheck, DoctorCheckId, DoctorCheckStatus, DoctorDeps, DoctorInput, DoctorResult, DuplicateKeyReport, EditConfiguredGlossaryTermInput, EditEntryActor, EditEntryDeps, EditEntryInput, EditEntryResult, EstimateCaveatCode, EstimateIdentity, EstimatePricing, ExchangeFormat, ExportTmxDeps, ExportTmxInput, ExportTmxLocaleCount, ExportTmxResult, ExportWorkbookDeps, ExportWorkbookInput, ExportWorkbookResult, ExtractDeps, ExtractInput, ExtractPlaceholders, ExtractResult, ExtractionConfig, FileQaReport, FlatFileAdapterOptions, FlatParseOutcome, FlatParseResult, FormatAdapter, FormatId, FuzzyCacheHit, GenerateTypesDeps, GenerateTypesInput, GenerateTypesResult, GitExecFile, GitExecFileResult, Glossary, GlossaryConfig, GlossaryDefinition, GlossaryDoNotTranslateDefinition, GlossaryDraftCheck, GlossaryDraftCheckInput, GlossaryDraftDoNotTranslateCheck, GlossaryDraftTermCheck, GlossaryFileDeps, GlossaryFileInput, GlossaryHitsInput, GlossaryInput, GlossaryProvenance, GlossaryTerm, GlossaryTermDefinition, HumanEditsPolicy, IcuPreviewAxis, IcuPreviewFailure, IcuPreviewInput, IcuPreviewResult, IcuPreviewRow, IcuSegment, IcuSegmentKind, IdleEvent, ImportTmxDeps, ImportTmxInput, ImportTmxLocaleResult, ImportTmxResult, ImportWorkbookDeps, ImportWorkbookInput, IncompletePlural, InconsistencyGroup, InconsistentTranslation, IntegrityGateReason, IntegrityRefusal, JsonLeaf, JsonRecord, JsonSchemaDocument, JsonSchemaObject, JsonTree, KeyConflict, KeyContext, KeyContextDeps, KeyContextGlossaryNotice, KeyContextInput, KeyHistoryDeps, KeyHistoryInput, KeyHistoryResult, KeyHistorySegment, KeyHistorySegmentKind, KeyHistoryTruncation, KeyIntegrityDeps, KeyIntegrityEntry, KeyIntegrityInput, KeyMode, KeyOrigin, KeyProvenance, KeyReviewState, KeyRevision, KeyValueDeps, KeyValueInput, KeyValuePair, KeyValueResult, KeyWorkingTreeValue, LanguageTableRefresh, LanguageTableRefreshStatus, LimitsFileNotice, LiteralFinding, LiteralScan, LiteralSuppressionReason, LoadConfigOptions, LoadLockFileDeps, LoadLockFileInput, LoadProvenanceDeps, LoadProvenanceInput, LoadedConfig, LocaleCapability, LocaleCapabilityReport, LocaleCapabilityWarning, LocaleCapabilityWarningCode, LocaleCheckSummary, LocaleDiff, LocaleEstimate, LocaleEstimateQuantity, LocaleFileCheck, LocaleFileSnapshot, LocaleFinishedEvent, LocaleGitDiffChange, LocaleGitDiffDeps, LocaleGitDiffEntry, LocaleGitDiffInput, LocaleGitDiffResult, LocaleGitDiffState, LocaleGitFile, LocaleGitFileState, LocaleGitRepositoryUnavailableReason, LocaleGitStatusDeps, LocaleGitStatusInput, LocaleGitStatusResult, LocaleGitUnavailableReason, LocaleGlossary, LocaleGlossaryTerm, LocaleHistoryCommit, LocaleHistoryDeps, LocaleHistoryInput, LocaleHistoryResult, LocaleHistoryUnavailableReason, LocaleIntegrityDeps, LocaleIntegrityInput, LocaleKeyIntegrity, LocaleNotice, LocalePathResolver, LocalePathResolverConfig, LocalePlannedEvent, LocaleQaReport, LocaleResource, LocaleReviewReport, LocaleSnapshotDelta, LocaleStartedEvent, LocaleStyle, LocaleSummary, LocaleSupport, LocaleValues, LocaleValuesDeps, LocaleValuesInput, LocaleValuesPage, LocaleValuesPageEntry, LocaleValuesPageInput, LocaleValuesPageLocale, LocaleWatchFiles, LocaleWatchGitPaths, LocaleWatchPathsDeps, LocaleWatchPathsInput, LocaleWatchPathsResult, LockFile, LockHolder, LockLocaleState, LockStateDeps, LockStateInput, LockStateResult, LockWaitEvent, LockWaitListener, MachineClassOrigin, MalformedRowReport, MaxLengthSource, MessageArgumentType, MessageArguments, ModelRate, NamedMessageArgument, NeedsReviewEntry, NetworkPolicy, NetworkRule, OrderedRecord, OrderedValue, PlaceholderComparator, PlaceholderExtractor, PlaceholderIntegrityResult, PluralCategories, PluralCategory, PluralCategoryLookup, PluralRuleType, PossiblyDynamicKey, PreviewValueReplaceInput, PricedLocaleEstimate, PricedRunEstimate, ProgressEvent, ProgressListener, ProjectDetection, ProtectedKey, ProtectionReason, ProvenanceBucket, ProvenanceFile, ProvenanceMarkers, ProvenanceOrigin, ProvenanceRecord, ProvenanceReport, ProvenanceReportDeps, ProvenanceReportEntry, ProvenanceReportInput, ProvenanceReportLocale, ProvenanceReportPage, ProvenanceReportPageInput, ProvenanceReportPageLocale, ProvenanceReportPageResult, ProvenanceReportResult, ProvenanceReviewState, ProvenanceSummary, ProviderBilling, ProviderConfig, ProviderErrorCode, ProviderId, ProviderKind, ProviderNetwork, ProviderNotice, ProviderNoticeCode, ProviderRetry, ProviderRetryEvent, ProviderRetryListener, PseudoMode, PseudolocalizeDeps, PseudolocalizeInput, PseudolocalizeResult, QaFinding, QaIntegrityFinding, QaReviewFinding, QaSeverity, QaSyntaxFinding, RateCard, ReadCurrentGlossaryInput, ReadLocaleFileSnapshotDeps, ReadLocaleFileSnapshotInput, ReadResult, RedactedGlossary, RepairEvent, ResolveOptions, RetranslateBatchOutcome, RetranslateEntriesInput, RetranslateEntriesResult, RetranslateEntryDeps, RetranslateEntryInput, RetranslateEntryResult, ReviewBatchEntry, ReviewBatchOutcome, ReviewDecisionDeps, ReviewDecisionInput, ReviewDecisionResult, ReviewEntriesInput, ReviewEntriesResult, ReviewFlag, ReviewQueueDeps, ReviewQueueEntry, ReviewQueueInput, ReviewQueueLocale, ReviewQueueResult, ReviewReasonCode, RunBudget, RunCostBasis, RunCostCaveat, RunEstimate, RunEstimateQuantity, RunFinishedEvent, RunHistoryCost, RunHistoryCoverage, RunHistoryDeps, RunHistoryInput, RunHistoryLocale, RunHistoryRecord, RunHistoryResult, RunHistoryTrigger, RunHistoryUnavailableReason, RunStatusDeps, RunStatusFile, RunStatusInput, RunStatusLocale, RunStatusResult, RunStatusUnavailableReason, RunSummary, RunTranslate, ScaffoldableProviderId, ScanDiagnostic, ScanDiagnosticReason, ScanProgressEvent, ScanProgressListener, SdkErrorCode, SdkFs, SdkNotice, SdkNoticeCode, SensitiveField, SensitiveFindingSource, SensitiveKeyFinding, SetKeyLengthLimitDeps, SetKeyLengthLimitInput, SetKeyLengthLimitResult, Sniff, SourceExtractor, SourceFramework, SourceLocaleCapability, SourceLocation, SplitRetryEvent, SubBatchProgressEvent, SuggestionStatus, SupportedFormat, SuppressedLiteral, SyntaxPosition, TmxErrorLocation, TmxLanguageReport, TmxOrigin, TmxRejectionCounts, TmxRejectionReason, TmxReview, TmxUnitRefusal, TokenRate, TokenRunQuantity, Tone, TranslateDeps, TranslateInput, TranslateRequest, TranslateResult, TranslationEntry, TranslationMemory, TranslationProvider, TreeFileAdapterOptions, UnpricedLocaleEstimate, UnpricedRunEstimate, UnresolvedArgumentReason, UnresolvedMessage, UnusedKey, UnusedKeysNotRun, UnusedKeysNotRunReason, UnusedKeysPrefixSite, UnusedKeysReport, UnusedKeysScan, UnusedKeysSite, UnusedKeysUnreliability, UnusedKeysUnreliableReason, UpdateGlossaryTermInput, Usage, UsageSummary, ValidateMessage, ValidateTree, ValueMarker, ValueReplaceDeps, ValueReplaceEntryRef, ValueReplaceLocaleFailure, ValueReplaceOutcome, ValueReplacePreview, ValueReplacePreviewEntry, ValueReplaceSkipReason, ValueReplaceStatus, VerbatraConfig, VerbatraConfigInput, WatchController, WatchDeps, WatchInput, WatchRunResult, Watcher, WriteContext, WritingEvent, XliffFormat };
|