@giveitsmaller/sdk 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +8 -15
  3. package/dist/_audit.js +14 -4
  4. package/dist/builder.d.ts +5 -4
  5. package/dist/builder.js +16 -16
  6. package/dist/client.d.ts +17 -7
  7. package/dist/client.js +116 -62
  8. package/dist/ergonomic/image_output_routes.d.ts +30 -0
  9. package/dist/ergonomic/image_output_routes.js +82 -11
  10. package/dist/ergonomic/option_types.d.ts +34 -1
  11. package/dist/ergonomic/option_types.js +5 -1
  12. package/dist/ergonomic/option_validation.d.ts +19 -1
  13. package/dist/ergonomic/option_validation.js +34 -1
  14. package/dist/ergonomic/preset_resolver.d.ts +2 -2
  15. package/dist/ergonomic/preset_resolver.js +6 -10
  16. package/dist/ergonomic/presets/index.d.ts +9 -8
  17. package/dist/ergonomic/presets/index.js +1 -9
  18. package/dist/errors.d.ts +105 -3
  19. package/dist/errors.js +136 -2
  20. package/dist/file-first.d.ts +234 -16
  21. package/dist/file-first.js +692 -175
  22. package/dist/generated/sdk_spec/enums.d.ts +0 -26
  23. package/dist/generated/sdk_spec/enums.js +0 -16
  24. package/dist/generated/sdk_spec/errors.d.ts +1 -1
  25. package/dist/generated/sdk_spec/errors.js +12 -0
  26. package/dist/generated/sdk_spec/presets.js +0 -14
  27. package/dist/generated/sdk_spec/version.d.ts +2 -2
  28. package/dist/generated/sdk_spec/version.js +2 -2
  29. package/dist/gisl.d.ts +93 -5
  30. package/dist/gisl.js +72 -2
  31. package/dist/handle.d.ts +6 -1
  32. package/dist/handle.js +42 -13
  33. package/dist/index.core.d.ts +10 -8
  34. package/dist/index.core.js +11 -3
  35. package/dist/merge.d.ts +12 -0
  36. package/dist/merge.js +14 -2
  37. package/dist/retry-metadata.d.ts +37 -0
  38. package/dist/retry-metadata.js +86 -0
  39. package/dist/sse.d.ts +2 -1
  40. package/dist/sse.js +26 -6
  41. package/dist/types.d.ts +54 -4
  42. package/dist/types.js +1 -0
  43. package/package.json +3 -3
  44. package/dist/ergonomic/presets/document_pdf_compress.d.ts +0 -12
  45. package/dist/ergonomic/presets/document_pdf_compress.js +0 -33
@@ -63,20 +63,6 @@ export declare const AudioSampleRate: {
63
63
  readonly _48000: 48000;
64
64
  };
65
65
  export type AudioSampleRate = typeof AudioSampleRate[keyof typeof AudioSampleRate];
66
- export declare const PdfProfile: {
67
- readonly Screen: "screen";
68
- readonly Ebook: "ebook";
69
- readonly Printer: "printer";
70
- readonly Prepress: "prepress";
71
- };
72
- export type PdfProfile = typeof PdfProfile[keyof typeof PdfProfile];
73
- export declare const PdfColorspace: {
74
- readonly Unchanged: "unchanged";
75
- readonly Rgb: "rgb";
76
- readonly Cmyk: "cmyk";
77
- readonly Grayscale: "grayscale";
78
- };
79
- export type PdfColorspace = typeof PdfColorspace[keyof typeof PdfColorspace];
80
66
  /** Catalog of every ergonomic enum (canonicalName → wire). */
