@giveitsmaller/sdk 0.19.0 → 0.20.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/dist/_audit.js +12 -0
- package/dist/builder.d.ts +1 -0
- package/dist/client.d.ts +8 -1
- package/dist/client.js +27 -32
- package/dist/ergonomic/option_types.d.ts +34 -1
- package/dist/ergonomic/option_types.js +5 -1
- package/dist/ergonomic/option_validation.d.ts +19 -1
- package/dist/ergonomic/option_validation.js +34 -1
- package/dist/errors.d.ts +57 -1
- package/dist/errors.js +82 -1
- package/dist/file-first.d.ts +153 -3
- package/dist/file-first.js +417 -115
- package/dist/gisl.d.ts +72 -3
- package/dist/gisl.js +72 -2
- package/dist/index.core.d.ts +8 -6
- package/dist/index.core.js +9 -1
- package/dist/merge.d.ts +12 -0
- package/dist/merge.js +12 -0
- package/dist/retry-metadata.d.ts +37 -0
- package/dist/retry-metadata.js +86 -0
- package/dist/sse.d.ts +2 -1
- package/dist/sse.js +26 -6
- package/dist/types.d.ts +43 -1
- package/package.json +2 -2
package/dist/file-first.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { GislItemFailedError } from './errors.js';
|
|
|
13
13
|
import { type ProgressEvent } from './builder.js';
|
|
14
14
|
import type { GislClient } from './client.js';
|
|
15
15
|
import type { OperationDownload, WorkflowStatusResponse } from '@giveitsmaller/contracts/openapi';
|
|
16
|
-
import type { ConvertOptions, ThumbnailOptions, TextWatermarkOptions, WatermarkOptions, OutputOptions, OutputFit } from './ergonomic/option_types.js';
|
|
16
|
+
import type { ConvertOptions, ThumbnailOptions, TransformOptions, TextWatermarkOptions, WatermarkOptions, OutputOptions, OutputFit } from './ergonomic/option_types.js';
|
|
17
17
|
import { OptimizeFor } from './generated/sdk_spec/enums.js';
|
|
18
18
|
import type { PresetDefaults } from './ergonomic/presets/index.js';
|
|
19
19
|
import type { WorkflowCreatePayload } from './types.js';
|
|
@@ -72,6 +72,19 @@ export interface OutputFile {
|
|
|
72
72
|
* outputs.
|
|
73
73
|
*/
|
|
74
74
|
readonly targetSizeMet?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* The measured perceptual quality of an `auto_quality` encode (0-1). Projected
|
|
77
|
+
* from the generated {@link OperationDownload.measuredQuality}; undefined
|
|
78
|
+
* (omitted) when the worker reported no measurement. Pairs with
|
|
79
|
+
* {@link qualityMetric}, which names the metric it was measured on.
|
|
80
|
+
*/
|
|
81
|
+
readonly measuredQuality?: number;
|
|
82
|
+
/**
|
|
83
|
+
* The metric {@link measuredQuality} was measured on (e.g. `ssimulacra2`).
|
|
84
|
+
* Projected from the generated {@link OperationDownload.qualityMetric};
|
|
85
|
+
* undefined when no measurement was reported.
|
|
86
|
+
*/
|
|
87
|
+
readonly qualityMetric?: string;
|
|
75
88
|
}
|
|
76
89
|
/**
|
|
77
90
|
* One succeeded entry in {@link RunResult.succeeded}: a single input's
|
|
@@ -324,7 +337,7 @@ export declare const fileInput: {
|
|
|
324
337
|
};
|
|
325
338
|
/** One step in a {@link Recipe}'s chain — an op kind + captured ergonomic args. */
|
|
326
339
|
interface RecipeStep {
|
|
327
|
-
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark' | 'output';
|
|
340
|
+
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark' | 'output' | 'transform';
|
|
328
341
|
readonly options: Readonly<Record<string, unknown>>;
|
|
329
342
|
}
|
|
330
343
|
/**
|
|
@@ -378,6 +391,19 @@ export declare class Recipe {
|
|
|
378
391
|
* dropped from the wire options (not sent as `undefined`).
|
|
379
392
|
*/
|
|
380
393
|
thumbnail(options: ThumbnailOptions): Recipe;
|
|
394
|
+
/**
|
|
395
|
+
* Geometric transform: rotate (0/90/180/270°) and/or flip. Chainable — the
|
|
396
|
+
* canonical single-job order is `transform → convert → compress → thumbnail`,
|
|
397
|
+
* so downstream size options refer to the final (post-transform) frame.
|
|
398
|
+
*
|
|
399
|
+
* Passthrough: `rotate`/`flip` are forwarded as-is; the SDK does NOT narrow
|
|
400
|
+
* per media (a `flip` on a PDF input passes SDK validation but the server
|
|
401
|
+
* rejects it — documents rotate only). The transform op is `availability:
|
|
402
|
+
* planned` today, so workflow-create returns `feature_not_available` (422)
|
|
403
|
+
* until the per-media Lambdas ship. A no-op (`rotate:0` + `flip:none`) is
|
|
404
|
+
* rejected server-side as `invalid_options`.
|
|
405
|
+
*/
|
|
406
|
+
transform(options?: TransformOptions): Recipe;
|
|
381
407
|
/**
|
|
382
408
|
* Produce ONE transformed image: keep or change format, plus quality, resize
|
|
383
409
|
* and route-honored controls. The single user-facing image transform — the SDK
|
|
@@ -414,7 +440,8 @@ export declare class Recipe {
|
|
|
414
440
|
* (beta). Audio/document/animated-GIF/unsupported-subtype/undetectable bases
|
|
415
441
|
* throw locally BEFORE any upload (the planned-op gate). `options` carries the
|
|
416
442
|
* wire watermark options (`anchor`, `opacity`, `margin_x`, `margin_y`,
|
|
417
|
-
* `overlay_width`). Returns a
|
|
443
|
+
* `overlay_width`, or `overlays[]` for the multi-overlay stack). Returns a
|
|
444
|
+
* {@link WatermarkedRecipe} (chain post-watermark
|
|
418
445
|
* `compress`/`convert`/`thumbnail`, then `run`/`submit`). Distinct from
|
|
419
446
|
* {@link textWatermark} (single-input text overlay).
|
|
420
447
|
*/
|
|
@@ -466,6 +493,8 @@ export declare class Recipe {
|
|
|
466
493
|
maxWait?: string | number;
|
|
467
494
|
onProgress?: (event: ProgressEvent) => void;
|
|
468
495
|
signal?: AbortSignal;
|
|
496
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
497
|
+
useSSE?: boolean;
|
|
469
498
|
pollIntervalMs?: number;
|
|
470
499
|
probeBeforeCreate?: boolean;
|
|
471
500
|
probeTimeoutMs?: number;
|
|
@@ -625,6 +654,8 @@ export declare class FilesRecipe {
|
|
|
625
654
|
convert(format: string, options?: ConvertOptions): FilesRecipe;
|
|
626
655
|
/** Generate a preview of every input. `width` AND `height` are required; validated via the base {@link Recipe} before any upload. */
|
|
627
656
|
thumbnail(options: ThumbnailOptions): FilesRecipe;
|
|
657
|
+
/** Apply the same geometric transform (rotate/flip) to every input. Validated via the base {@link Recipe}. */
|
|
658
|
+
transform(options?: TransformOptions): FilesRecipe;
|
|
628
659
|
/** Apply the same text watermark to every input. Option keys validated via the base {@link Recipe}. */
|
|
629
660
|
textWatermark(text: string, options?: TextWatermarkOptions): FilesRecipe;
|
|
630
661
|
/**
|
|
@@ -681,6 +712,8 @@ export declare class FilesRecipe {
|
|
|
681
712
|
maxWait?: string | number;
|
|
682
713
|
onProgress?: (event: ProgressEvent) => void;
|
|
683
714
|
signal?: AbortSignal;
|
|
715
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
716
|
+
useSSE?: boolean;
|
|
684
717
|
pollIntervalMs?: number;
|
|
685
718
|
probeBeforeCreate?: boolean;
|
|
686
719
|
probeTimeoutMs?: number;
|
|
@@ -761,6 +794,8 @@ export declare class MergedRecipe {
|
|
|
761
794
|
convert(format: string, options?: ConvertOptions): MergedRecipe;
|
|
762
795
|
/** Thumbnail the merged output. `width` AND `height` are required; validated pre-upload. */
|
|
763
796
|
thumbnail(options: ThumbnailOptions): MergedRecipe;
|
|
797
|
+
/** Geometric transform (rotate/flip) of the merged output. Passthrough; see {@link Recipe.transform}. */
|
|
798
|
+
transform(options?: TransformOptions): MergedRecipe;
|
|
764
799
|
/**
|
|
765
800
|
* Lower to the merge DAG: one `passthrough` source job per input + one
|
|
766
801
|
* `merge` job whose `operations[]` is `[merge, ...post-combine ops]`. The
|
|
@@ -788,6 +823,8 @@ export declare class MergedRecipe {
|
|
|
788
823
|
maxWait?: string | number;
|
|
789
824
|
onProgress?: (event: ProgressEvent) => void;
|
|
790
825
|
signal?: AbortSignal;
|
|
826
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
827
|
+
useSSE?: boolean;
|
|
791
828
|
pollIntervalMs?: number;
|
|
792
829
|
probeBeforeCreate?: boolean;
|
|
793
830
|
probeTimeoutMs?: number;
|
|
@@ -887,6 +924,8 @@ export declare class ArchivedRecipe {
|
|
|
887
924
|
maxWait?: string | number;
|
|
888
925
|
onProgress?: (event: ProgressEvent) => void;
|
|
889
926
|
signal?: AbortSignal;
|
|
927
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
928
|
+
useSSE?: boolean;
|
|
890
929
|
pollIntervalMs?: number;
|
|
891
930
|
probeBeforeCreate?: boolean;
|
|
892
931
|
probeTimeoutMs?: number;
|
|
@@ -944,6 +983,8 @@ export declare class WatermarkedRecipe {
|
|
|
944
983
|
convert(format: string, options?: ConvertOptions): WatermarkedRecipe;
|
|
945
984
|
/** Thumbnail the watermarked output. `width` AND `height` are required; validated pre-upload. */
|
|
946
985
|
thumbnail(options: ThumbnailOptions): WatermarkedRecipe;
|
|
986
|
+
/** Geometric transform (rotate/flip) of the watermarked output. Passthrough; see {@link Recipe.transform}. */
|
|
987
|
+
transform(options?: TransformOptions): WatermarkedRecipe;
|
|
947
988
|
/**
|
|
948
989
|
* Lower to the watermark DAG: a `src_0` passthrough/base-steps job + a `src_1`
|
|
949
990
|
* passthrough/overlay-steps job + one `watermark` job whose `inputs[]` consume
|
|
@@ -967,6 +1008,8 @@ export declare class WatermarkedRecipe {
|
|
|
967
1008
|
maxWait?: string | number;
|
|
968
1009
|
onProgress?: (event: ProgressEvent) => void;
|
|
969
1010
|
signal?: AbortSignal;
|
|
1011
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
1012
|
+
useSSE?: boolean;
|
|
970
1013
|
pollIntervalMs?: number;
|
|
971
1014
|
probeBeforeCreate?: boolean;
|
|
972
1015
|
probeTimeoutMs?: number;
|
|
@@ -1005,4 +1048,111 @@ export declare class WatermarkedRecipe {
|
|
|
1005
1048
|
private lowerPostSteps;
|
|
1006
1049
|
private withStep;
|
|
1007
1050
|
}
|
|
1051
|
+
/**
|
|
1052
|
+
* The keyed multi-recipe batch builder (FF7 / MFaCjL8d). `client.batch([r1, r2, …])`
|
|
1053
|
+
* runs N DISTINCT single-input keyed {@link Recipe}s as ONE workflow; the
|
|
1054
|
+
* partitioned {@link RunResult} addresses each entry's outputs by the caller key
|
|
1055
|
+
* given at `client.file(input, key)` time (`res.byKey('hero')`), and one failed
|
|
1056
|
+
* entry lands in `failed` without sinking the rest.
|
|
1057
|
+
*
|
|
1058
|
+
* **v1 scope (locked):** `.run()` only (no `submit()` / reattach — a follow-up);
|
|
1059
|
+
* single-input {@link Recipe} entries only — the multi-input builders
|
|
1060
|
+
* ({@link FilesRecipe}, {@link MergedRecipe}, {@link WatermarkedRecipe},
|
|
1061
|
+
* {@link ArchivedRecipe}) are REJECTED pre-upload. Cross-entry upload dedupe
|
|
1062
|
+
* IS applied (1LwSJcz1): two entries sourcing the SAME input (by
|
|
1063
|
+
* {@link inputIdentity}) upload ONCE and share the resulting fileId —
|
|
1064
|
+
* correctness-neutral (same bytes → same per-job output), it only elides
|
|
1065
|
+
* redundant uploads. Observable caveat: `onProgress` upload-phase events drop
|
|
1066
|
+
* to one-per-UNIQUE input rather than one-per-entry.
|
|
1067
|
+
*
|
|
1068
|
+
* **Lowering (one workflow):** for each entry `i`, lower its single job via
|
|
1069
|
+
* {@link Recipe.toWorkflowPayload} and re-id it `b{i}` — a POSITIONAL namespace
|
|
1070
|
+
* DISTINCT from the fan-out `file-{i}` / merge-archive-watermark `src_{i}` refs so
|
|
1071
|
+
* a future reattach can't misdetect the wire as a fan-out / merge. `keyByRef`
|
|
1072
|
+
* maps each `b{i}` ref to that entry's caller key, so
|
|
1073
|
+
* {@link projectMultiJobToRunResult} partitions per entry (1 job ↔ 1 key:
|
|
1074
|
+
* `completed` → `succeeded`, else → `failed` with a {@link GislItemFailedError}).
|
|
1075
|
+
*
|
|
1076
|
+
* **Immutability:** the ctor is CLIENT-ONLY (the ordered entries + the client) —
|
|
1077
|
+
* entries are already-built Recipes that captured their own preset defaults at
|
|
1078
|
+
* `client.file(...)` time, so batch never re-plumbs
|
|
1079
|
+
* presetDefaults/scopedPresetDefaults. Mirrors the PHP `BatchRecipe`.
|
|
1080
|
+
*/
|
|
1081
|
+
export declare class BatchRecipe {
|
|
1082
|
+
private readonly client?;
|
|
1083
|
+
private readonly recipes;
|
|
1084
|
+
constructor(recipes: ReadonlyArray<Recipe>, client?: GislClient | undefined);
|
|
1085
|
+
/**
|
|
1086
|
+
* Execute the batch end-to-end: validate + lowering-preflight EVERY entry
|
|
1087
|
+
* BEFORE any upload, upload each entry's input, create ONE multi-job workflow
|
|
1088
|
+
* (one `b{i}` job per entry), await a terminal state (SSE with poll fallback,
|
|
1089
|
+
* honouring `useSSE`), then partition the per-job downloads into a keyed
|
|
1090
|
+
* {@link RunResult}. `partially_failed` is a NORMAL terminal state here — the
|
|
1091
|
+
* completed entries land in `succeeded`, the rest in `failed`.
|
|
1092
|
+
*
|
|
1093
|
+
* Requires a client bound at construction time — `gisl().batch([...])` wires
|
|
1094
|
+
* it; a directly-constructed {@link BatchRecipe} (e.g. a lowering-only test)
|
|
1095
|
+
* throws {@link GislConfigError}. Mirrors the fan-out {@link FilesRecipe.run}.
|
|
1096
|
+
*/
|
|
1097
|
+
run(options?: {
|
|
1098
|
+
maxWait?: string | number;
|
|
1099
|
+
onProgress?: (event: ProgressEvent) => void;
|
|
1100
|
+
signal?: AbortSignal;
|
|
1101
|
+
/** Force the poll fallback instead of attempting SSE. Default true (SSE-first, poll fallback). */
|
|
1102
|
+
useSSE?: boolean;
|
|
1103
|
+
pollIntervalMs?: number;
|
|
1104
|
+
probeBeforeCreate?: boolean;
|
|
1105
|
+
probeTimeoutMs?: number;
|
|
1106
|
+
}): Promise<RunResult>;
|
|
1107
|
+
/**
|
|
1108
|
+
* Lower the batch to ONE multi-job workflow-create payload against a list of
|
|
1109
|
+
* resolved upload ids (one per entry, in entry order). Each entry `i` becomes
|
|
1110
|
+
* ONE job re-id'd `b{i}` carrying that entry's lowered `source` + `operations`.
|
|
1111
|
+
* Composes the single-file {@link Recipe.toWorkflowPayload} per entry so each
|
|
1112
|
+
* keeps its own media-hint + preset resolution and lowering logic is not
|
|
1113
|
+
* duplicated. `callback_url` is built in ONLY when a webhook is supplied
|
|
1114
|
+
* (batch v1 run() supplies none, so it is omitted).
|
|
1115
|
+
*
|
|
1116
|
+
* @internal Consumed by {@link run} (after uploading) and the cross-language
|
|
1117
|
+
* golden-payload lowering test (with fixed ids). Not caller-facing.
|
|
1118
|
+
*/
|
|
1119
|
+
toWorkflowPayload(fileIds: readonly string[], callbackUrl?: string): WorkflowCreatePayload;
|
|
1120
|
+
/** The number of recipe entries in this batch (introspection / tests). */
|
|
1121
|
+
get recipeCount(): number;
|
|
1122
|
+
/**
|
|
1123
|
+
* Validate the batch AND lowering-preflight every entry BEFORE any upload
|
|
1124
|
+
* fires — an invalid entry costs no bandwidth. TWO PASSES (mirrors PHP
|
|
1125
|
+
* `BatchRecipe`'s structural-loop-then-preflight-loop), throwing
|
|
1126
|
+
* {@link GislConfigError}:
|
|
1127
|
+
* 0. empty batch → `no_recipes` (checked first).
|
|
1128
|
+
* PASS 1 (structural, ALL entries in order):
|
|
1129
|
+
* - a KNOWN multi-input builder (checked FIRST — they do NOT extend
|
|
1130
|
+
* {@link Recipe}, so the not-a-Recipe catch-all would otherwise misreport
|
|
1131
|
+
* them as plain type errors) → `multi_input_recipe_unsupported`;
|
|
1132
|
+
* - a non-{@link Recipe} entry → `invalid_recipe`;
|
|
1133
|
+
* - a missing/empty key → `missing_key`;
|
|
1134
|
+
* - a duplicate key → `duplicate_key`.
|
|
1135
|
+
* PASS 2 (lowering preflight, ALL entries): lower each entry (via
|
|
1136
|
+
* {@link Recipe.toWorkflowPayload}) so an invalid lowering throws BEFORE any
|
|
1137
|
+
* upload, mirroring what {@link FilesRecipe} lowers pre-create.
|
|
1138
|
+
*
|
|
1139
|
+
* Two passes so a batch with MULTIPLE distinct violations throws the SAME
|
|
1140
|
+
* reason regardless of entry order (a structural error anywhere wins over a
|
|
1141
|
+
* lowering error elsewhere) — converging TS + PHP error reporting. The
|
|
1142
|
+
* offending key/index rides the MESSAGE (not `conflictingFields`, which is
|
|
1143
|
+
* reserved for wire FIELD names).
|
|
1144
|
+
*/
|
|
1145
|
+
private validatePreUpload;
|
|
1146
|
+
/**
|
|
1147
|
+
* Collapse the entry inputs to a first-appearance-unique list for cross-entry
|
|
1148
|
+
* upload dedupe: two entries sourcing the SAME input (by {@link inputIdentity})
|
|
1149
|
+
* upload ONCE and share the fileId. Returns the ordered `uniqueInputs` plus an
|
|
1150
|
+
* `entryToUnique` index map (length N, entry order) so {@link run} can expand
|
|
1151
|
+
* the unique fileIds back to one-per-entry before {@link toWorkflowPayload} —
|
|
1152
|
+
* keeping the b{i} refs + {@link keyByRef} N-length and correctness-neutral.
|
|
1153
|
+
*/
|
|
1154
|
+
private planUploads;
|
|
1155
|
+
/** Map each `b{i}` job ref to that entry's caller key (validated non-empty). */
|
|
1156
|
+
private keyByRef;
|
|
1157
|
+
}
|
|
1008
1158
|
export {};
|