@giveitsmaller/sdk 0.15.0 → 0.17.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 +21 -0
- package/dist/_audit.js +15 -2
- package/dist/client.d.ts +27 -4
- package/dist/client.js +46 -4
- package/dist/ergonomic/image_output_routes.d.ts +89 -0
- package/dist/ergonomic/image_output_routes.js +155 -0
- package/dist/ergonomic/option_types.d.ts +147 -0
- package/dist/ergonomic/option_types.js +57 -0
- package/dist/ergonomic/option_validation.d.ts +58 -0
- package/dist/ergonomic/option_validation.js +143 -0
- package/dist/ergonomic/preset_resolver.d.ts +7 -6
- package/dist/ergonomic/preset_resolver.js +43 -39
- package/dist/ergonomic/presets/document_pdf_compress.d.ts +3 -5
- package/dist/ergonomic/presets/document_pdf_compress.js +10 -12
- package/dist/ergonomic/presets/image_compress.d.ts +4 -11
- package/dist/ergonomic/presets/image_compress.js +12 -25
- package/dist/ergonomic/presets/index.d.ts +21 -1
- package/dist/ergonomic/presets/index.js +4 -4
- package/dist/errors.d.ts +25 -0
- package/dist/errors.js +34 -0
- package/dist/file-first.d.ts +241 -49
- package/dist/file-first.js +803 -249
- package/dist/generated/sdk_spec/enums.d.ts +8 -46
- package/dist/generated/sdk_spec/enums.js +12 -33
- package/dist/generated/sdk_spec/presets.js +9 -20
- package/dist/generated/sdk_spec/version.d.ts +3 -3
- package/dist/generated/sdk_spec/version.js +3 -3
- package/dist/gisl.d.ts +8 -1
- package/dist/gisl.js +12 -0
- package/dist/handle.js +9 -1
- package/dist/index.core.d.ts +7 -4
- package/dist/index.core.js +8 -1
- package/dist/types.d.ts +21 -0
- package/package.json +3 -3
|
@@ -41,7 +41,7 @@ export { DocumentOfficeCompressPresetOptions, } from './document_office_compress
|
|
|
41
41
|
export { DocumentOdfCompressPresetOptions, } from './document_odf_compress.js';
|
|
42
42
|
export { DocumentEpubCompressPresetOptions, } from './document_epub_compress.js';
|
|
43
43
|
// Re-export ergonomic enums for callers (single canonical path).
|
|
44
|
-
export { OptimizeFor,
|
|
44
|
+
export { OptimizeFor, ImageMetadataPolicy, ImageFormat, VideoCodec, VideoPreset, VideoFit, AudioBitrate, AudioCodec, AudioSampleRate, PdfProfile, PdfColorspace, } from '../../generated/sdk_spec/enums.js';
|
|
45
45
|
function cellKeyOf(media, op) {
|
|
46
46
|
return `${media}_${op}`;
|
|
47
47
|
}
|
|
@@ -55,8 +55,8 @@ function cellKeyOf(media, op) {
|
|
|
55
55
|
*
|
|
56
56
|
* `definedFieldsOf` filters undefined values out of each instance
|
|
57
57
|
* BEFORE the merge: with TS `useDefineForClassFields` (the ES2022
|
|
58
|
-
* default), `readonly
|
|
59
|
-
* field as an enumerable own property with value `undefined` BEFORE
|
|
58
|
+
* default), `readonly outputFormat?: ImageFormat` declarations initialise
|
|
59
|
+
* the field as an enumerable own property with value `undefined` BEFORE
|
|
60
60
|
* the ctor body runs. A naive `Object.assign({}, parent, child)`
|
|
61
61
|
* therefore lets child's `undefined` overwrite parent's defined value
|
|
62
62
|
* — caught by CI on PR #125 first run. Filter-then-spread restores
|
|
@@ -64,7 +64,7 @@ function cellKeyOf(media, op) {
|
|
|
64
64
|
*
|
|
65
65
|
* @internal
|
|
66
66
|
*/
|
|
67
|
-
function definedFieldsOf(opts) {
|
|
67
|
+
export function definedFieldsOf(opts) {
|
|
68
68
|
const out = {};
|
|
69
69
|
for (const key of Object.keys(opts)) {
|
|
70
70
|
const value = opts[key];
|
package/dist/errors.d.ts
CHANGED
|
@@ -461,3 +461,28 @@ export declare class GislSinkError extends GislError {
|
|
|
461
461
|
readonly reason: GislSinkErrorReason;
|
|
462
462
|
});
|
|
463
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* A terminal item failure in {@link RunResult.failed} — an input whose job did
|
|
466
|
+
* not reach `completed`. Stored in `ItemFailure.error` so a caller can branch on
|
|
467
|
+
* the failure reason WITHOUT string-parsing.
|
|
468
|
+
*
|
|
469
|
+
* - `state`: the terminal lifecycle state (`failed` / `expired` / `cancelled` /
|
|
470
|
+
* `partially_failed` / `paused_insufficient_credits`, or a per-job
|
|
471
|
+
* non-`completed` status).
|
|
472
|
+
* - `errorMessage` / `errorCode`: the human + machine fields read from the first
|
|
473
|
+
* failing operation (`OperationResponse.error_message` / `.error_code`). BOTH
|
|
474
|
+
* are absent for non-`failed` terminal states — cancel / expire / credit-pause
|
|
475
|
+
* carry only the bare `state`.
|
|
476
|
+
*
|
|
477
|
+
* `message` is `state` optionally suffixed `: errorMessage`, preserving the
|
|
478
|
+
* pre-typed string exactly (an empty-string `errorMessage` still adds the colon).
|
|
479
|
+
*
|
|
480
|
+
* Mirrors the PHP `Gisl\Sdk\Errors\GislItemFailedError`.
|
|
481
|
+
*/
|
|
482
|
+
export declare class GislItemFailedError extends GislError {
|
|
483
|
+
readonly key: string | null;
|
|
484
|
+
readonly state: string;
|
|
485
|
+
readonly errorMessage?: string;
|
|
486
|
+
readonly errorCode?: string;
|
|
487
|
+
constructor(key: string | null, state: string, errorMessage?: string, errorCode?: string);
|
|
488
|
+
}
|
package/dist/errors.js
CHANGED
|
@@ -503,3 +503,37 @@ export class GislSinkError extends GislError {
|
|
|
503
503
|
this.reason = options.reason;
|
|
504
504
|
}
|
|
505
505
|
}
|
|
506
|
+
/**
|
|
507
|
+
* A terminal item failure in {@link RunResult.failed} — an input whose job did
|
|
508
|
+
* not reach `completed`. Stored in `ItemFailure.error` so a caller can branch on
|
|
509
|
+
* the failure reason WITHOUT string-parsing.
|
|
510
|
+
*
|
|
511
|
+
* - `state`: the terminal lifecycle state (`failed` / `expired` / `cancelled` /
|
|
512
|
+
* `partially_failed` / `paused_insufficient_credits`, or a per-job
|
|
513
|
+
* non-`completed` status).
|
|
514
|
+
* - `errorMessage` / `errorCode`: the human + machine fields read from the first
|
|
515
|
+
* failing operation (`OperationResponse.error_message` / `.error_code`). BOTH
|
|
516
|
+
* are absent for non-`failed` terminal states — cancel / expire / credit-pause
|
|
517
|
+
* carry only the bare `state`.
|
|
518
|
+
*
|
|
519
|
+
* `message` is `state` optionally suffixed `: errorMessage`, preserving the
|
|
520
|
+
* pre-typed string exactly (an empty-string `errorMessage` still adds the colon).
|
|
521
|
+
*
|
|
522
|
+
* Mirrors the PHP `Gisl\Sdk\Errors\GislItemFailedError`.
|
|
523
|
+
*/
|
|
524
|
+
export class GislItemFailedError extends GislError {
|
|
525
|
+
key;
|
|
526
|
+
state;
|
|
527
|
+
errorMessage;
|
|
528
|
+
errorCode;
|
|
529
|
+
constructor(key, state, errorMessage, errorCode) {
|
|
530
|
+
super(state + (errorMessage !== undefined ? `: ${errorMessage}` : ''));
|
|
531
|
+
this.name = 'GislItemFailedError';
|
|
532
|
+
this.key = key;
|
|
533
|
+
this.state = state;
|
|
534
|
+
if (errorMessage !== undefined)
|
|
535
|
+
this.errorMessage = errorMessage;
|
|
536
|
+
if (errorCode !== undefined)
|
|
537
|
+
this.errorCode = errorCode;
|
|
538
|
+
}
|
|
539
|
+
}
|
package/dist/file-first.d.ts
CHANGED
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Mirrors `packages/php/src/FileFirst/*`.
|
|
11
11
|
*/
|
|
12
|
+
import { GislItemFailedError } from './errors.js';
|
|
12
13
|
import { type ProgressEvent } from './builder.js';
|
|
13
14
|
import type { GislClient } from './client.js';
|
|
14
15
|
import type { OperationDownload, WorkflowStatusResponse } from '@giveitsmaller/contracts/openapi';
|
|
16
|
+
import type { ConvertOptions, ThumbnailOptions, TextWatermarkOptions, WatermarkOptions, OutputOptions, OutputFit } from './ergonomic/option_types.js';
|
|
15
17
|
import { OptimizeFor } from './generated/sdk_spec/enums.js';
|
|
16
18
|
import type { PresetDefaults } from './ergonomic/presets/index.js';
|
|
17
19
|
import type { WorkflowCreatePayload } from './types.js';
|
|
@@ -66,15 +68,16 @@ export interface ItemResult {
|
|
|
66
68
|
readonly outputs: readonly OutputFile[];
|
|
67
69
|
}
|
|
68
70
|
/**
|
|
69
|
-
* One failed entry in {@link RunResult.failed}: an input that did not
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
71
|
+
* One failed entry in {@link RunResult.failed}: an input that did not produce a
|
|
72
|
+
* deliverable, paired with the cause. One bad input does not sink the rest of a
|
|
73
|
+
* multi-input run. `error` is a typed {@link GislItemFailedError} carrying the
|
|
74
|
+
* terminal `state` plus the failing operation's `errorMessage`/`errorCode` (when
|
|
75
|
+
* present), so the caller can branch on the failure WITHOUT string-parsing.
|
|
76
|
+
* Mirrors the PHP `ItemFailure`.
|
|
74
77
|
*/
|
|
75
78
|
export interface ItemFailure {
|
|
76
79
|
readonly key: string | null;
|
|
77
|
-
readonly error:
|
|
80
|
+
readonly error: GislItemFailedError;
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
80
83
|
* Return value of {@link RunResult.downloadTo} — the local paths written,
|
|
@@ -159,27 +162,13 @@ export declare class RunResult {
|
|
|
159
162
|
failed: readonly {
|
|
160
163
|
key: string | null;
|
|
161
164
|
error: string;
|
|
165
|
+
state: string;
|
|
166
|
+
errorMessage?: string;
|
|
167
|
+
errorCode?: string;
|
|
162
168
|
}[];
|
|
163
169
|
};
|
|
164
170
|
private requireDownloader;
|
|
165
171
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Flatten the terminal workflow status + its downloads into a {@link RunResult}.
|
|
168
|
-
*
|
|
169
|
-
* Shared by {@link Recipe.run} (passes its recipe key) and the file-first
|
|
170
|
-
* {@link Handle} reattach surface (`Handle.wait()`/`Handle.result()`, FF5a —
|
|
171
|
-
* passes `null` because a reattached handle carries no recipe key).
|
|
172
|
-
*
|
|
173
|
-
* **Partition invariant (carries a prior codex-review fix — do NOT let it
|
|
174
|
-
* drift):** success is ONLY `state === 'completed'`. Every other terminal
|
|
175
|
-
* state — `failed`, `partially_failed`, `cancelled`, `expired`,
|
|
176
|
-
* `paused_insufficient_credits` — partitions into `failed[]` so a caller's
|
|
177
|
-
* `ok`/`succeeded` check can never treat a cancelled/expired/paused run as a
|
|
178
|
-
* clean result.
|
|
179
|
-
*
|
|
180
|
-
* @internal Exported for reuse by the file-first `Handle`; not part of the
|
|
181
|
-
* caller-facing fluent surface.
|
|
182
|
-
*/
|
|
183
172
|
export declare function projectDownloadsToRunResult(workflowId: string, finalStatus: WorkflowStatusResponse, jobDownloads: readonly {
|
|
184
173
|
files: readonly OperationDownload[];
|
|
185
174
|
}[], key: string | null, downloader?: Downloader): RunResult;
|
|
@@ -249,6 +238,19 @@ export declare function isMergeStatus(finalStatus: WorkflowStatusResponse): bool
|
|
|
249
238
|
* @internal Exported for the file-first `Handle`; not part of the public API.
|
|
250
239
|
*/
|
|
251
240
|
export declare function isArchiveStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
241
|
+
/**
|
|
242
|
+
* True when a terminal status describes a fluent `file(...).watermark(overlay)`
|
|
243
|
+
* — at least one job ref `watermark` and every OTHER job ref is `src_{i}` (the
|
|
244
|
+
* ids the {@link WatermarkedRecipe} lowering assigns: `src_0` base, `src_1`
|
|
245
|
+
* overlay). Lets {@link Handle.wait}/{@link Handle.result} AND
|
|
246
|
+
* {@link WatermarkedRecipe.run} project ONLY the watermark output — filtering
|
|
247
|
+
* the `src_*` passthrough plumbing — even after a `client.workflow(id)` reattach.
|
|
248
|
+
* Mutually exclusive with {@link isFanoutStatus} / {@link isMergeStatus} /
|
|
249
|
+
* {@link isArchiveStatus}.
|
|
250
|
+
*
|
|
251
|
+
* @internal Exported for the file-first `Handle`; not part of the public API.
|
|
252
|
+
*/
|
|
253
|
+
export declare function isWatermarkStatus(finalStatus: WorkflowStatusResponse): boolean;
|
|
252
254
|
/**
|
|
253
255
|
* The primary file a {@link Recipe} operates on — the "subject" of the
|
|
254
256
|
* file-first surface. A discriminated union over the ways a caller names an
|
|
@@ -293,7 +295,7 @@ export declare const fileInput: {
|
|
|
293
295
|
};
|
|
294
296
|
/** One step in a {@link Recipe}'s chain — an op kind + captured ergonomic args. */
|
|
295
297
|
interface RecipeStep {
|
|
296
|
-
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark';
|
|
298
|
+
readonly opType: 'compress' | 'convert' | 'thumbnail' | 'text_watermark' | 'output';
|
|
297
299
|
readonly options: Readonly<Record<string, unknown>>;
|
|
298
300
|
}
|
|
299
301
|
/**
|
|
@@ -339,22 +341,55 @@ export declare class Recipe {
|
|
|
339
341
|
* option (the convert op's wire key per the contract); `options` carries any
|
|
340
342
|
* additional per-op convert options.
|
|
341
343
|
*/
|
|
342
|
-
convert(format: string, options?:
|
|
344
|
+
convert(format: string, options?: ConvertOptions): Recipe;
|
|
343
345
|
/**
|
|
344
|
-
* Generate a preview.
|
|
345
|
-
*
|
|
346
|
-
*
|
|
346
|
+
* Generate a preview / resize. `width` AND `height` are required (the contract
|
|
347
|
+
* marks both required for image/video/document); any additional per-op
|
|
348
|
+
* thumbnail option passes through. An omitted (`undefined`) optional value is
|
|
349
|
+
* dropped from the wire options (not sent as `undefined`).
|
|
347
350
|
*/
|
|
348
|
-
thumbnail(options
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
thumbnail(options: ThumbnailOptions): Recipe;
|
|
352
|
+
/**
|
|
353
|
+
* Produce ONE transformed image: keep or change format, plus quality, resize
|
|
354
|
+
* and route-honored controls. The single user-facing image transform — the SDK
|
|
355
|
+
* resolves the route from `(input format, output_format)` against the contract's
|
|
356
|
+
* image-output-routes projection and lowers to that route's wire op:
|
|
357
|
+
* same-format → `compress` (optimiser, `output_format: 'original'`), format-change
|
|
358
|
+
* → `convert` (transcoder, `output_format: <fmt>`). Only options the resolved
|
|
359
|
+
* route honors are sent; a planned or not-honored option throws BEFORE upload.
|
|
360
|
+
* Resize (`width`/`height`/`fit`, via `options` or {@link resize}) stays on the
|
|
361
|
+
* SAME op — one output, never a separate thumbnail.
|
|
362
|
+
*
|
|
363
|
+
* `format` omitted → keep the input format (same-format optimiser route).
|
|
364
|
+
*/
|
|
365
|
+
output(format?: string, options?: OutputOptions): Recipe;
|
|
366
|
+
/**
|
|
367
|
+
* Resize as part of the Output transform. Merges `width`/`height`/`fit` into the
|
|
368
|
+
* PRECEDING `output()` step (one artifact); if no Output step precedes, appends a
|
|
369
|
+
* same-format Output step carrying the resize. Never emits a `thumbnail` op.
|
|
370
|
+
* `height` is optional — width-only resize preserves aspect ratio. Resize is
|
|
371
|
+
* raster-only (e.g. an SVG input has no resize on its route → throws at lower).
|
|
372
|
+
*/
|
|
373
|
+
resize(width: number, height?: number, fit?: OutputFit): Recipe;
|
|
352
374
|
/**
|
|
353
375
|
* Apply a text watermark. Single-input (the text is an option, not a
|
|
354
376
|
* secondary file) — lowers to the `text_watermark` op with a `text` option;
|
|
355
377
|
* `options` carries any additional per-op watermark options.
|
|
356
378
|
*/
|
|
357
|
-
textWatermark(text: string, options?:
|
|
379
|
+
textWatermark(text: string, options?: TextWatermarkOptions): Recipe;
|
|
380
|
+
/**
|
|
381
|
+
* Composite an image OVERLAY onto this file (a multi-input op). `overlay` is a
|
|
382
|
+
* secondary file-NODE (a {@link Recipe} — e.g. `client.file('logo.png')`),
|
|
383
|
+
* itself optionally processed first. Routes by THIS file's effective media:
|
|
384
|
+
* image base → `image_watermark` (stable), video base → `video_watermark`
|
|
385
|
+
* (beta). Audio/document/animated-GIF/unsupported-subtype/undetectable bases
|
|
386
|
+
* throw locally BEFORE any upload (the planned-op gate). `options` carries the
|
|
387
|
+
* wire watermark options (`anchor`, `opacity`, `margin_x`, `margin_y`,
|
|
388
|
+
* `overlay_width`). Returns a {@link WatermarkedRecipe} (chain post-watermark
|
|
389
|
+
* `compress`/`convert`/`thumbnail`, then `run`/`submit`). Distinct from
|
|
390
|
+
* {@link textWatermark} (single-input text overlay).
|
|
391
|
+
*/
|
|
392
|
+
watermark(overlay: Recipe, options?: WatermarkOptions): WatermarkedRecipe;
|
|
358
393
|
/**
|
|
359
394
|
* Lower this recipe to a workflow-create payload against a resolved upload
|
|
360
395
|
* id. Single-input chain → ONE job, `source: upload(fileId)`, ordered
|
|
@@ -380,6 +415,13 @@ export declare class Recipe {
|
|
|
380
415
|
* @internal
|
|
381
416
|
*/
|
|
382
417
|
get recipeSteps(): readonly RecipeStep[];
|
|
418
|
+
/**
|
|
419
|
+
* The primary input this recipe operates on. Read by {@link WatermarkedRecipe}
|
|
420
|
+
* to lift an overlay Recipe's input (for upload + media inference + src-job
|
|
421
|
+
* lowering) without making the ctor field public.
|
|
422
|
+
* @internal
|
|
423
|
+
*/
|
|
424
|
+
get recipeInput(): FileInput;
|
|
383
425
|
/**
|
|
384
426
|
* Execute the recipe end-to-end: upload the input (when required), create
|
|
385
427
|
* the workflow, await a terminal state (SSE with poll fallback), then
|
|
@@ -432,10 +474,78 @@ export declare class Recipe {
|
|
|
432
474
|
private _uploadAndCreate;
|
|
433
475
|
private withStep;
|
|
434
476
|
private lowerStep;
|
|
477
|
+
/**
|
|
478
|
+
* Lower an `output` step to its route's wire op. Resolves the route from the
|
|
479
|
+
* (chain-folded) input format token + the requested `output_format`, then emits
|
|
480
|
+
* `compress` (same_format) or `convert` (format_change) carrying only the
|
|
481
|
+
* route-honored options. A planned option (e.g. `lossless`), an option not
|
|
482
|
+
* honored on the resolved route (e.g. `progressive` on a format-change), a
|
|
483
|
+
* planned per-value (e.g. `metadata: 'keep'`), or an unrepresentable route all
|
|
484
|
+
* throw a typed {@link GislConfigError} BEFORE upload. Resize (`width`/`height`/
|
|
485
|
+
* `fit`) is input-keyed (raster only) and rides whichever op the route selects.
|
|
486
|
+
*/
|
|
487
|
+
private lowerOutputStep;
|
|
488
|
+
/**
|
|
489
|
+
* The input format token an `output` step at `uptoIndex` operates on — the
|
|
490
|
+
* original input's token, FOLDED through preceding `convert`/`output` steps that
|
|
491
|
+
* change the format (mirrors {@link compressMediaHint}). Undefined when the input
|
|
492
|
+
* media is not inferable (a bare upload id / unnamed, untyped Blob).
|
|
493
|
+
*/
|
|
494
|
+
private outputInputToken;
|
|
495
|
+
/** The original input's image format token (path ext / Blob type / Blob name). */
|
|
496
|
+
private inputFormatToken;
|
|
435
497
|
private lowerCompressOptions;
|
|
498
|
+
/** Media of the original input (no chain context) — used by the probe gate. */
|
|
499
|
+
private inputMedia;
|
|
500
|
+
/**
|
|
501
|
+
* The media class a `compress` step at `uptoIndex` actually operates on. With no
|
|
502
|
+
* chain context (`uptoIndex` undefined) this is the original input's media. With
|
|
503
|
+
* context, FOLD the preceding `convert` steps: each `convert(output_format)` changes
|
|
504
|
+
* the media the next step sees (56N4chXY / N8eESzQN — a chain like
|
|
505
|
+
* `mp3 -> convert(flac) -> compress` must resolve against flac, not mp3). Reuses the
|
|
506
|
+
* synthetic-filename detection precedent from {@link MergedRecipe} (`merged.<ext>`).
|
|
507
|
+
*/
|
|
436
508
|
private compressMediaHint;
|
|
509
|
+
/**
|
|
510
|
+
* Whether the media a `compress` step at `uptoIndex` operates on is lossless audio.
|
|
511
|
+
* Determined by the most recent preceding `convert` target (`flac`/`wav` -> lossless)
|
|
512
|
+
* when there is one, else by the original input. Lossless is unaffected by the
|
|
513
|
+
* video/ogg guard (ogg is never lossless either way).
|
|
514
|
+
*/
|
|
437
515
|
private compressAudioLossless;
|
|
438
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* The single SDK-side source of truth for which `(wire op, base mime)`
|
|
519
|
+
* combinations the file-first `watermark()` verb may emit, and their
|
|
520
|
+
* availability. The generated typed metadata sidecar does NOT carry the
|
|
521
|
+
* supported-mime allowlist (`MimeGroupMetadata` has no `mimes` field and
|
|
522
|
+
* `per_mime_availability` is empty for these ops), so this hand table is the
|
|
523
|
+
* gate's source — PINNED to the generated `availability.json` by a conformance
|
|
524
|
+
* test (mirrors the wire-key-conformance pattern): a contract regen that
|
|
525
|
+
* changes the supported mimes or availability of `image_watermark` /
|
|
526
|
+
* `video_watermark` fails that test. The gate reads ONLY this table.
|
|
527
|
+
* @internal
|
|
528
|
+
*/
|
|
529
|
+
export declare const WATERMARK_CAPABILITY: {
|
|
530
|
+
readonly image_watermark: {
|
|
531
|
+
readonly image: {
|
|
532
|
+
readonly mimes: readonly ["image/jpeg", "image/png", "image/webp"];
|
|
533
|
+
readonly availability: "stable";
|
|
534
|
+
};
|
|
535
|
+
readonly image_gif: {
|
|
536
|
+
readonly mimes: readonly ["image/gif"];
|
|
537
|
+
readonly availability: "planned";
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
readonly video_watermark: {
|
|
541
|
+
readonly video: {
|
|
542
|
+
readonly mimes: readonly ["video/mp4", "video/webm"];
|
|
543
|
+
readonly availability: "beta";
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
};
|
|
547
|
+
/** Wire op types the file-first `watermark()` verb can route to. */
|
|
548
|
+
export type WatermarkWireOp = 'image_watermark' | 'video_watermark';
|
|
439
549
|
/**
|
|
440
550
|
* The homogeneous fan-out builder value (FF3a). `client.files([a, b, c])`
|
|
441
551
|
* returns a `FilesRecipe`; the op-chain methods (`compress`, `convert`,
|
|
@@ -474,15 +584,12 @@ export declare class FilesRecipe {
|
|
|
474
584
|
* lowering builds an internal Recipe that throws the same `GislConfigError`.
|
|
475
585
|
*/
|
|
476
586
|
compress(optimize?: OptimizeFor, options?: Record<string, unknown>): FilesRecipe;
|
|
477
|
-
/** Change every input's format. `format` lowers to the contract `output_format` wire key (via {@link Recipe.convert}), NOT `format`. */
|
|
478
|
-
convert(format: string, options?:
|
|
479
|
-
/** Generate a preview of every input.
|
|
480
|
-
thumbnail(options
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
} & Record<string, unknown>): FilesRecipe;
|
|
484
|
-
/** Apply the same text watermark to every input. */
|
|
485
|
-
textWatermark(text: string, options?: Record<string, unknown>): FilesRecipe;
|
|
587
|
+
/** Change every input's format. `format` lowers to the contract `output_format` wire key (via {@link Recipe.convert}), NOT `format`. Option keys are validated (via the base {@link Recipe}) before any upload. */
|
|
588
|
+
convert(format: string, options?: ConvertOptions): FilesRecipe;
|
|
589
|
+
/** Generate a preview of every input. `width` AND `height` are required; validated via the base {@link Recipe} before any upload. */
|
|
590
|
+
thumbnail(options: ThumbnailOptions): FilesRecipe;
|
|
591
|
+
/** Apply the same text watermark to every input. Option keys validated via the base {@link Recipe}. */
|
|
592
|
+
textWatermark(text: string, options?: TextWatermarkOptions): FilesRecipe;
|
|
486
593
|
/**
|
|
487
594
|
* Combine the inputs into ONE output (N→1), in array order (FF3b). Returns a
|
|
488
595
|
* single-output {@link MergedRecipe} you chain further ops on
|
|
@@ -613,13 +720,10 @@ export declare class MergedRecipe {
|
|
|
613
720
|
constructor(inputs: readonly FileInput[], mergeOptions: MergeOptions, postSteps?: readonly RecipeStep[], presetDefaults?: PresetDefaults | undefined, scopedPresetDefaults?: PresetDefaults | undefined, client?: GislClient | undefined);
|
|
614
721
|
/** Reduce the merged output's size. See {@link Recipe.compress}. */
|
|
615
722
|
compress(optimize?: OptimizeFor, options?: Record<string, unknown>): MergedRecipe;
|
|
616
|
-
/** Change the merged output's format. See {@link Recipe.convert}. */
|
|
617
|
-
convert(format: string, options?:
|
|
618
|
-
/** Thumbnail the merged output.
|
|
619
|
-
thumbnail(options
|
|
620
|
-
width?: number;
|
|
621
|
-
height?: number;
|
|
622
|
-
} & Record<string, unknown>): MergedRecipe;
|
|
723
|
+
/** Change the merged output's format. See {@link Recipe.convert}. Option keys validated pre-upload. */
|
|
724
|
+
convert(format: string, options?: ConvertOptions): MergedRecipe;
|
|
725
|
+
/** Thumbnail the merged output. `width` AND `height` are required; validated pre-upload. */
|
|
726
|
+
thumbnail(options: ThumbnailOptions): MergedRecipe;
|
|
623
727
|
/**
|
|
624
728
|
* Lower to the merge DAG: one `passthrough` source job per input + one
|
|
625
729
|
* `merge` job whose `operations[]` is `[merge, ...post-combine ops]`. The
|
|
@@ -776,4 +880,92 @@ export declare class ArchivedRecipe {
|
|
|
776
880
|
*/
|
|
777
881
|
private wireArchiveOptions;
|
|
778
882
|
}
|
|
883
|
+
/**
|
|
884
|
+
* The single-output recipe you're in AFTER `file(base).watermark(overlay, …)`
|
|
885
|
+
* (FF4a). Composites an image OVERLAY onto the base (image_watermark for image
|
|
886
|
+
* bases, video_watermark for video bases — routed at lowering by the base's
|
|
887
|
+
* effective media). A multi-input op: base + overlay each enter via their own
|
|
888
|
+
* `passthrough` source job (`src_0` base, `src_1` overlay; their own preceding
|
|
889
|
+
* steps lower into those jobs), and the `watermark` job consumes them via
|
|
890
|
+
* `job_output` inputs tagged `role: base` / `role: overlay`. Post-watermark
|
|
891
|
+
* `compress`/`convert`/`thumbnail` chain onto the watermark output. Mirrors
|
|
892
|
+
* {@link MergedRecipe}. `textWatermark` is intentionally NOT a post-verb here.
|
|
893
|
+
*/
|
|
894
|
+
export declare class WatermarkedRecipe {
|
|
895
|
+
private readonly baseInput;
|
|
896
|
+
private readonly baseSteps;
|
|
897
|
+
private readonly overlay;
|
|
898
|
+
private readonly watermarkOptions;
|
|
899
|
+
private readonly postSteps;
|
|
900
|
+
private readonly presetDefaults?;
|
|
901
|
+
private readonly scopedPresetDefaults?;
|
|
902
|
+
private readonly client?;
|
|
903
|
+
constructor(baseInput: FileInput, baseSteps: readonly RecipeStep[], overlay: Recipe, watermarkOptions: WatermarkOptions, postSteps?: readonly RecipeStep[], presetDefaults?: PresetDefaults | undefined, scopedPresetDefaults?: PresetDefaults | undefined, client?: GislClient | undefined);
|
|
904
|
+
/** Reduce the watermarked output's size. See {@link Recipe.compress}. */
|
|
905
|
+
compress(optimize?: OptimizeFor, options?: Record<string, unknown>): WatermarkedRecipe;
|
|
906
|
+
/** Change the watermarked output's format. See {@link Recipe.convert}. Option keys validated pre-upload. */
|
|
907
|
+
convert(format: string, options?: ConvertOptions): WatermarkedRecipe;
|
|
908
|
+
/** Thumbnail the watermarked output. `width` AND `height` are required; validated pre-upload. */
|
|
909
|
+
thumbnail(options: ThumbnailOptions): WatermarkedRecipe;
|
|
910
|
+
/**
|
|
911
|
+
* Lower to the watermark DAG: a `src_0` passthrough/base-steps job + a `src_1`
|
|
912
|
+
* passthrough/overlay-steps job + one `watermark` job whose `inputs[]` consume
|
|
913
|
+
* them via `job_output` (role base/overlay) and whose `operations[]` is
|
|
914
|
+
* `[image_watermark|video_watermark, ...post-watermark ops]`. `fileIds` is
|
|
915
|
+
* `[baseId, overlayId]` (upload order). Throws pre-lowering if the base media
|
|
916
|
+
* is undetectable/unsupported (the planned-op gate).
|
|
917
|
+
*
|
|
918
|
+
* @internal Consumed by {@link run}/{@link submit} (after upload) + the parity harness.
|
|
919
|
+
*/
|
|
920
|
+
toWorkflowPayload(fileIds: readonly string[], callbackUrl?: string): WorkflowCreatePayload;
|
|
921
|
+
/** The number of post-watermark ops chained so far (introspection / tests). */
|
|
922
|
+
get stepCount(): number;
|
|
923
|
+
/**
|
|
924
|
+
* Execute end-to-end: upload base + overlay, create the watermark workflow,
|
|
925
|
+
* await terminal (SSE with poll fallback), then resolve ONLY the watermark
|
|
926
|
+
* output into a {@link RunResult}. Requires a client bound at construction.
|
|
927
|
+
* Mirrors {@link MergedRecipe.run}.
|
|
928
|
+
*/
|
|
929
|
+
run(options?: {
|
|
930
|
+
maxWait?: string | number;
|
|
931
|
+
onProgress?: (event: ProgressEvent) => void;
|
|
932
|
+
signal?: AbortSignal;
|
|
933
|
+
pollIntervalMs?: number;
|
|
934
|
+
probeBeforeCreate?: boolean;
|
|
935
|
+
probeTimeoutMs?: number;
|
|
936
|
+
}): Promise<RunResult>;
|
|
937
|
+
/**
|
|
938
|
+
* Fire-and-forget: upload base + overlay + create the watermark workflow
|
|
939
|
+
* (wiring `webhook` into `callback_url` when given), return a client-bound
|
|
940
|
+
* {@link Handle}. Does NOT wait for terminal status. Mirrors {@link MergedRecipe.submit}.
|
|
941
|
+
*/
|
|
942
|
+
submit(webhook?: string, options?: {
|
|
943
|
+
probeBeforeCreate?: boolean;
|
|
944
|
+
probeTimeoutMs?: number;
|
|
945
|
+
}): Promise<Handle>;
|
|
946
|
+
/** Base + overlay inputs, in upload/lowering order (`[base, overlay]`). */
|
|
947
|
+
private inputsInOrder;
|
|
948
|
+
/**
|
|
949
|
+
* Validate the watermark BEFORE any upload: the base must route to a shippable
|
|
950
|
+
* wire op (throws for undetectable/unsupported/planned bases), and the overlay
|
|
951
|
+
* must be an image. Shared by {@link run}/{@link submit}. Mirrors
|
|
952
|
+
* {@link MergedRecipe.validatePreUpload}.
|
|
953
|
+
*/
|
|
954
|
+
private validatePreUpload;
|
|
955
|
+
/**
|
|
956
|
+
* Upload base + overlay (verbatim for a pre-uploaded id; uploading a path /
|
|
957
|
+
* blob otherwise) then create ONE watermark workflow. Validates pre-upload.
|
|
958
|
+
* Shared first half of {@link run} + {@link submit}; mirrors
|
|
959
|
+
* {@link MergedRecipe._uploadAllAndCreate}.
|
|
960
|
+
*/
|
|
961
|
+
private _uploadAllAndCreate;
|
|
962
|
+
/**
|
|
963
|
+
* Lower the post-watermark chain over a synthetic input whose extension
|
|
964
|
+
* matches the watermark OUTPUT media (image→png, video→mp4) so
|
|
965
|
+
* `compress(optimize)` resolves the correct preset — mirrors
|
|
966
|
+
* {@link MergedRecipe.lowerPostSteps}.
|
|
967
|
+
*/
|
|
968
|
+
private lowerPostSteps;
|
|
969
|
+
private withStep;
|
|
970
|
+
}
|
|
779
971
|
export {};
|