@verbatra/sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.cjs +669 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -1
- package/dist/index.d.ts +102 -1
- package/dist/index.js +665 -31
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.d.cts
CHANGED
|
@@ -226,6 +226,15 @@ type BoundedFileRead = {
|
|
|
226
226
|
} | {
|
|
227
227
|
readonly kind: "too-large";
|
|
228
228
|
};
|
|
229
|
+
/** Outcome of a bounded binary read: the bytes, or why they could not be read in bounds. */
|
|
230
|
+
type BoundedBytesRead = {
|
|
231
|
+
readonly kind: "ok";
|
|
232
|
+
readonly bytes: Uint8Array;
|
|
233
|
+
} | {
|
|
234
|
+
readonly kind: "missing";
|
|
235
|
+
} | {
|
|
236
|
+
readonly kind: "too-large";
|
|
237
|
+
};
|
|
229
238
|
/**
|
|
230
239
|
* The minimal file-system surface the SDK needs for the lock-file and for existence
|
|
231
240
|
* checks. Injectable so tests stay deterministic; the format adapters do their own
|
|
@@ -241,8 +250,17 @@ interface SdkFs {
|
|
|
241
250
|
* unreadable path is "missing" (first-run); a file over the cap is "too-large".
|
|
242
251
|
*/
|
|
243
252
|
readFileBounded(path: string, maxBytes: number): Promise<BoundedFileRead>;
|
|
253
|
+
/**
|
|
254
|
+
* Read a file as raw bytes through a single handle, bounded to maxBytes, with the SAME
|
|
255
|
+
* TOCTOU-safe discipline as {@link readFileBounded}: the handle is fstat'd and the read never
|
|
256
|
+
* advances past the sized length. Used for the untrusted workbook on import; a file over the
|
|
257
|
+
* cap is "too-large", a missing path is "missing".
|
|
258
|
+
*/
|
|
259
|
+
readBytesBounded(path: string, maxBytes: number): Promise<BoundedBytesRead>;
|
|
244
260
|
/** Write atomically: a temp file in the same directory, then rename over the target. */
|
|
245
261
|
writeFile(path: string, data: string): Promise<void>;
|
|
262
|
+
/** Write raw bytes atomically (temp file, then rename over the target). Used for the workbook. */
|
|
263
|
+
writeBytes(path: string, data: Uint8Array): Promise<void>;
|
|
246
264
|
}
|
|
247
265
|
|
|
248
266
|
/** Builds the provider from its config. Injectable so tests stay offline. */
|
|
@@ -314,6 +332,89 @@ interface TranslateDeps {
|
|
|
314
332
|
*/
|
|
315
333
|
declare function translate(input: TranslateInput, deps?: TranslateDeps): Promise<RunSummary>;
|
|
316
334
|
|
|
335
|
+
/** Default workbook output path, relative to the resolved working directory. */
|
|
336
|
+
declare const DEFAULT_WORKBOOK_PATH = "verbatra-translations.xlsx";
|
|
337
|
+
/** Input for {@link exportWorkbook}: the validated config and where/how to run the export. */
|
|
338
|
+
interface ExportWorkbookInput {
|
|
339
|
+
/** The validated configuration (typically from {@link loadConfig}). */
|
|
340
|
+
readonly config: VerbatraConfig;
|
|
341
|
+
/** Directory the file pattern, lock-file, and output path resolve against; defaults to cwd. */
|
|
342
|
+
readonly cwd?: string;
|
|
343
|
+
/** Output path for the workbook; defaults to {@link DEFAULT_WORKBOOK_PATH} under cwd. */
|
|
344
|
+
readonly out?: string;
|
|
345
|
+
/** Subset of target locales to export; defaults to all configured target locales. */
|
|
346
|
+
readonly locales?: readonly string[];
|
|
347
|
+
/** Include unchanged keys (off by default; export is missing-and-changed only). */
|
|
348
|
+
readonly includeUnchanged?: boolean;
|
|
349
|
+
}
|
|
350
|
+
/** Composition seam for {@link exportWorkbook}: inject a registry and a file system for tests. */
|
|
351
|
+
interface ExportWorkbookDeps {
|
|
352
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
353
|
+
readonly fs?: SdkFs;
|
|
354
|
+
}
|
|
355
|
+
/** The outcome of an export: where it was written and how many rows per locale. */
|
|
356
|
+
interface ExportWorkbookResult {
|
|
357
|
+
/** The absolute path the workbook was written to. */
|
|
358
|
+
readonly path: string;
|
|
359
|
+
/** Per-locale row counts, in config order; the same set the workbook carries. */
|
|
360
|
+
readonly locales: readonly {
|
|
361
|
+
readonly locale: string;
|
|
362
|
+
readonly rows: number;
|
|
363
|
+
}[];
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Export the strings needing human translation into a styled `.xlsx` workbook. Reuses the same
|
|
367
|
+
* source read, adapter selection, and lock baseline the translate flow uses, runs `diffResources`
|
|
368
|
+
* per target locale to pick the rows (missing and changed by default; add unchanged with
|
|
369
|
+
* `includeUnchanged`), hands the neutral row model to `@verbatra/exchange`'s `buildWorkbook`, and
|
|
370
|
+
* writes the bytes through the {@link SdkFs} seam. No provider is called and no lock-file is written.
|
|
371
|
+
*
|
|
372
|
+
* @param input - The validated config and export options.
|
|
373
|
+
* @param deps - Optional composition seams (registry, file system) for tests.
|
|
374
|
+
* @returns Where the workbook was written and the per-locale row counts.
|
|
375
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`, `SOURCE_UNREADABLE`, `SOURCE_INVALID`, `LOCK_FILE_INVALID`
|
|
376
|
+
* with the same meanings as in `translate`.
|
|
377
|
+
*/
|
|
378
|
+
declare function exportWorkbook(input: ExportWorkbookInput, deps?: ExportWorkbookDeps): Promise<ExportWorkbookResult>;
|
|
379
|
+
|
|
380
|
+
/** Input for {@link importWorkbook}: the validated config, the workbook path, and run options. */
|
|
381
|
+
interface ImportWorkbookInput {
|
|
382
|
+
/** The validated configuration (typically from {@link loadConfig}). */
|
|
383
|
+
readonly config: VerbatraConfig;
|
|
384
|
+
/** Path to the filled workbook to import. */
|
|
385
|
+
readonly workbook: string;
|
|
386
|
+
/** Directory the file pattern, lock-file, and workbook path resolve against; defaults to cwd. */
|
|
387
|
+
readonly cwd?: string;
|
|
388
|
+
/** When true, validate and report only: write no locale file and update no lock-file. */
|
|
389
|
+
readonly dryRun?: boolean;
|
|
390
|
+
}
|
|
391
|
+
/** Composition seam for {@link importWorkbook}: inject a registry and a file system for tests. */
|
|
392
|
+
interface ImportWorkbookDeps {
|
|
393
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
394
|
+
readonly fs?: SdkFs;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Import a filled workbook back into the locale files. Reads the untrusted workbook through the
|
|
398
|
+
* SDK's bounded read, parses it with `@verbatra/exchange`'s `readWorkbook` (which bounds and
|
|
399
|
+
* sanitizes it), then for each target-locale data sheet runs the EXISTING core checks (source-drift
|
|
400
|
+
* via `contentHash`, placeholder integrity via `checkPlaceholders`, ICU via the adapter's
|
|
401
|
+
* `validateMessage`), writes the accepted values through the format adapter, and updates the lock
|
|
402
|
+
* through the existing lock logic. Returns a {@link RunSummary} structurally identical to
|
|
403
|
+
* `translate`'s, so the CLI formatter and exit-code rule are shared with no special case.
|
|
404
|
+
*
|
|
405
|
+
* Whole-run failures (unknown format, unreadable/invalid/oversized workbook, corrupt lock) throw a
|
|
406
|
+
* structured {@link SdkError}. A per-sheet failure (a locale not in config, a broken-round-trip key,
|
|
407
|
+
* a write failure) is isolated as that locale's `status: "failed"`, not a throw; per-row rejections
|
|
408
|
+
* are withheld and reported on the locale, exactly as the provider path treats integrity mismatches.
|
|
409
|
+
* `--dry-run` validates and reports without writing any locale or lock file.
|
|
410
|
+
*
|
|
411
|
+
* @param input - The validated config, the workbook path, and run options.
|
|
412
|
+
* @param deps - Optional composition seams (registry, file system) for tests.
|
|
413
|
+
* @returns A {@link RunSummary} with one locale per data sheet, in workbook order.
|
|
414
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`, `SOURCE_UNREADABLE`, `SOURCE_INVALID`, `LOCK_FILE_INVALID`.
|
|
415
|
+
*/
|
|
416
|
+
declare function importWorkbook(input: ImportWorkbookInput, deps?: ImportWorkbookDeps): Promise<RunSummary>;
|
|
417
|
+
|
|
317
418
|
/** A minimal source-change event source. Production wraps chokidar; tests inject a stub. */
|
|
318
419
|
interface Watcher {
|
|
319
420
|
/** Register a listener invoked once per coalesced source-change event. */
|
|
@@ -411,4 +512,4 @@ interface WatchController {
|
|
|
411
512
|
*/
|
|
412
513
|
declare function watch(input: WatchInput, deps?: WatchDeps): Promise<WatchController>;
|
|
413
514
|
|
|
414
|
-
export { type CreateProvider, type CreateWatcher, type LoadConfigOptions, type LocaleSummary, type ProviderConfig, type ProviderId, type RunSummary, type RunTranslate, SdkError, type SdkErrorCode, type SdkFs, type TranslateDeps, type TranslateInput, type VerbatraConfig, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, defineConfig, loadConfig, translate, verbatraConfigSchema, watch };
|
|
515
|
+
export { type CreateProvider, type CreateWatcher, DEFAULT_WORKBOOK_PATH, type ExportWorkbookDeps, type ExportWorkbookInput, type ExportWorkbookResult, type ImportWorkbookDeps, type ImportWorkbookInput, type LoadConfigOptions, type LocaleSummary, type ProviderConfig, type ProviderId, type RunSummary, type RunTranslate, SdkError, type SdkErrorCode, type SdkFs, type TranslateDeps, type TranslateInput, type VerbatraConfig, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, defineConfig, exportWorkbook, importWorkbook, loadConfig, translate, verbatraConfigSchema, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -226,6 +226,15 @@ type BoundedFileRead = {
|
|
|
226
226
|
} | {
|
|
227
227
|
readonly kind: "too-large";
|
|
228
228
|
};
|
|
229
|
+
/** Outcome of a bounded binary read: the bytes, or why they could not be read in bounds. */
|
|
230
|
+
type BoundedBytesRead = {
|
|
231
|
+
readonly kind: "ok";
|
|
232
|
+
readonly bytes: Uint8Array;
|
|
233
|
+
} | {
|
|
234
|
+
readonly kind: "missing";
|
|
235
|
+
} | {
|
|
236
|
+
readonly kind: "too-large";
|
|
237
|
+
};
|
|
229
238
|
/**
|
|
230
239
|
* The minimal file-system surface the SDK needs for the lock-file and for existence
|
|
231
240
|
* checks. Injectable so tests stay deterministic; the format adapters do their own
|
|
@@ -241,8 +250,17 @@ interface SdkFs {
|
|
|
241
250
|
* unreadable path is "missing" (first-run); a file over the cap is "too-large".
|
|
242
251
|
*/
|
|
243
252
|
readFileBounded(path: string, maxBytes: number): Promise<BoundedFileRead>;
|
|
253
|
+
/**
|
|
254
|
+
* Read a file as raw bytes through a single handle, bounded to maxBytes, with the SAME
|
|
255
|
+
* TOCTOU-safe discipline as {@link readFileBounded}: the handle is fstat'd and the read never
|
|
256
|
+
* advances past the sized length. Used for the untrusted workbook on import; a file over the
|
|
257
|
+
* cap is "too-large", a missing path is "missing".
|
|
258
|
+
*/
|
|
259
|
+
readBytesBounded(path: string, maxBytes: number): Promise<BoundedBytesRead>;
|
|
244
260
|
/** Write atomically: a temp file in the same directory, then rename over the target. */
|
|
245
261
|
writeFile(path: string, data: string): Promise<void>;
|
|
262
|
+
/** Write raw bytes atomically (temp file, then rename over the target). Used for the workbook. */
|
|
263
|
+
writeBytes(path: string, data: Uint8Array): Promise<void>;
|
|
246
264
|
}
|
|
247
265
|
|
|
248
266
|
/** Builds the provider from its config. Injectable so tests stay offline. */
|
|
@@ -314,6 +332,89 @@ interface TranslateDeps {
|
|
|
314
332
|
*/
|
|
315
333
|
declare function translate(input: TranslateInput, deps?: TranslateDeps): Promise<RunSummary>;
|
|
316
334
|
|
|
335
|
+
/** Default workbook output path, relative to the resolved working directory. */
|
|
336
|
+
declare const DEFAULT_WORKBOOK_PATH = "verbatra-translations.xlsx";
|
|
337
|
+
/** Input for {@link exportWorkbook}: the validated config and where/how to run the export. */
|
|
338
|
+
interface ExportWorkbookInput {
|
|
339
|
+
/** The validated configuration (typically from {@link loadConfig}). */
|
|
340
|
+
readonly config: VerbatraConfig;
|
|
341
|
+
/** Directory the file pattern, lock-file, and output path resolve against; defaults to cwd. */
|
|
342
|
+
readonly cwd?: string;
|
|
343
|
+
/** Output path for the workbook; defaults to {@link DEFAULT_WORKBOOK_PATH} under cwd. */
|
|
344
|
+
readonly out?: string;
|
|
345
|
+
/** Subset of target locales to export; defaults to all configured target locales. */
|
|
346
|
+
readonly locales?: readonly string[];
|
|
347
|
+
/** Include unchanged keys (off by default; export is missing-and-changed only). */
|
|
348
|
+
readonly includeUnchanged?: boolean;
|
|
349
|
+
}
|
|
350
|
+
/** Composition seam for {@link exportWorkbook}: inject a registry and a file system for tests. */
|
|
351
|
+
interface ExportWorkbookDeps {
|
|
352
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
353
|
+
readonly fs?: SdkFs;
|
|
354
|
+
}
|
|
355
|
+
/** The outcome of an export: where it was written and how many rows per locale. */
|
|
356
|
+
interface ExportWorkbookResult {
|
|
357
|
+
/** The absolute path the workbook was written to. */
|
|
358
|
+
readonly path: string;
|
|
359
|
+
/** Per-locale row counts, in config order; the same set the workbook carries. */
|
|
360
|
+
readonly locales: readonly {
|
|
361
|
+
readonly locale: string;
|
|
362
|
+
readonly rows: number;
|
|
363
|
+
}[];
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Export the strings needing human translation into a styled `.xlsx` workbook. Reuses the same
|
|
367
|
+
* source read, adapter selection, and lock baseline the translate flow uses, runs `diffResources`
|
|
368
|
+
* per target locale to pick the rows (missing and changed by default; add unchanged with
|
|
369
|
+
* `includeUnchanged`), hands the neutral row model to `@verbatra/exchange`'s `buildWorkbook`, and
|
|
370
|
+
* writes the bytes through the {@link SdkFs} seam. No provider is called and no lock-file is written.
|
|
371
|
+
*
|
|
372
|
+
* @param input - The validated config and export options.
|
|
373
|
+
* @param deps - Optional composition seams (registry, file system) for tests.
|
|
374
|
+
* @returns Where the workbook was written and the per-locale row counts.
|
|
375
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`, `SOURCE_UNREADABLE`, `SOURCE_INVALID`, `LOCK_FILE_INVALID`
|
|
376
|
+
* with the same meanings as in `translate`.
|
|
377
|
+
*/
|
|
378
|
+
declare function exportWorkbook(input: ExportWorkbookInput, deps?: ExportWorkbookDeps): Promise<ExportWorkbookResult>;
|
|
379
|
+
|
|
380
|
+
/** Input for {@link importWorkbook}: the validated config, the workbook path, and run options. */
|
|
381
|
+
interface ImportWorkbookInput {
|
|
382
|
+
/** The validated configuration (typically from {@link loadConfig}). */
|
|
383
|
+
readonly config: VerbatraConfig;
|
|
384
|
+
/** Path to the filled workbook to import. */
|
|
385
|
+
readonly workbook: string;
|
|
386
|
+
/** Directory the file pattern, lock-file, and workbook path resolve against; defaults to cwd. */
|
|
387
|
+
readonly cwd?: string;
|
|
388
|
+
/** When true, validate and report only: write no locale file and update no lock-file. */
|
|
389
|
+
readonly dryRun?: boolean;
|
|
390
|
+
}
|
|
391
|
+
/** Composition seam for {@link importWorkbook}: inject a registry and a file system for tests. */
|
|
392
|
+
interface ImportWorkbookDeps {
|
|
393
|
+
readonly adapterRegistry?: AdapterRegistry;
|
|
394
|
+
readonly fs?: SdkFs;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Import a filled workbook back into the locale files. Reads the untrusted workbook through the
|
|
398
|
+
* SDK's bounded read, parses it with `@verbatra/exchange`'s `readWorkbook` (which bounds and
|
|
399
|
+
* sanitizes it), then for each target-locale data sheet runs the EXISTING core checks (source-drift
|
|
400
|
+
* via `contentHash`, placeholder integrity via `checkPlaceholders`, ICU via the adapter's
|
|
401
|
+
* `validateMessage`), writes the accepted values through the format adapter, and updates the lock
|
|
402
|
+
* through the existing lock logic. Returns a {@link RunSummary} structurally identical to
|
|
403
|
+
* `translate`'s, so the CLI formatter and exit-code rule are shared with no special case.
|
|
404
|
+
*
|
|
405
|
+
* Whole-run failures (unknown format, unreadable/invalid/oversized workbook, corrupt lock) throw a
|
|
406
|
+
* structured {@link SdkError}. A per-sheet failure (a locale not in config, a broken-round-trip key,
|
|
407
|
+
* a write failure) is isolated as that locale's `status: "failed"`, not a throw; per-row rejections
|
|
408
|
+
* are withheld and reported on the locale, exactly as the provider path treats integrity mismatches.
|
|
409
|
+
* `--dry-run` validates and reports without writing any locale or lock file.
|
|
410
|
+
*
|
|
411
|
+
* @param input - The validated config, the workbook path, and run options.
|
|
412
|
+
* @param deps - Optional composition seams (registry, file system) for tests.
|
|
413
|
+
* @returns A {@link RunSummary} with one locale per data sheet, in workbook order.
|
|
414
|
+
* @throws {@link SdkError} `UNKNOWN_FORMAT`, `SOURCE_UNREADABLE`, `SOURCE_INVALID`, `LOCK_FILE_INVALID`.
|
|
415
|
+
*/
|
|
416
|
+
declare function importWorkbook(input: ImportWorkbookInput, deps?: ImportWorkbookDeps): Promise<RunSummary>;
|
|
417
|
+
|
|
317
418
|
/** A minimal source-change event source. Production wraps chokidar; tests inject a stub. */
|
|
318
419
|
interface Watcher {
|
|
319
420
|
/** Register a listener invoked once per coalesced source-change event. */
|
|
@@ -411,4 +512,4 @@ interface WatchController {
|
|
|
411
512
|
*/
|
|
412
513
|
declare function watch(input: WatchInput, deps?: WatchDeps): Promise<WatchController>;
|
|
413
514
|
|
|
414
|
-
export { type CreateProvider, type CreateWatcher, type LoadConfigOptions, type LocaleSummary, type ProviderConfig, type ProviderId, type RunSummary, type RunTranslate, SdkError, type SdkErrorCode, type SdkFs, type TranslateDeps, type TranslateInput, type VerbatraConfig, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, defineConfig, loadConfig, translate, verbatraConfigSchema, watch };
|
|
515
|
+
export { type CreateProvider, type CreateWatcher, DEFAULT_WORKBOOK_PATH, type ExportWorkbookDeps, type ExportWorkbookInput, type ExportWorkbookResult, type ImportWorkbookDeps, type ImportWorkbookInput, type LoadConfigOptions, type LocaleSummary, type ProviderConfig, type ProviderId, type RunSummary, type RunTranslate, SdkError, type SdkErrorCode, type SdkFs, type TranslateDeps, type TranslateInput, type VerbatraConfig, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, defineConfig, exportWorkbook, importWorkbook, loadConfig, translate, verbatraConfigSchema, watch };
|