81
67
  export declare const ERGONOMIC_ENUMS: {
82
68
  readonly OptimizeFor: {
@@ -135,16 +121,4 @@ export declare const ERGONOMIC_ENUMS: {
135
121
  readonly _44100: 44100;
136
122
  readonly _48000: 48000;
137
123
  };
138
- readonly PdfProfile: {
139
- readonly Screen: "screen";
140
- readonly Ebook: "ebook";
141
- readonly Printer: "printer";
142
- readonly Prepress: "prepress";
143
- };
144
- readonly PdfColorspace: {
145
- readonly Unchanged: "unchanged";
146
- readonly Rgb: "rgb";
147
- readonly Cmyk: "cmyk";
148
- readonly Grayscale: "grayscale";
149
- };
150
124
  };
@@ -77,20 +77,6 @@ export const AudioSampleRate = {
77
77
  _44100: 44100,
78
78
  _48000: 48000,
79
79
  };
80
- // PDF Ghostscript preset. Screen = smallest; Ebook = mid; Printer = 300dpi; Prepress = print-production.
81
- export const PdfProfile = {
82
- Screen: "screen",
83
- Ebook: "ebook",
84
- Printer: "printer",
85
- Prepress: "prepress",
86
- };
87
- // PDF output color space.
88
- export const PdfColorspace = {
89
- Unchanged: "unchanged",
90
- Rgb: "rgb",
91
- Cmyk: "cmyk",
92
- Grayscale: "grayscale",
93
- };
94
80
  /** Catalog of every ergonomic enum (canonicalName → wire). */
95
81
  export const ERGONOMIC_ENUMS = {
96
82
  OptimizeFor,
@@ -102,6 +88,4 @@ export const ERGONOMIC_ENUMS = {
102
88
  AudioBitrate,
103
89
  AudioCodec,
104
90
  AudioSampleRate,
105
- PdfProfile,
106
- PdfColorspace,
107
91
  };
@@ -1,4 +1,4 @@
1
- export type ErrorCode = "missing_credentials" | "feature_requires_auth" | "undeclared_asset" | "unused_asset" | "per_input_options_not_supported" | "chain_cardinality_mismatch" | "multipart_part_invalid" | "multipart_part_count_exceeded" | "timeout" | "aborted" | "validation_failed" | "validation_error" | "cyclic_workflow_edges" | "workflow_edge_references_unknown_job" | "reserved_job_id_pattern" | "cyclic_job_output_source_graph" | "auth_failed" | "feature_tier_restricted" | "tier_restriction" | "multipart_session_ownership" | "multipart_session_auth_required" | "multipart_session_not_found" | "upload_not_found" | "workflow_expired" | "balance_exhausted" | "feature_not_available" | "upload_size_exceeds_tier" | "upload_duration_exceeds_tier" | "probe_pending" | "requires_reencode" | "invalid_options" | "invalid_combination" | "missing_dependency" | "unsupported_value" | "type_mismatch" | "upload_failed" | "workflow_failed";
1
+ export type ErrorCode = "missing_credentials" | "feature_requires_auth" | "undeclared_asset" | "unused_asset" | "per_input_options_not_supported" | "chain_cardinality_mismatch" | "multipart_part_invalid" | "multipart_part_count_exceeded" | "timeout" | "aborted" | "validation_failed" | "validation_error" | "cyclic_workflow_edges" | "workflow_edge_references_unknown_job" | "reserved_job_id_pattern" | "cyclic_job_output_source_graph" | "auth_failed" | "feature_tier_restricted" | "tier_restriction" | "multipart_session_ownership" | "multipart_session_auth_required" | "multipart_session_not_found" | "upload_not_found" | "workflow_expired" | "balance_exhausted" | "feature_not_available" | "upload_size_exceeds_tier" | "upload_duration_exceeds_tier" | "probe_pending" | "requires_reencode" | "invalid_options" | "invalid_combination" | "missing_dependency" | "unsupported_value" | "type_mismatch" | "image_dimensions_too_large" | "upload_failed" | "workflow_failed";
2
2
  export type ErrorCategory = 'api' | 'config' | 'network' | 'auth' | 'validation' | 'chain';
3
3
  export type ErrorStatus = 'wired' | 'planned';
4
4
  export interface ErrorEntry {
@@ -467,6 +467,17 @@ export const ERROR_CODES = Object.freeze({
467
467
  "actual": "string",
468
468
  }),
469
469
  }),
470
+ "image_dimensions_too_large": Object.freeze({
471
+ code: "image_dimensions_too_large",
472
+ category: "api",
473
+ source: "ErrorEnvelope.error",
474
+ status: "wired",
475
+ httpStatus: 413,
476
+ retryable: false,
477
+ sdkClass: "GislUploadCapExceededError",
478
+ description: "413 — POST /api/uploads rejected a decodable raster image whose pixel area (width × height) exceeds the configured ceiling (UPLOAD_MAX_IMAGE_PIXELS, default 16 MP), read from the file header before decode (I0Rqj4jo). Wire `IMAGE_DIMENSIONS_TOO_LARGE`; flat ErrorEnvelope (no details[]). A pixel-dimension member of the upload-cap family — GislUploadCapExceededError, alongside the size/duration caps — matching the SDKs' existing status-based 413 dispatch (NOT GislValidationError, which is the structured-422 class). Retry only after downscaling the input.",
479
+ metadataSchema: Object.freeze({}),
480
+ }),
470
481
  "upload_failed": Object.freeze({
471
482
  code: "upload_failed",
472
483
  category: "network",
@@ -509,6 +520,7 @@ export const ERROR_CATEGORIES = Object.freeze({
509
520
  "upload_duration_exceeds_tier",
510
521
  "probe_pending",
511
522
  "requires_reencode",
523
+ "image_dimensions_too_large",
512
524
  "workflow_failed",
513
525
  ]),
514
526
  config: Object.freeze([
@@ -50,20 +50,6 @@ export const PRESETS = Object.freeze({
50
50
  "preset": "Slow",
51
51
  }),
52
52
  }),
53
- "document_pdf_compress": Object.freeze({
54
- Size: Object.freeze({
55
- "profile": "Screen",
56
- "grayscale": true,
57
- }),
58
- Balanced: Object.freeze({
59
- "profile": "Ebook",
60
- "grayscale": false,
61
- }),
62
- Quality: Object.freeze({
63
- "profile": "Printer",
64
- "grayscale": false,
65
- }),
66
- }),
67
53
  "document_office_compress": Object.freeze({
68
54
  Size: Object.freeze({
69
55
  "stripMacros": true,
@@ -1,3 +1,3 @@
1
- export declare const SDK_SPEC_VERSION: "2.2.0";
1
+ export declare const SDK_SPEC_VERSION: "2.3.0";
2
2
  export declare const PRESET_VERSION: "1.6";
3
- export declare const PRESET_CONFIG_HASH: "sha256:0fe215aede1da13430380384c58226d074c3b8344c091efc53e097c2930a34f7";
3
+ export declare const PRESET_CONFIG_HASH: "sha256:354814f7906f85be6a6ca5ede6c0722c83cdc058fd658a9bb2b0996520466c6d";
@@ -1,6 +1,6 @@
1
1
  // CODE GENERATED — DO NOT EDIT.
2
2
  // Source: compression_contracts/sdk-spec/ (see sdk-spec/README.md).
3
3
  // Regenerate with: scripts/generate.py.
4
- export const SDK_SPEC_VERSION = "2.2.0";
4
+ export const SDK_SPEC_VERSION = "2.3.0";
5
5
  export const PRESET_VERSION = "1.6";
6
- export const PRESET_CONFIG_HASH = "sha256:0fe215aede1da13430380384c58226d074c3b8344c091efc53e097c2930a34f7";
6
+ export const PRESET_CONFIG_HASH = "sha256:354814f7906f85be6a6ca5ede6c0722c83cdc058fd658a9bb2b0996520466c6d";
package/dist/gisl.d.ts CHANGED
@@ -19,12 +19,13 @@
19
19
  import { GislClient } from './client.js';
20
20
  import { GislConfigError, GislFeatureRequiresAuthError, GislMissingCredentialsError } from './errors.js';
21
21
  import { type ResolveCredentialsOptions, type ResolveEndpointOptions } from './credentials.js';
22
- import type { CreditsUsageOptions, GislClientConfig } from './types.js';
23
- import type { AccountLimits, CreditsBalanceResponse, CreditsUsageResponse } from '@giveitsmaller/contracts/openapi';
22
+ import type { CreditsUsageOptions, GislClientConfig, CapabilitiesSnapshot } from './types.js';
23
+ import type { AccountLimits, CreditsBalanceResponse, CreditsUsageResponse, OperationCapability, OperationType } from '@giveitsmaller/contracts/openapi';
24
24
  import { OperationBuilder } from './builder.js';
25
+ import type { ConvertOptions, ThumbnailOptions } from './ergonomic/option_types.js';
25
26
  import { MergeBuilder, type Asset, type MergeOptions } from './merge.js';
26
27
  import { PresetDefaults } from './ergonomic/presets/index.js';
27
- import { Recipe, FilesRecipe, type FileInput } from './file-first.js';
28
+ import { Recipe, FilesRecipe, BatchRecipe, type FileInput } from './file-first.js';
28
29
  import { Handle } from './handle.js';
29
30
  /**
30
31
  * Operations that may be invoked on a `gisl.anonymous()` client without
@@ -61,6 +62,21 @@ export interface GislCreateOptions extends ResolveCredentialsOptions, ResolveEnd
61
62
  * legitimately have no apiKey at construction time.
62
63
  */
63
64
  export declare function create(opts?: GislCreateOptions): Promise<ErgonomicClient>;
65
+ /**
66
+ * Operation types that need MORE THAN ONE input source, so they cannot be
67
+ * driven through the single-input {@link ErgonomicClient.operation} escape
68
+ * hatch — each has a dedicated multi-input builder (`merge(...)`,
69
+ * `files(...).archive(...)`, `file(a).watermark(b)`). Excluded from
70
+ * `operation()`'s op-type autocomplete.
71
+ */
72
+ export type MultiInputOperationType = 'merge' | 'archive' | 'image_watermark' | 'video_watermark' | 'audio_overlay' | 'audio_to_video';
73
+ /**
74
+ * Op types reachable via {@link ErgonomicClient.operation}: every
75
+ * {@link OperationType} except the {@link MultiInputOperationType} ones, widened
76
+ * with `(string & {})` so a genuinely-unknown (not-yet-in-contract) op type is
77
+ * still accepted while known single-input ops keep autocomplete.
78
+ */
79
+ export type SingleInputOperationType = Exclude<OperationType, MultiInputOperationType> | (string & {});
64
80
  /**
65
81
  * The ergonomic-client surface: `GislClient` (verbatim low-level API)
66
82
  * plus three ergonomic op-builder factories. Intersection type — at
@@ -91,6 +107,20 @@ export type ErgonomicClient = GislClient & {
91
107
  * returns a {@link Handle} whose `wait()`/`result()` partition per input.
92
108
  */
93
109
  files(inputs: ReadonlyArray<string | Blob | FileInput>): FilesRecipe;
110
+ /**
111
+ * Keyed multi-recipe batch entry point (FF7). Run N DISTINCT single-input
112
+ * keyed {@link Recipe}s as ONE workflow — build each via
113
+ * `client.file(input, key).<op>(...)` with a UNIQUE key, then
114
+ * `client.batch([r1, r2, …]).run()`. The partitioned {@link RunResult}
115
+ * addresses each entry's outputs by its caller key (`res.byKey('hero')`); one
116
+ * failed entry lands in `failed` without sinking the rest.
117
+ *
118
+ * v1 accepts ONLY single-input {@link Recipe} entries — the multi-input
119
+ * builders ({@link FilesRecipe} via `files(...)`, `merge(...)`, `archive(...)`,
120
+ * `watermark(...)`) are rejected pre-upload with a typed {@link GislConfigError}.
121
+ * `.run()`-only; `.submit()` / reattach are a follow-up.
122
+ */
123
+ batch(recipes: ReadonlyArray<Recipe>): BatchRecipe;
94
124
  /**
95
125
  * Reattach to a previously-created workflow (FF5a). Returns a client-bound
96
126
  * {@link Handle} you can `.status()` / `.wait()` / `.result()`. The handle
@@ -100,8 +130,28 @@ export type ErgonomicClient = GislClient & {
100
130
  */
101
131
  workflow(id: string): Handle;
102
132
  compress(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
103
- convert(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
104
- thumbnail(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
133
+ /**
134
+ * Single-op convert. The target format rides the bag as the required
135
+ * `output_format` (the single-op builder has no positional format — that is
136
+ * the file-first `Recipe.convert(format, …)` surface). Extra keys are the
137
+ * typed {@link ConvertOptions}. A missing `output_format` is a compile-time
138
+ * error (uFbM31dC); an unknown key is a compile-time error for an INLINE bag
139
+ * only — aliased bags bypass TS excess-property checks — so the runtime guard
140
+ * remains the backstop (also for untyped JS callers).
141
+ */
142
+ convert(input: string | Blob, options: ConvertOptions & {
143
+ output_format: string;
144
+ }): OperationBuilder;
145
+ /**
146
+ * Single-op thumbnail. {@link ThumbnailOptions} requires `width` + `height`;
147
+ * omitting either is a compile-time error (uFbM31dC). An unknown key is a
148
+ * compile-time error for an INLINE bag only — aliased bags bypass TS
149
+ * excess-property checks — so the runtime guard remains the backstop (also
150
+ * for untyped JS callers).
151
+ */
152
+ thumbnail(input: string | Blob, options: ThumbnailOptions): OperationBuilder;
153
+ /** Geometric transform (rotate/flip). Passthrough; the op is `planned` (server 422s until Lambdas ship). */
154
+ transform(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
105
155
  /**
106
156
  * Merge ordered-sequence factory (T3). Accepts a variadic list of assets
107
157
  * (strings/Blobs/`handle()`/`asset()`) optionally terminated by a
@@ -135,6 +185,44 @@ export type ErgonomicClient = GislClient & {
135
185
  creditsUsage(options?: CreditsUsageOptions): Promise<CreditsUsageResponse>;
136
186
  /** Effective account limits / tier-resolved caps (sugar for `getAccountLimits()`). */
137
187
  limits(): Promise<AccountLimits>;
188
+ /**
189
+ * Operation-capability read helper (qUhxfDA5). A typed projection over
190
+ * `getSchema()` that surfaces the tier-scoped operation-capability matrix,
191
+ * the output-property table, and the image-encode capability matrix —
192
+ * without dropping to the low-level `getSchema()` and its not-modified union.
193
+ *
194
+ * Called with no argument it returns the full {@link CapabilitiesSnapshot};
195
+ * called with an operation type it returns just that op's
196
+ * {@link OperationCapability}, or `undefined` when the op is absent from the
197
+ * server's capability matrix.
198
+ *
199
+ * Degraded fallback: if the client is configured to force conditional
200
+ * revalidation (a static `If-None-Match` in `config.headers`) the schema
201
+ * fetch may 304 with no body — in that case the snapshot is empty / the
202
+ * per-op lookup is `undefined`.
203
+ */
204
+ capabilities(): Promise<CapabilitiesSnapshot>;
205
+ capabilities(opType: OperationType | (string & {})): Promise<OperationCapability | undefined>;
206
+ /**
207
+ * Generic operation escape hatch (qUhxfDA5). Build + run a SINGLE-input,
208
+ * SINGLE-operation job for an op type with no first-class verb (e.g.
209
+ * `text_watermark`, `split`, or a not-yet-in-contract op). `options` reach the
210
+ * wire unchanged — there is NO pre-upload validation (the server validates) and
211
+ * NO preset resolution unless `opType` is `compress`. Prefer the typed verbs
212
+ * (`compress` / `convert` / `thumbnail`) when they exist — they add local
213
+ * validation.
214
+ *
215
+ * Multi-input operations (`merge`, `archive`, overlay watermarks — see
216
+ * {@link MultiInputOperationType}) are REJECTED at compile time: passing one
217
+ * of those literals is a type error (its dedicated builder is `merge(...)`,
218
+ * `files(...).archive(...)`, or `file(a).watermark(b)`). A genuinely-unknown
219
+ * (not-yet-in-contract) op string is still accepted.
220
+ *
221
+ * The generic parameter enforces the exclusion: a known single-input op or an
222
+ * unknown string maps to itself, while a {@link MultiInputOperationType}
223
+ * literal maps to `never` (so it cannot be passed).
224
+ */
225
+ operation<Op extends SingleInputOperationType>(opType: Op extends MultiInputOperationType ? never : Op, input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
138
226
  };
139
227
  /**
140
228
  * The `gisl` namespace — primary ergonomic-layer entry point.
package/dist/gisl.js CHANGED
@@ -20,9 +20,10 @@ import { GislClient } from './client.js';
20
20
  import { GislConfigError, GislFeatureRequiresAuthError, GislMissingCredentialsError, } from './errors.js';
21
21
  import { resolveApiKey, resolveEndpoint, } from './credentials.js';
22
22
  import { OperationBuilder } from './builder.js';
23
+ import { validateVerbOptions, validateSingleOpConvertOptions, assertThumbnailDimensions, } from './ergonomic/option_validation.js';
23
24
  import { MergeBuilder, asset } from './merge.js';
24
25
  import { PresetDefaults } from './ergonomic/presets/index.js';
25
- import { Recipe, FilesRecipe, fileInput } from './file-first.js';
26
+ import { Recipe, FilesRecipe, BatchRecipe, fileInput } from './file-first.js';
26
27
  import { Handle } from './handle.js';
27
28
  // ---------------------------------------------------------------------------
28
29
  // Anonymous-capable operation allowlist (internal)
@@ -112,14 +113,42 @@ function wrapErgonomic(client, presetDefaults, scopedPresetDefaults) {
112
113
  return new FilesRecipe(resolved, [], presetDefaults, scopedPresetDefaults, target);
113
114
  };
114
115
  }
116
+ if (prop === 'batch') {
117
+ // Keyed multi-recipe batch entry point (FF7). Run N DISTINCT single-input
118
+ // keyed recipes as ONE workflow; run() partitions the RunResult per entry
119
+ // by the caller key given at `file(input, key)` time. Client-only ctor —
120
+ // each entry already captured its own preset defaults at `client.file(...)`
121
+ // time, so batch never re-plumbs presetDefaults/scopedPresetDefaults.
122
+ return (recipes) => new BatchRecipe(recipes, target);
123
+ }
115
124
  if (prop === 'workflow') {
116
125
  // Reattach to a previously-created workflow (FF5a). Returns a
117
126
  // client-bound Handle with no webhookSecret and no recipe key —
118
127
  // its RunResult is therefore keyless (succeeded[].key === null).
119
128
  return (id) => new Handle(id, undefined, target);
120
129
  }
121
- if (prop === 'compress' || prop === 'convert' || prop === 'thumbnail') {
130
+ if (prop === 'compress' || prop === 'convert' || prop === 'thumbnail' || prop === 'transform') {
122
131
  return (input, options = {}) => {
132
+ // ExVcchMz — validate the option bag pre-upload for the exported
133
+ // single-op builder so a bad bag (unknown key / missing thumbnail dims /
134
+ // missing convert target) fails locally instead of as a server 422.
135
+ // `compress` is EXCLUDED: it validates through the preset resolver
136
+ // (resolveCompressOptions / KNOWN_WIRE_FIELDS), not these guards.
137
+ // `convert` uses a SINGLE-OP-specific guard (NOT validateVerbOptions):
138
+ // the single-op builder has no positional format, so its target rides
139
+ // the bag as `output_format` — which the file-first convert guard would
140
+ // reject as positional-owned. `thumbnail` reuses the file-first guards
141
+ // (it has no positional-owned keys).
142
+ if (prop === 'convert')
143
+ validateSingleOpConvertOptions(options);
144
+ if (prop === 'thumbnail') {
145
+ validateVerbOptions('thumbnail', options);
146
+ assertThumbnailDimensions(options);
147
+ }
148
+ // `transform` is a passthrough (rotate/flip); no positional-owned keys
149
+ // and no required dims — just the generic key-validation.
150
+ if (prop === 'transform')
151
+ validateVerbOptions('transform', options);
123
152
  // T4b — pass client-scope presetDefaults into the builder so
124
153
  // .run()/.submit() consult the preset resolver. The Proxy's
125
154
  // closure carries the same reference for every per-call
@@ -178,6 +207,47 @@ function wrapErgonomic(client, presetDefaults, scopedPresetDefaults) {
178
207
  if (prop === 'limits') {
179
208
  return () => target.getAccountLimits();
180
209
  }
210
+ if (prop === 'capabilities') {
211
+ // qUhxfDA5 — READ/PROJECTION over getSchema() surfacing the three
212
+ // v2.124 capability fields (previously typed but with no ergonomic
213
+ // consumer). No arg → the full CapabilitiesSnapshot; an opType → that
214
+ // op's OperationCapability (or undefined when absent).
215
+ return async (opType) => {
216
+ const schema = await target.getSchema();
217
+ // capabilities() passes no conditional headers, so getSchema()
218
+ // normally returns the 200 hit with data. A 304 is only possible if
219
+ // the caller globally configured a conditional header (e.g. a static
220
+ // `If-None-Match` in `config.headers`) — an unusual, self-inflicted
221
+ // case. Rather than throw, degrade to an empty projection (documented
222
+ // on the method); a caller who forces revalidation gets no snapshot.
223
+ const data = schema.notModified ? undefined : schema.data;
224
+ const operations = data?.capabilities ?? {};
225
+ if (opType !== undefined) {
226
+ return operations[opType];
227
+ }
228
+ return {
229
+ operations,
230
+ outputProperties: data?.outputProperties ?? {},
231
+ ...(data?.imageEncodeCapabilities !== undefined
232
+ ? { imageEncode: data.imageEncodeCapabilities }
233
+ : {}),
234
+ };
235
+ };
236
+ }
237
+ if (prop === 'operation') {
238
+ // qUhxfDA5 — generic escape-hatch sibling of the single-op verbs
239
+ // (compress/convert/thumbnail). Builds a SINGLE-input, SINGLE-operation
240
+ // job for an op type with no typed verb (e.g. `text_watermark`, `split`,
241
+ // or a not-yet-in-contract op). Options ride through to the wire
242
+ // unchanged (no preset resolution unless opType is 'compress'); NO
243
+ // pre-upload validation — the server validates.
244
+ //
245
+ // Multi-input operations (merge, archive, image/video/audio overlay
246
+ // watermarks) canNOT be expressed here — they need multiple sources and
247
+ // have dedicated builders (`merge(...)`, `files(...).archive(...)`,
248
+ // `file(a).watermark(b)`). They are excluded from the op-type param.
249
+ return (opType, input, options = {}) => new OperationBuilder(target, opType, input, options, presetDefaults, scopedPresetDefaults);
250
+ }
181
251
  return Reflect.get(target, prop, receiver);
182
252
  },
183
253
  });
package/dist/handle.d.ts CHANGED
@@ -97,7 +97,7 @@ export declare class Handle {
97
97
  * This is the ONLY blocking accessor on a `Handle`.
98
98
  *
99
99
  * @param maxWait Wall-clock deadline for the wait + downloads (string suffix
100
- * `'2h'`/`'30m'`/`'120s'` or a number of milliseconds). Defaults to 300s,
100
+ * `'2h'`/`'30m'`/`'120s'` or a number of milliseconds). Defaults to 600s,
101
101
  * matching `Recipe.run()` / the PHP `Handle::wait()` default.
102
102
  * @throws {GislConfigError} reason `no_client` when no client is bound.
103
103
  * @throws {GislTimeoutError} when `maxWait` elapses before terminal.
@@ -125,6 +125,11 @@ export declare class Handle {
125
125
  * empty `keyByRef`, so each input's key is recovered from its `file-{i}`
126
126
  * ref (`"0"`, `"1"`, …). A submitted/reattached fan-out carries no
127
127
  * caller-supplied keys — keyed fan-out is a separate concern.
128
+ * - A `merge` / `archive` / `watermark` shape ({@link isMergeStatus} /
129
+ * {@link isArchiveStatus} / {@link isWatermarkStatus}) → project ONLY the
130
+ * terminal deliverable, filtering the `src_*` passthrough plumbing. The
131
+ * terminal ref is the downstream `post` job when post-`sole_op` steps were
132
+ * chained ({@link terminalOutputRef}), else the sole_op job itself.
128
133
  * - Anything else (the single-file {@link Recipe} path) →
129
134
  * {@link projectDownloadsToRunResult} keyed by this handle's `#key`
130
135
  * (the recipe key from a file-first `submit()`, or `null` on reattach).
package/dist/handle.js CHANGED
@@ -34,7 +34,7 @@
34
34
  */
35
35
  import { GislConfigError, GislNetworkError, GislResultNotReadyError, GislTimeoutError, SseEndedWithoutTerminal, } from './errors.js';
36
36
  import { _consumeSseToTerminal, _pollToTerminal, _parseMaxWait, } from './builder.js';
37
- import { projectDownloadsToRunResult, projectMultiJobToRunResult, isFanoutStatus, isMergeStatus, isArchiveStatus, isWatermarkStatus, } from './file-first.js';
37
+ import { projectDownloadsToRunResult, projectMultiJobToRunResult, isFanoutStatus, isMergeStatus, isArchiveStatus, isWatermarkStatus, isSoleOpChainStatus, soleOpChainDeliverableRef, _POST_STEP_JOB_REF, } from './file-first.js';
38
38
  import { LazyHttpDownloader } from './lazy-downloader.js';
39
39
  /**
40
40
  * The terminal workflow states. A status response in any of these states
@@ -80,6 +80,16 @@ export class StatusSnapshot {
80
80
  return { workflowId: this.workflowId, state: this.state };
81
81
  }
82
82
  }
83
+ /**
84
+ * The terminal deliverable's job ref for a `sole_op` DAG: the downstream
85
+ * post-steps job ({@link _POST_STEP_JOB_REF}, present when the caller chained
86
+ * ops after `watermark()` / `merge()`) when it exists, else the `sole_op` job
87
+ * itself. Lets a submitted/reattached {@link Handle} project the final output —
88
+ * not the intermediate `sole_op` artifact — without builder state. PIiUit28.
89
+ */
90
+ function terminalOutputRef(jobDownloads, soleOpRef) {
91
+ return jobDownloads.some((d) => d.ref === _POST_STEP_JOB_REF) ? _POST_STEP_JOB_REF : soleOpRef;
92
+ }
83
93
  /**
84
94
  * Handle to a created workflow. Carries `workflowId` + an optional
85
95
  * `webhookSecret` (the data the operation-first/merge `submit()` returns)
@@ -139,12 +149,12 @@ export class Handle {
139
149
  * This is the ONLY blocking accessor on a `Handle`.
140
150
  *
141
151
  * @param maxWait Wall-clock deadline for the wait + downloads (string suffix
142
- * `'2h'`/`'30m'`/`'120s'` or a number of milliseconds). Defaults to 300s,
152
+ * `'2h'`/`'30m'`/`'120s'` or a number of milliseconds). Defaults to 600s,
143
153
  * matching `Recipe.run()` / the PHP `Handle::wait()` default.
144
154
  * @throws {GislConfigError} reason `no_client` when no client is bound.
145
155
  * @throws {GislTimeoutError} when `maxWait` elapses before terminal.
146
156
  */
147
- async wait(maxWait = 300_000, onProgress) {
157
+ async wait(maxWait = 600_000, onProgress) {
148
158
  const client = this.requireClient();
149
159
  const deadline = Date.now() + _parseMaxWait(maxWait);
150
160
  let finalStatus;
@@ -172,13 +182,13 @@ export class Handle {
172
182
  });
173
183
  }
174
184
  if (Date.now() >= deadline) {
175
- throw new GislTimeoutError(`Workflow ${this.workflowId} reached terminal status but maxWait elapsed before downloads could be fetched`);
185
+ throw new GislTimeoutError(`Workflow ${this.workflowId} reached terminal status but maxWait elapsed before downloads could be fetched`, this.workflowId);
176
186
  }
177
187
  const downloads = await client.getWorkflowDownloads(this.workflowId);
178
188
  // TDqmkWpX: re-check AFTER the downloads fetch so a slow getWorkflowDownloads
179
189
  // cannot return a success past the advertised maxWait.
180
190
  if (Date.now() >= deadline) {
181
- throw new GislTimeoutError(`Workflow ${this.workflowId} downloads fetch completed after maxWait elapsed`);
191
+ throw new GislTimeoutError(`Workflow ${this.workflowId} downloads fetch completed after maxWait elapsed`, this.workflowId);
182
192
  }
183
193
  return this.project(finalStatus, downloads.downloads);
184
194
  }
@@ -212,6 +222,11 @@ export class Handle {
212
222
  * empty `keyByRef`, so each input's key is recovered from its `file-{i}`
213
223
  * ref (`"0"`, `"1"`, …). A submitted/reattached fan-out carries no
214
224
  * caller-supplied keys — keyed fan-out is a separate concern.
225
+ * - A `merge` / `archive` / `watermark` shape ({@link isMergeStatus} /
226
+ * {@link isArchiveStatus} / {@link isWatermarkStatus}) → project ONLY the
227
+ * terminal deliverable, filtering the `src_*` passthrough plumbing. The
228
+ * terminal ref is the downstream `post` job when post-`sole_op` steps were
229
+ * chained ({@link terminalOutputRef}), else the sole_op job itself.
215
230
  * - Anything else (the single-file {@link Recipe} path) →
216
231
  * {@link projectDownloadsToRunResult} keyed by this handle's `#key`
217
232
  * (the recipe key from a file-first `submit()`, or `null` on reattach).
@@ -221,13 +236,16 @@ export class Handle {
221
236
  if (isFanoutStatus(finalStatus)) {
222
237
  return projectMultiJobToRunResult(this.workflowId, finalStatus, jobDownloads, new Map(), downloader);
223
238
  }
224
- // A fluent `files([...]).merge(...)` combine — project ONLY the merged
225
- // output, filtering the `src_*` passthrough plumbing (which re-exposes the
226
- // raw inputs). Matches MergedRecipe.run()'s `ref === 'merge'` filter so a
239
+ // A fluent `files([...]).merge(...)` combine — project ONLY the terminal
240
+ // deliverable, filtering the `src_*` passthrough plumbing (which re-exposes
241
+ // the raw inputs). Matches MergedRecipe.run()'s terminal-output filter so a
227
242
  // submitted/reattached merge handle never surfaces the input artifacts
228
243
  // alongside the combined output (codex c1).
229
244
  if (isMergeStatus(finalStatus)) {
230
- const mergeDownloads = jobDownloads.filter((d) => d.ref === 'merge');
245
+ // Post-merge steps (PIiUit28) lower into the downstream `_POST_STEP_JOB_REF`
246
+ // job, which is then the deliverable; otherwise the `merge` job is.
247
+ const mergeOutputRef = terminalOutputRef(jobDownloads, 'merge');
248
+ const mergeDownloads = jobDownloads.filter((d) => d.ref === mergeOutputRef);
231
249
  return projectDownloadsToRunResult(this.workflowId, finalStatus, mergeDownloads, null, downloader);
232
250
  }
233
251
  // A fluent `files([...]).archive(...)` bundle — project ONLY the archive
@@ -237,14 +255,25 @@ export class Handle {
237
255
  const archiveDownloads = jobDownloads.filter((d) => d.ref === 'archive');
238
256
  return projectDownloadsToRunResult(this.workflowId, finalStatus, archiveDownloads, null, downloader);
239
257
  }
240
- // A fluent `file(...).watermark(overlay)` — project ONLY the watermark
241
- // output, filtering the `src_*` (base/overlay) passthrough plumbing. Matches
242
- // WatermarkedRecipe.run()'s `ref === 'watermark'` filter so a
258
+ // A fluent `file(...).watermark(overlay)` — project ONLY the terminal
259
+ // deliverable, filtering the `src_*` (base/overlay) passthrough plumbing.
260
+ // Matches WatermarkedRecipe.run()'s terminal-output filter so a
243
261
  // submitted/reattached watermark handle never surfaces the raw inputs.
244
262
  if (isWatermarkStatus(finalStatus)) {
245
- const watermarkDownloads = jobDownloads.filter((d) => d.ref === 'watermark');
263
+ const watermarkOutputRef = terminalOutputRef(jobDownloads, 'watermark');
264
+ const watermarkDownloads = jobDownloads.filter((d) => d.ref === watermarkOutputRef);
246
265
  return projectDownloadsToRunResult(this.workflowId, finalStatus, watermarkDownloads, null, downloader);
247
266
  }
267
+ // A single-input `sole_op` chain — e.g. `.textWatermark('x').compress()`
268
+ // lowered to a `text_watermark` job + downstream `post` job (IQc01rj0).
269
+ // Project ONLY the terminal deliverable, filtering the intermediate sole_op
270
+ // artifact. The recipe key is preserved (unlike the multi-input branches):
271
+ // this is the single-file path with a terminal-ref filter.
272
+ if (isSoleOpChainStatus(finalStatus)) {
273
+ const soleOpRef = soleOpChainDeliverableRef(finalStatus);
274
+ const soleOpDownloads = jobDownloads.filter((d) => d.ref === soleOpRef);
275
+ return projectDownloadsToRunResult(this.workflowId, finalStatus, soleOpDownloads, this.#key, downloader);
276
+ }
248
277
  return projectDownloadsToRunResult(this.workflowId, finalStatus, jobDownloads, this.#key, downloader);
249
278
  }
250
279
  /**
@@ -1,10 +1,11 @@
1
1
  export { GislClient, DEFAULT_MULTIPART_FIRST_CHUNK_SIZE } from './client.js';
2
2
  export { parseSseStream } from './sse.js';
3
- export type { CreditsUsageOptions, ListWorkflowsOptions, GetSchemaOptions, GetSchemaResult, PreflightClipError, PreflightClipsResult, ProbeWaitOptions, ProbeWaitResult, GislClientConfig, GislSseEvent, UploadOptions, WaitOptions, WorkflowCreatePayload, OperationDef, WorkflowSourcePayload, MultiInputSourcePayload, UploadSourcePayload, JobOutputSourcePayload, ExternalImportSourcePayload, ConnectionSourcePayload, JobInputV2Payload, JobDefinitionPayload, ExternalDestinationPayload, DeliveryPayload, DeliveryModePayload, DeliveryBundleFormatPayload, DeliverySelectionPayload, DeliverySelectionTypePayload, DeliveryOutputRefPayload, WorkflowProcessingPayload, ProcessingClassHintPayload, MultipartCheckpointState, _Sdk3HandCodedUploadedPart, _Sdk3HandCodedMultipartStatusResult, _Sdk3HandCodedPresignedPart, _Sdk3HandCodedPresignPartsResult, _Sdk3HandCodedKeepaliveResult, } from './types.js';
3
+ export type { CreditsUsageOptions, ListWorkflowsOptions, GetSchemaOptions, GetSchemaResult, CapabilitiesSnapshot, PreflightClipError, PreflightClipsResult, ProbeWaitOptions, ProbeWaitResult, GislClientConfig, GislSseEvent, GislSseParseFailure, UploadOptions, WaitOptions, WorkflowCreatePayload, OperationDef, WorkflowSourcePayload, MultiInputSourcePayload, UploadSourcePayload, JobOutputSourcePayload, ExternalImportSourcePayload, ConnectionSourcePayload, JobInputV2Payload, JobDefinitionPayload, ExternalDestinationPayload, DeliveryPayload, DeliveryModePayload, DeliveryBundleFormatPayload, DeliverySelectionPayload, DeliverySelectionTypePayload, DeliveryOutputRefPayload, WorkflowProcessingPayload, ProcessingClassHintPayload, MultipartCheckpointState, _Sdk3HandCodedUploadedPart, _Sdk3HandCodedMultipartStatusResult, _Sdk3HandCodedPresignedPart, _Sdk3HandCodedPresignPartsResult, _Sdk3HandCodedKeepaliveResult, } from './types.js';
4
4
  export { uploadSource, jobOutputSource, externalImportSource, connectionSource, } from './types.js';
5
5
  export type { GislConfigErrorMetadata } from './errors.js';
6
- export { GislError, GislApiError, GislValidationError, GislBalanceExhaustedError, GislTierRestrictedError, GislFeatureTierRestrictedError, GislFeatureNotAvailableError, GislWorkflowExpiredError, GislProbePendingError, GislAuthError, GislUploadCapExceededError, GislMultipartPartError, GislMultipartPartCountError, GislMultipartSessionNotFoundError, GislMultipartSessionOwnershipError, GislMultipartSessionAuthRequiredError, GislTimeoutError, GislAbortError, GislNetworkError, GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError, GislUndeclaredAssetError, GislUnusedAssetError, GislPerInputOptionsNotSupportedError, GislChainCardinalityMismatchError, GislBundleAlreadyArchivedError, GislNoSuchKeyError, GislSinkError, GislItemFailedError, GislResultNotReadyError, } from './errors.js';
6
+ export { GislError, GislApiError, GislValidationError, GislBalanceExhaustedError, GislLongFormConcurrencyError, GislTierRestrictedError, GislFeatureTierRestrictedError, GislFeatureNotAvailableError, GislWorkflowExpiredError, GislProbePendingError, GislAuthError, GislUploadCapExceededError, GislMultipartPartError, GislMultipartPartCountError, GislMultipartSessionNotFoundError, GislMultipartSessionOwnershipError, GislMultipartSessionAuthRequiredError, GislTimeoutError, GislAbortError, GislNetworkError, GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError, GislUndeclaredAssetError, GislUnusedAssetError, GislPerInputOptionsNotSupportedError, GislChainCardinalityMismatchError, GislBundleAlreadyArchivedError, GislNoSuchKeyError, GislSinkError, GislItemFailedError, GislResultNotReadyError, } from './errors.js';
7
7
  export type { GislApiErrorOptions, GislUploadCapKind } from './errors.js';
8
+ export type { ErrorCategory } from './generated/sdk_spec/errors.js';
8
9
  export { RunResult } from './file-first.js';
9
10
  export type { OutputFile, ItemResult, ItemFailure, Manifest, Downloader, } from './file-first.js';
10
11
  export { Recipe, fileInput } from './file-first.js';
@@ -15,24 +16,25 @@ export { ArchivedRecipe } from './file-first.js';
15
16
  export type { ArchiveRecipeOptions } from './file-first.js';
16
17
  export { WatermarkedRecipe } from './file-first.js';
17
18
  export type { WatermarkWireOp } from './file-first.js';
19
+ export { BatchRecipe } from './file-first.js';
18
20
  export { Handle, StatusSnapshot } from './handle.js';
19
21
  export { gisl, create } from './gisl.js';
20
- export type { GislCreateOptions, Environment, ErgonomicClient } from './gisl.js';
21
- export { presetDefaults, PresetDefaults, type PresetMedia, type PresetOp, type AnyPresetOptions, ImageCompressPresetOptions, type ImageCompressPresetOptionsInput, AudioCompressPresetOptions, type AudioCompressPresetOptionsInput, VideoCompressPresetOptions, type VideoCompressPresetOptionsInput, DocumentPdfCompressPresetOptions, type DocumentPdfCompressPresetOptionsInput, DocumentOfficeCompressPresetOptions, type DocumentOfficeCompressPresetOptionsInput, DocumentOdfCompressPresetOptions, type DocumentOdfCompressPresetOptionsInput, DocumentEpubCompressPresetOptions, type DocumentEpubCompressPresetOptionsInput, OptimizeFor, ImageMetadataPolicy, ImageFormat, VideoCodec, VideoPreset, VideoFit, AudioBitrate, AudioCodec, AudioSampleRate, PdfProfile, PdfColorspace, } from './ergonomic/presets/index.js';
22
+ export type { GislCreateOptions, Environment, ErgonomicClient, SingleInputOperationType, MultiInputOperationType, } from './gisl.js';
23
+ export { presetDefaults, PresetDefaults, type PresetMedia, type PresetOp, type AnyPresetOptions, ImageCompressPresetOptions, type ImageCompressPresetOptionsInput, AudioCompressPresetOptions, type AudioCompressPresetOptionsInput, VideoCompressPresetOptions, type VideoCompressPresetOptionsInput, DocumentOfficeCompressPresetOptions, type DocumentOfficeCompressPresetOptionsInput, DocumentOdfCompressPresetOptions, type DocumentOdfCompressPresetOptionsInput, DocumentEpubCompressPresetOptions, type DocumentEpubCompressPresetOptionsInput, OptimizeFor, ImageMetadataPolicy, ImageFormat, VideoCodec, VideoPreset, VideoFit, AudioBitrate, AudioCodec, AudioSampleRate, } from './ergonomic/presets/index.js';
22
24
  export { OperationBuilder, MapEachBuilder } from './builder.js';
23
25
  export { MergeBuilder, asset, handle, clip } from './merge.js';
24
26
  export type { Asset, ClipEntry, ClipOptions, MergeMediaKind, MergeOptions, SequenceEntry, } from './merge.js';
25
27
  export type { Artifact, ArtifactRef, JobBreakdown, OperationBreakdown, ProcessingProgressEvent, ProgressEvent, ResolvedOptions, ResolvedOptionsSources, Result, RunOptions, SubmitOptions, UploadProgressEvent, } from './builder.js';
26
28
  export { PRESET_VERSION, resolveCompressOptions } from './ergonomic/preset_resolver.js';
27
29
  export type { ResolveCompressOptionsInput, ResolveCompressOptionsOutput, } from './ergonomic/preset_resolver.js';
28
- export type { AccountLimits, AccountLimitsLimits, AccountLimitEntry, AudioWatermarkDecodeRequest, AudioWatermarkDecodeResponse, ContactRequest, CreditsBalanceResponse, CreditsUsageResponse, CreditTransaction, ExternalImportCreatedResponse, ExternalImportRequest, LoginUserRequest, LoginUser200ResponseData, LoginUser200ResponseDataUser, WorkflowCancelResponse, WorkflowResumeResponse, WorkflowPausedDetail, WorkflowPausedDetailLinks, UploadResponse, UploadConstraintsApplied, UploadProbeResponse, UploadProbeMediaMetadata, MultipartInitiateRequestMetadataHint, WorkflowCreateResponse, WorkflowStatusResponse, WorkflowListResponse, WorkflowSummary, WorkflowDownloadResponse, MetadataResponse, MetadataResponseDimensions, MetadataResponseExif, MetadataResponseExifGps, OperationsSchemaResponse, OperationSchemaDefinition, MimeGroupSchema, OptionSchema, PerValueAvailabilityEntry, PerRoleCardinalityEntry, RetryResponse, JobDownload, OperationDownload, DownloadBundle, WebhookPayload, WebhookOperationContext, JobResponse, OperationResponse, OperationResult, OperationResultMetrics, ExternalDestination, Delivery, DeliveryPlan, DeliveryPlanOutput, WorkflowProcessing, ProcessingPlan, ProcessingPlanJob, WorkflowEdge, WorkflowWarning, JobInputV2, WorkflowSource, UploadSource, JobOutputSource, ConnectionSource, ExternalImportToken, BalanceExhaustedResponse, BalanceExhaustedResponseAllOfLinks, TierRestrictionResponse, FeatureTierRestrictedResponse, FeatureNotAvailableResponse, FeatureViolation, WorkflowExpiredResponse, ProbePendingResponse, AuthErrorResponse, } from '@giveitsmaller/contracts/openapi';
30
+ export type { AccountLimits, AccountLimitsLimits, AccountLimitEntry, AudioWatermarkDecodeRequest, AudioWatermarkDecodeResponse, ContactRequest, CreditsBalanceResponse, CreditsUsageResponse, CreditTransaction, ExternalImportCreatedResponse, ExternalImportRequest, LoginUserRequest, LoginUser200ResponseData, LoginUser200ResponseDataUser, WorkflowCancelResponse, WorkflowResumeResponse, WorkflowPausedDetail, WorkflowPausedDetailLinks, UploadResponse, UploadConstraintsApplied, UploadProbeResponse, UploadProbeMediaMetadata, MultipartInitiateRequestMetadataHint, WorkflowCreateResponse, WorkflowStatusResponse, WorkflowListResponse, WorkflowSummary, WorkflowDownloadResponse, MetadataResponse, MetadataResponseDimensions, MetadataResponseExif, MetadataResponseExifGps, OperationsSchemaResponse, OperationCapability, OutputProperties, ImageEncodeCapabilities, OperationSchemaDefinition, MimeGroupSchema, OptionSchema, PerValueAvailabilityEntry, PerRoleCardinalityEntry, RetryResponse, JobDownload, OperationDownload, DownloadBundle, WebhookPayload, WebhookOperationContext, JobResponse, OperationResponse, OperationResult, OperationResultMetrics, ExternalDestination, Delivery, DeliveryPlan, DeliveryPlanOutput, WorkflowProcessing, ProcessingPlan, ProcessingPlanJob, WorkflowEdge, WorkflowWarning, JobInputV2, WorkflowSource, UploadSource, JobOutputSource, ConnectionSource, ExternalImportToken, BalanceExhaustedResponse, BalanceExhaustedResponseAllOfLinks, LongFormConcurrencyLimitResponse, LongFormConcurrencyLimitResponseAllOfLinks, TierRestrictionResponse, FeatureTierRestrictedResponse, FeatureNotAvailableResponse, FeatureViolation, WorkflowExpiredResponse, ProbePendingResponse, AuthErrorResponse, } from '@giveitsmaller/contracts/openapi';
29
31
  export { AudioWatermarkDecodeRequestMethodHintEnum, AudioWatermarkDecodeResponseMethodEnum, OperationInputModel, ExternalImportRequestProviderHintEnum, ContactSubject, CreditTransactionSourceBucket, UploadProbeStatus, UploadProbeProcessingClass, WorkflowCancelBillingEffect, WorkflowPauseRequiredAction, WorkflowStatus, WarningType, WorkflowWarningSeverity, OperationType, SseEventType, CallbackEventType, OperationStatus, JobStatus, JobInputV2RoleEnum, AuthErrorType, TierRestrictionKind, BalanceExhaustedResponseRequiredActionEnum, ProcessingClassReason, DeliveryPlanReason, UserTier, ProcessingClass, } from '@giveitsmaller/contracts/openapi';
30
32
  export type { SseOperationProgressData, SseOperationCompletedData, SseOperationFailedData, SseJobCompletedData, SseJobFailedData, SseWorkflowTerminalData, } from '@giveitsmaller/contracts/openapi';
31
33
  export type { MultiOutputCompletion, PageIndexed, PositionIndexed, Unindexed, } from '@giveitsmaller/contracts/asyncapi';
32
34
  import type { MultiOutputCompletion as _MultiOutputCompletion } from '@giveitsmaller/contracts/asyncapi';
33
35
  export type OperationResultOutputEntry = _MultiOutputCompletion['outputs'][number];
34
- export type { CompressImageOptions, CompressImageJpegOptions, CompressImagePngOptions, CompressImageAvifOptions, CompressVideoOptions, CompressAudioOptions, CompressDocumentPdfOptions, CompressDocumentOfficeOptions, CompressDocumentOdfOptions, CompressDocumentEpubOptions, ThumbnailImageOptions, ThumbnailVideoOptions, ThumbnailDocumentOptions, ConvertImageOptions, ConvertVideoOptions, ConvertAudioOptions, ConvertDocumentPdfOptions, MergeImageOptions, MergeVideoOptions, MergeVideoPerInputOptions, MergeAudioOptions, MergeAudioPerInputOptions, ArchiveOptions, ImageWatermarkImageOptions, ImageWatermarkImageGifOptions, TextWatermarkImageOptions, CustomLumaVideoOptions, AudioOverlayAudioOptions, AudioOverlayVideoOptions, AudioWatermarkAudioOptions, AudioWatermarkVideoOptions, AudioToVideoAudioOptions, VideoWatermarkVideoOptions, VideoTextWatermarkVideoOptions, SplitImageGifOptions, SplitDocumentPdfOptions, SplitAudioOptions, SplitVideoOptions, } from '@giveitsmaller/contracts/operations';
36
+ export type { CompressImageOptions, CompressImageJpegOptions, CompressImagePngOptions, CompressImageAvifOptions, CompressVideoOptions, CompressAudioOptions, CompressDocumentOfficeOptions, CompressDocumentOdfOptions, CompressDocumentEpubOptions, ThumbnailImageOptions, ThumbnailVideoOptions, ThumbnailDocumentOptions, TransformImageOptions, TransformImageGifOptions, TransformVideoOptions, TransformDocumentPdfOptions, ConvertImageOptions, ConvertVideoOptions, ConvertAudioOptions, ConvertDocumentPdfOptions, MergeImageOptions, MergeVideoOptions, MergeVideoPerInputOptions, MergeAudioOptions, MergeAudioPerInputOptions, ArchiveOptions, ImageWatermarkImageOptions, ImageWatermarkImageGifOptions, TextWatermarkImageOptions, CustomLumaVideoOptions, AudioOverlayAudioOptions, AudioOverlayVideoOptions, AudioWatermarkAudioOptions, AudioWatermarkVideoOptions, AudioToVideoAudioOptions, VideoWatermarkVideoOptions, VideoTextWatermarkVideoOptions, SplitImageGifOptions, SplitDocumentPdfOptions, SplitAudioOptions, SplitVideoOptions, } from '@giveitsmaller/contracts/operations';
35
37
  export { ImageWatermarkImageAnchor, ImageWatermarkImageGifAnchor, TextWatermarkImageAnchor, TextWatermarkImageFontFamily, TextWatermarkImageWatermarkMode, AudioOverlayAudioMode, AudioOverlayVideoMode, AudioOverlayVideoNoAudioTrackBehaviour, AudioWatermarkAudioMethod, AudioWatermarkAudioRobustness, AudioWatermarkAudioDensity, AudioWatermarkVideoMethod, AudioWatermarkVideoRobustness, AudioWatermarkVideoDensity, AudioToVideoAudioOutputResolution, AudioToVideoAudioImageFit, AudioToVideoAudioOutputFormat, VideoWatermarkVideoAnchor, VideoTextWatermarkVideoFontFamily, VideoTextWatermarkVideoWatermarkMode, VideoTextWatermarkVideoAnchor, SplitImageGifOutputFormat, SplitDocumentPdfMode, SplitAudioMode, SplitAudioPrecision, SplitVideoMode, SplitVideoPrecision, } from '@giveitsmaller/contracts/operations';
36
- export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata, audioToVideoMetadata, videoWatermarkMetadata, videoTextWatermarkMetadata, splitMetadata, } from '@giveitsmaller/contracts/operations';
37
- export type { ConvertOptions, ThumbnailOptions, TextWatermarkOptions, WatermarkOptions, WatermarkAnchor, } from './ergonomic/option_types.js';
38
+ export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata, audioToVideoMetadata, videoWatermarkMetadata, videoTextWatermarkMetadata, splitMetadata, transformMetadata, } from '@giveitsmaller/contracts/operations';
39
+ export type { ConvertOptions, ThumbnailOptions, TransformOptions, TextWatermarkOptions, WatermarkOptions, WatermarkOverlay, WatermarkAnchor, } from './ergonomic/option_types.js';
38
40
  export type { OperationMetadata, AvailabilityValue, AvailabilityEntry, FeatureEntry, MimeGroupMetadata, OptionMetadata, ProcessingClassConstraints, } from '@giveitsmaller/contracts/operations';