@giveitsmaller/sdk 0.6.0 → 0.7.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 +60 -0
- package/dist/builder.d.ts +406 -0
- package/dist/builder.js +706 -0
- package/dist/client.d.ts +10 -0
- package/dist/client.js +28 -2
- package/dist/credentials.d.ts +61 -0
- package/dist/credentials.js +200 -0
- package/dist/ergonomic/preset_resolver.d.ts +75 -0
- package/dist/ergonomic/preset_resolver.js +568 -0
- package/dist/ergonomic/presets/_translate.d.ts +11 -0
- package/dist/ergonomic/presets/_translate.js +35 -0
- package/dist/ergonomic/presets/audio_compress.d.ts +16 -0
- package/dist/ergonomic/presets/audio_compress.js +45 -0
- package/dist/ergonomic/presets/document_epub_compress.d.ts +14 -0
- package/dist/ergonomic/presets/document_epub_compress.js +34 -0
- package/dist/ergonomic/presets/document_odf_compress.d.ts +14 -0
- package/dist/ergonomic/presets/document_odf_compress.js +34 -0
- package/dist/ergonomic/presets/document_office_compress.d.ts +16 -0
- package/dist/ergonomic/presets/document_office_compress.js +40 -0
- package/dist/ergonomic/presets/document_pdf_compress.d.ts +14 -0
- package/dist/ergonomic/presets/document_pdf_compress.js +35 -0
- package/dist/ergonomic/presets/image_compress.d.ts +43 -0
- package/dist/ergonomic/presets/image_compress.js +95 -0
- package/dist/ergonomic/presets/index.d.ts +77 -0
- package/dist/ergonomic/presets/index.js +216 -0
- package/dist/ergonomic/presets/video_compress.d.ts +30 -0
- package/dist/ergonomic/presets/video_compress.js +83 -0
- package/dist/errors.d.ts +147 -1
- package/dist/errors.js +161 -0
- package/dist/generated/sdk_spec/enums.d.ts +195 -0
- package/dist/generated/sdk_spec/enums.js +127 -0
- package/dist/generated/sdk_spec/errors.d.ts +16 -0
- package/dist/generated/sdk_spec/errors.js +473 -0
- package/dist/generated/sdk_spec/index.d.ts +4 -0
- package/dist/generated/sdk_spec/index.js +7 -0
- package/dist/generated/sdk_spec/presets.d.ts +6 -0
- package/dist/generated/sdk_spec/presets.js +157 -0
- package/dist/generated/sdk_spec/version.d.ts +3 -0
- package/dist/generated/sdk_spec/version.js +6 -0
- package/dist/gisl.d.ts +112 -0
- package/dist/gisl.js +266 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +32 -4
- package/dist/merge.d.ts +142 -0
- package/dist/merge.js +411 -0
- package/dist/types.d.ts +12 -14
- package/dist/types.js +18 -0
- package/package.json +2 -2
package/dist/gisl.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ergonomic-layer entrypoint for the GISL SDK. Wraps the low-level
|
|
3
|
+
* `GislClient` (transport, multipart, SSE, downloads) with credential-chain
|
|
4
|
+
* resolution + ergonomic factory functions. Designed to feel native to a
|
|
5
|
+
* developer writing `import { gisl } from '@giveitsmaller/sdk'` and then
|
|
6
|
+
* `const client = await gisl.create();`.
|
|
7
|
+
*
|
|
8
|
+
* Scope of this card (T1, `wVU4xHx3`):
|
|
9
|
+
* - `gisl.create()` — full functionality. Resolves credentials + endpoint
|
|
10
|
+
* via `credentials.ts`, fails early with `GislMissingCredentialsError`
|
|
11
|
+
* when no apiKey is found AND the caller hasn't opted into cookie-mode
|
|
12
|
+
* or anonymous mode.
|
|
13
|
+
* - INTERNAL `_gislAnonymous` capability + `ANONYMOUS_ALLOWLIST` constant
|
|
14
|
+
* are wired but NOT publicly exported until the free-tier launch decides
|
|
15
|
+
* which operations are anonymous-capable (plan §12 open decision). A
|
|
16
|
+
* non-empty allowlist + the named export will arrive in a follow-up PR
|
|
17
|
+
* the moment user picks; this card avoids shipping a dead `gisl.anonymous()`.
|
|
18
|
+
*/
|
|
19
|
+
import { GislClient } from './client.js';
|
|
20
|
+
import { GislConfigError, GislFeatureRequiresAuthError, GislMissingCredentialsError } from './errors.js';
|
|
21
|
+
import { type ResolveCredentialsOptions, type ResolveEndpointOptions } from './credentials.js';
|
|
22
|
+
import type { GislClientConfig } from './types.js';
|
|
23
|
+
import { OperationBuilder } from './builder.js';
|
|
24
|
+
import { MergeBuilder, type Asset, type MergeOptions } from './merge.js';
|
|
25
|
+
import { PresetDefaults } from './ergonomic/presets/index.js';
|
|
26
|
+
/**
|
|
27
|
+
* Operations that may be invoked on a `gisl.anonymous()` client without
|
|
28
|
+
* raising `GislFeatureRequiresAuthError`. Empty until the free-tier launch
|
|
29
|
+
* decision lands (plan §12). Typed as a `readonly []` tuple (NOT
|
|
30
|
+
* `readonly string[]`) so the audit-gate compile-time assertion in
|
|
31
|
+
* `_audit.ts` fires if a future PR widens this without flipping the
|
|
32
|
+
* parking-decision + adding the public `gisl.anonymous()` export.
|
|
33
|
+
*
|
|
34
|
+
* Consumers must not depend on its emptiness today — only `package.json`
|
|
35
|
+
* `exports` keeps deep-imports blocked; the marker is internal.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export declare const ANONYMOUS_ALLOWLIST: readonly [];
|
|
40
|
+
export interface GislCreateOptions extends ResolveCredentialsOptions, ResolveEndpointOptions, Omit<GislClientConfig, 'baseUrl' | 'apiKey' | 'useSessionCookie'> {
|
|
41
|
+
/**
|
|
42
|
+
* Layered ergonomic preset defaults (T4a / VhIj4S7T). Built via
|
|
43
|
+
* `presetDefaults().<cell>(level, overrides?)…`. The resolver wiring
|
|
44
|
+
* that consumes this slot lands in T4b — until then, supplying this
|
|
45
|
+
* field is a no-op at workflow-create time.
|
|
46
|
+
*/
|
|
47
|
+
readonly presetDefaults?: PresetDefaults;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Construct an ergonomic-layer client. Resolves the API key + base URL via
|
|
51
|
+
* the credential chain (see `credentials.ts`) and constructs a low-level
|
|
52
|
+
* `GislClient`. Throws `GislMissingCredentialsError` synchronously before
|
|
53
|
+
* any HTTP I/O when no key is found AND neither `useSessionCookie` nor
|
|
54
|
+
* `allowAnonymous` is set.
|
|
55
|
+
*
|
|
56
|
+
* Cookie-mode (`useSessionCookie: true`) explicitly bypasses the missing-
|
|
57
|
+
* credentials check — browser SPAs that drive auth via `client.login()`
|
|
58
|
+
* legitimately have no apiKey at construction time.
|
|
59
|
+
*/
|
|
60
|
+
export declare function create(opts?: GislCreateOptions): Promise<ErgonomicClient>;
|
|
61
|
+
/**
|
|
62
|
+
* The ergonomic-client surface: `GislClient` (verbatim low-level API)
|
|
63
|
+
* plus three ergonomic op-builder factories. Intersection type — at
|
|
64
|
+
* runtime the Proxy synthesises the three methods on-demand. `input`
|
|
65
|
+
* accepts `string | Blob` matching `GislClient.uploadFile` (codex r1
|
|
66
|
+
* low 89cae59f4f04 — Blob/File uploads were previously rejected by the
|
|
67
|
+
* ergonomic factory's narrower string-only typing).
|
|
68
|
+
*/
|
|
69
|
+
export type ErgonomicClient = GislClient & {
|
|
70
|
+
compress(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
|
|
71
|
+
convert(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
|
|
72
|
+
thumbnail(input: string | Blob, options?: Record<string, unknown>): OperationBuilder;
|
|
73
|
+
/**
|
|
74
|
+
* Merge ordered-sequence factory (T3). Accepts a variadic list of assets
|
|
75
|
+
* (strings/Blobs/`handle()`/`asset()`) optionally terminated by a
|
|
76
|
+
* `MergeOptions` object. Returns a `MergeBuilder`; pin the play order
|
|
77
|
+
* with `.sequence(...)`.
|
|
78
|
+
*/
|
|
79
|
+
merge(...args: ReadonlyArray<string | Blob | Asset | MergeOptions>): MergeBuilder;
|
|
80
|
+
/**
|
|
81
|
+
* Immutable scoped derive (T4c — `ULAlOP6j`). Returns a new client
|
|
82
|
+
* with `defaults` layered on top of the parent's scoped defaults.
|
|
83
|
+
* Use for the "next N jobs" pattern — e.g. an evening batch needing
|
|
84
|
+
* higher quality without mutating the long-lived parent client.
|
|
85
|
+
*
|
|
86
|
+
* Identity: the derived client shares the SAME underlying low-level
|
|
87
|
+
* transport (baseUrl, apiKey, headers, timeouts, multipart, session
|
|
88
|
+
* cookie) by reference. Safe for concurrent parent + derived use.
|
|
89
|
+
*
|
|
90
|
+
* Merge semantics (codex r2 #5 — scalar leaf): scoped per-cell fields
|
|
91
|
+
* override the parent's scoped where defined; the parent's
|
|
92
|
+
* `client.presetDefaults` layer is unaffected and still contributes
|
|
93
|
+
* fields the scoped layer doesn't set.
|
|
94
|
+
*
|
|
95
|
+
* Does NOT re-resolve credentials. The derive never calls the
|
|
96
|
+
* credential chain or constructor — it composes new closure values
|
|
97
|
+
* over the existing transport.
|
|
98
|
+
*/
|
|
99
|
+
withPresetDefaults(defaults: PresetDefaults): ErgonomicClient;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* The `gisl` namespace — primary ergonomic-layer entry point.
|
|
103
|
+
* Exports `gisl.create()` only for v0.7; `gisl.anonymous()` lands once
|
|
104
|
+
* the anonymous-capable operation allowlist is non-empty (plan §12).
|
|
105
|
+
*/
|
|
106
|
+
export declare const gisl: {
|
|
107
|
+
readonly create: typeof create;
|
|
108
|
+
};
|
|
109
|
+
export type { Environment } from './credentials.js';
|
|
110
|
+
/** @internal */
|
|
111
|
+
export declare function _internalAnonymous(opts?: GislCreateOptions): Promise<GislClient>;
|
|
112
|
+
export { GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError };
|
package/dist/gisl.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ergonomic-layer entrypoint for the GISL SDK. Wraps the low-level
|
|
3
|
+
* `GislClient` (transport, multipart, SSE, downloads) with credential-chain
|
|
4
|
+
* resolution + ergonomic factory functions. Designed to feel native to a
|
|
5
|
+
* developer writing `import { gisl } from '@giveitsmaller/sdk'` and then
|
|
6
|
+
* `const client = await gisl.create();`.
|
|
7
|
+
*
|
|
8
|
+
* Scope of this card (T1, `wVU4xHx3`):
|
|
9
|
+
* - `gisl.create()` — full functionality. Resolves credentials + endpoint
|
|
10
|
+
* via `credentials.ts`, fails early with `GislMissingCredentialsError`
|
|
11
|
+
* when no apiKey is found AND the caller hasn't opted into cookie-mode
|
|
12
|
+
* or anonymous mode.
|
|
13
|
+
* - INTERNAL `_gislAnonymous` capability + `ANONYMOUS_ALLOWLIST` constant
|
|
14
|
+
* are wired but NOT publicly exported until the free-tier launch decides
|
|
15
|
+
* which operations are anonymous-capable (plan §12 open decision). A
|
|
16
|
+
* non-empty allowlist + the named export will arrive in a follow-up PR
|
|
17
|
+
* the moment user picks; this card avoids shipping a dead `gisl.anonymous()`.
|
|
18
|
+
*/
|
|
19
|
+
import { GislClient } from './client.js';
|
|
20
|
+
import { GislConfigError, GislFeatureRequiresAuthError, GislMissingCredentialsError, } from './errors.js';
|
|
21
|
+
import { resolveApiKey, resolveEndpoint, } from './credentials.js';
|
|
22
|
+
import { OperationBuilder } from './builder.js';
|
|
23
|
+
import { MergeBuilder, asset } from './merge.js';
|
|
24
|
+
import { PresetDefaults } from './ergonomic/presets/index.js';
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Anonymous-capable operation allowlist (internal)
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
/**
|
|
29
|
+
* Operations that may be invoked on a `gisl.anonymous()` client without
|
|
30
|
+
* raising `GislFeatureRequiresAuthError`. Empty until the free-tier launch
|
|
31
|
+
* decision lands (plan §12). Typed as a `readonly []` tuple (NOT
|
|
32
|
+
* `readonly string[]`) so the audit-gate compile-time assertion in
|
|
33
|
+
* `_audit.ts` fires if a future PR widens this without flipping the
|
|
34
|
+
* parking-decision + adding the public `gisl.anonymous()` export.
|
|
35
|
+
*
|
|
36
|
+
* Consumers must not depend on its emptiness today — only `package.json`
|
|
37
|
+
* `exports` keeps deep-imports blocked; the marker is internal.
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export const ANONYMOUS_ALLOWLIST = [];
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Factories
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* Construct an ergonomic-layer client. Resolves the API key + base URL via
|
|
47
|
+
* the credential chain (see `credentials.ts`) and constructs a low-level
|
|
48
|
+
* `GislClient`. Throws `GislMissingCredentialsError` synchronously before
|
|
49
|
+
* any HTTP I/O when no key is found AND neither `useSessionCookie` nor
|
|
50
|
+
* `allowAnonymous` is set.
|
|
51
|
+
*
|
|
52
|
+
* Cookie-mode (`useSessionCookie: true`) explicitly bypasses the missing-
|
|
53
|
+
* credentials check — browser SPAs that drive auth via `client.login()`
|
|
54
|
+
* legitimately have no apiKey at construction time.
|
|
55
|
+
*/
|
|
56
|
+
export async function create(opts = {}) {
|
|
57
|
+
// Extract presetDefaults BEFORE `_createInternal` destructures and
|
|
58
|
+
// strips it — the resolver needs the value for every operation call,
|
|
59
|
+
// not just construction. `_createInternal` still strips the slot
|
|
60
|
+
// from the low-level `GislClient` config (no leak into transport).
|
|
61
|
+
const presetDefaults = opts.presetDefaults;
|
|
62
|
+
return wrapErgonomic(await _createInternal(opts), presetDefaults);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compose the ergonomic operation surface (`.compress` / `.convert` /
|
|
66
|
+
* `.thumbnail`) on top of a `GislClient` via Proxy — matches the
|
|
67
|
+
* `wrapAnonymous` precedent (no prototype mutation). Layer order is
|
|
68
|
+
* builder-wrap INSIDE, anonymous-wrap OUTSIDE so the allowlist gate
|
|
69
|
+
* runs last in `_internalAnonymous` (see `_createInternal`).
|
|
70
|
+
*/
|
|
71
|
+
function wrapErgonomic(client, presetDefaults, scopedPresetDefaults) {
|
|
72
|
+
return new Proxy(client, {
|
|
73
|
+
get(target, prop, receiver) {
|
|
74
|
+
if (prop === 'compress' || prop === 'convert' || prop === 'thumbnail') {
|
|
75
|
+
return (input, options = {}) => {
|
|
76
|
+
// T4b — pass client-scope presetDefaults into the builder so
|
|
77
|
+
// .run()/.submit() consult the preset resolver. The Proxy's
|
|
78
|
+
// closure carries the same reference for every per-call
|
|
79
|
+
// builder construction.
|
|
80
|
+
// T4c — also forward the scopedPresetDefaults closure (from
|
|
81
|
+
// `withPresetDefaults`); `undefined` on root clients.
|
|
82
|
+
return new OperationBuilder(target, prop, input, options, presetDefaults, scopedPresetDefaults);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (prop === 'withPresetDefaults') {
|
|
86
|
+
// T4c — immutable scoped derive. Computes mergedScoped =
|
|
87
|
+
// (parent.scoped === undefined ? new : PresetDefaults.merge(
|
|
88
|
+
// parent.scoped, new)) and returns a new Proxy wrapping the SAME
|
|
89
|
+
// underlying GislClient `target` (identity preservation —
|
|
90
|
+
// baseUrl / apiKey / headers / timeouts / multipart / session-
|
|
91
|
+
// cookie all by reference). Does NOT re-trigger _createInternal
|
|
92
|
+
// / resolveApiKey (codex r2 invariant — derives never re-read
|
|
93
|
+
// env or profile).
|
|
94
|
+
return (defaults) => {
|
|
95
|
+
const mergedScoped = scopedPresetDefaults === undefined
|
|
96
|
+
? defaults
|
|
97
|
+
: PresetDefaults.merge(scopedPresetDefaults, defaults);
|
|
98
|
+
return wrapErgonomic(target, presetDefaults, mergedScoped);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (prop === 'merge') {
|
|
102
|
+
// merge(...) accepts a mix of:
|
|
103
|
+
// - Asset objects (handle/path) — declared explicitly
|
|
104
|
+
// - string | Blob — wrapped via `asset()`
|
|
105
|
+
// - MergeOptions (always LAST) — sniffed by the absence of asset shape
|
|
106
|
+
return (...args) => {
|
|
107
|
+
let mergeOpts = {};
|
|
108
|
+
let last = args.length > 0 ? args[args.length - 1] : undefined;
|
|
109
|
+
if (isMergeOptions(last)) {
|
|
110
|
+
mergeOpts = last;
|
|
111
|
+
args = args.slice(0, -1);
|
|
112
|
+
}
|
|
113
|
+
const declared = args.map((a) => {
|
|
114
|
+
if (typeof a === 'string' || a instanceof Blob)
|
|
115
|
+
return asset(a);
|
|
116
|
+
// Asset (handle or path).
|
|
117
|
+
return a;
|
|
118
|
+
});
|
|
119
|
+
return new MergeBuilder(target, declared, mergeOpts);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return Reflect.get(target, prop, receiver);
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Sniff whether the final argument to `merge(...)` is a `MergeOptions`
|
|
128
|
+
* object rather than an `Asset`. Heuristic: an `Asset` always has a
|
|
129
|
+
* `type` field with `'handle'` or `'path'`; a `MergeOptions` does not.
|
|
130
|
+
*/
|
|
131
|
+
function isMergeOptions(value) {
|
|
132
|
+
if (value === null || typeof value !== 'object')
|
|
133
|
+
return false;
|
|
134
|
+
if (typeof value.then === 'function')
|
|
135
|
+
return false;
|
|
136
|
+
if (value instanceof Blob)
|
|
137
|
+
return false;
|
|
138
|
+
const t = value.type;
|
|
139
|
+
if (t === 'handle' || t === 'path' || t === 'clip')
|
|
140
|
+
return false;
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Inner factory shared by `create()` and `_internalAnonymous()` — extracted
|
|
145
|
+
* so the anonymous branch can ENTIRELY skip the credential chain rather
|
|
146
|
+
* than just suppressing its throw (codex r1 high e9e1c1182d56 — without
|
|
147
|
+
* this, env-resolved keys would silently attach an Authorization header
|
|
148
|
+
* to anonymous calls and defeat the parking guarantee).
|
|
149
|
+
*
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
async function _createInternal(opts) {
|
|
153
|
+
const { apiKey: explicitKey, profile, profilePath, useSessionCookie, baseUrl, environment, allowAnonymous,
|
|
154
|
+
// T4a slot — stripped from transportConfig so it does not leak
|
|
155
|
+
// into the low-level `GislClientConfig` spread. The T4b resolver
|
|
156
|
+
// reads `opts.presetDefaults` directly via its own path.
|
|
157
|
+
presetDefaults: _presetDefaults, ...transportConfig } = opts;
|
|
158
|
+
void _presetDefaults;
|
|
159
|
+
const resolvedBaseUrl = resolveEndpoint({ baseUrl, environment });
|
|
160
|
+
// Anonymous mode entirely BYPASSES the credential chain. Any env / profile
|
|
161
|
+
// key that happens to exist on the host MUST NOT leak into the request
|
|
162
|
+
// (codex r1 high e9e1c1182d56). Cookie-mode also bypasses, since the
|
|
163
|
+
// caller authenticates via session cookie later.
|
|
164
|
+
if (allowAnonymous === true) {
|
|
165
|
+
const config = {
|
|
166
|
+
baseUrl: resolvedBaseUrl,
|
|
167
|
+
...transportConfig,
|
|
168
|
+
};
|
|
169
|
+
if (useSessionCookie !== undefined) {
|
|
170
|
+
config.useSessionCookie = useSessionCookie;
|
|
171
|
+
}
|
|
172
|
+
return wrapAnonymous(new GislClient(config));
|
|
173
|
+
}
|
|
174
|
+
// Cookie-mode: skip env / profile resolution entirely UNLESS the caller
|
|
175
|
+
// ALSO passes an explicit `{apiKey}` (the mixed case is legitimate — a
|
|
176
|
+
// cookie-authenticated SPA may also send a server-issued API key). Codex
|
|
177
|
+
// r2 medium 913e4d8073f5 — without this, useSessionCookie=true could
|
|
178
|
+
// silently pick up an ambient GISL_API_KEY or fail on a malformed local
|
|
179
|
+
// profile, neither of which a cookie-auth caller expects.
|
|
180
|
+
let resolvedKey;
|
|
181
|
+
if (useSessionCookie === true && (explicitKey === undefined || explicitKey === '')) {
|
|
182
|
+
resolvedKey = null;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
resolvedKey = await resolveApiKey({
|
|
186
|
+
apiKey: explicitKey,
|
|
187
|
+
profile,
|
|
188
|
+
profilePath,
|
|
189
|
+
useSessionCookie,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (resolvedKey === null && useSessionCookie !== true) {
|
|
193
|
+
throw new GislMissingCredentialsError('No API key found via explicit arg, GISL_API_KEY env, or ~/.gisl/credentials profile. ' +
|
|
194
|
+
'Pass {apiKey} explicitly, set GISL_API_KEY, populate ~/.gisl/credentials, ' +
|
|
195
|
+
'or pass {useSessionCookie: true} for browser session-cookie authentication.');
|
|
196
|
+
}
|
|
197
|
+
const config = {
|
|
198
|
+
baseUrl: resolvedBaseUrl,
|
|
199
|
+
...transportConfig,
|
|
200
|
+
};
|
|
201
|
+
if (resolvedKey !== null) {
|
|
202
|
+
config.apiKey = resolvedKey;
|
|
203
|
+
}
|
|
204
|
+
if (useSessionCookie !== undefined) {
|
|
205
|
+
config.useSessionCookie = useSessionCookie;
|
|
206
|
+
}
|
|
207
|
+
return new GislClient(config);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Wrap a `GislClient` so calls to non-allowlisted operations throw
|
|
211
|
+
* `GislFeatureRequiresAuthError` BEFORE any I/O. This is the internal
|
|
212
|
+
* capability that backs `gisl.anonymous()` once the allowlist is non-empty.
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
function wrapAnonymous(client) {
|
|
217
|
+
// Explicit Set<string> — `ANONYMOUS_ALLOWLIST` is currently typed as the
|
|
218
|
+
// empty tuple `readonly []` (audit-gate parking-invariant in _audit.ts).
|
|
219
|
+
// Without this, `new Set(ANONYMOUS_ALLOWLIST)` would infer `Set<never>`.
|
|
220
|
+
const allowlist = new Set(ANONYMOUS_ALLOWLIST);
|
|
221
|
+
return new Proxy(client, {
|
|
222
|
+
get(target, prop, receiver) {
|
|
223
|
+
const value = Reflect.get(target, prop, receiver);
|
|
224
|
+
if (typeof value !== 'function' || typeof prop !== 'string') {
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
// Allow base infrastructure methods that don't carry user operations.
|
|
228
|
+
if (prop.startsWith('_') ||
|
|
229
|
+
prop === 'login' ||
|
|
230
|
+
prop === 'logout' ||
|
|
231
|
+
prop === 'getSchema' ||
|
|
232
|
+
prop === 'submitContact' ||
|
|
233
|
+
prop === 'constructor') {
|
|
234
|
+
return value.bind(target);
|
|
235
|
+
}
|
|
236
|
+
// Allowlist gate: throw if the op isn't approved for anonymous use.
|
|
237
|
+
if (!allowlist.has(prop)) {
|
|
238
|
+
return () => {
|
|
239
|
+
throw new GislFeatureRequiresAuthError(prop, `Operation '${prop}' is not available on an anonymous client. ` +
|
|
240
|
+
`Use gisl.create({apiKey}) for authenticated access, or wait for the operation to be added to the anonymous allowlist.`);
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return value.bind(target);
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
// Public `gisl` namespace
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
/**
|
|
251
|
+
* The `gisl` namespace — primary ergonomic-layer entry point.
|
|
252
|
+
* Exports `gisl.create()` only for v0.7; `gisl.anonymous()` lands once
|
|
253
|
+
* the anonymous-capable operation allowlist is non-empty (plan §12).
|
|
254
|
+
*/
|
|
255
|
+
export const gisl = {
|
|
256
|
+
create,
|
|
257
|
+
};
|
|
258
|
+
// `_internalAnonymous` is the implementation behind the future public
|
|
259
|
+
// `gisl.anonymous()` export. Kept underscore-prefixed so it does not
|
|
260
|
+
// reach the audit gate as a public symbol.
|
|
261
|
+
/** @internal */
|
|
262
|
+
export async function _internalAnonymous(opts = {}) {
|
|
263
|
+
return _createInternal({ ...opts, allowAnonymous: true });
|
|
264
|
+
}
|
|
265
|
+
// Re-export error types for callers that want to `instanceof` them.
|
|
266
|
+
export { GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,15 +3,25 @@ export { verifyWebhook } from './webhook.js';
|
|
|
3
3
|
export { parseSseStream } from './sse.js';
|
|
4
4
|
export type { CreditsUsageOptions, GetSchemaOptions, GetSchemaResult, PreflightClipError, PreflightClipsResult, GislClientConfig, GislSseEvent, UploadOptions, WaitOptions, WorkflowCreatePayload, OperationDef, WorkflowSourcePayload, UploadSourcePayload, JobOutputSourcePayload, ExternalImportSourcePayload, ConnectionSourcePayload, JobInputV2Payload, JobDefinitionPayload, ExternalDestinationPayload, DeliveryPayload, DeliveryModePayload, DeliveryBundleFormatPayload, DeliverySelectionPayload, DeliverySelectionTypePayload, DeliveryOutputRefPayload, WorkflowProcessingPayload, ProcessingClassHintPayload, MultipartCheckpointState, _Sdk3HandCodedUploadedPart, _Sdk3HandCodedMultipartStatusResult, _Sdk3HandCodedPresignedPart, _Sdk3HandCodedPresignPartsResult, _Sdk3HandCodedKeepaliveResult, } from './types.js';
|
|
5
5
|
export { uploadSource, jobOutputSource, externalImportSource, connectionSource, } from './types.js';
|
|
6
|
-
export {
|
|
6
|
+
export type { GislConfigErrorMetadata } from './errors.js';
|
|
7
|
+
export { GislError, GislApiError, GislValidationError, GislBalanceExhaustedError, GislTierRestrictedError, GislFeatureTierRestrictedError, GislFeatureNotAvailableError, GislWorkflowExpiredError, GislProbePendingError, GislAuthError, GislUploadCapExceededError, GislMultipartPartError, GislMultipartPartCountError, GislMultipartSessionNotFoundError, GislMultipartSessionOwnershipError, GislMultipartSessionAuthRequiredError, GislTimeoutError, GislAbortError, GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError, GislUndeclaredAssetError, GislUnusedAssetError, GislPerInputOptionsNotSupportedError, GislChainCardinalityMismatchError, } from './errors.js';
|
|
7
8
|
export type { GislApiErrorOptions, GislUploadCapKind } from './errors.js';
|
|
8
|
-
export
|
|
9
|
+
export { gisl, create } from './gisl.js';
|
|
10
|
+
export type { GislCreateOptions, Environment, ErgonomicClient } from './gisl.js';
|
|
11
|
+
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, ImageMode, ImageFit, ImageMetadataPolicy, IccProfilePolicy, ImageFormat, VideoCodec, VideoPreset, VideoFit, AudioBitrate, AudioCodec, AudioSampleRate, PdfProfile, PdfColorspace, } from './ergonomic/presets/index.js';
|
|
12
|
+
export { OperationBuilder, MapEachBuilder } from './builder.js';
|
|
13
|
+
export { MergeBuilder, asset, handle, clip } from './merge.js';
|
|
14
|
+
export type { Asset, ClipEntry, ClipOptions, MergeMediaKind, MergeOptions, SequenceEntry, } from './merge.js';
|
|
15
|
+
export type { Artifact, ArtifactRef, Handle, JobBreakdown, OperationBreakdown, ProcessingProgressEvent, ProgressEvent, ResolvedOptions, ResolvedOptionsSources, Result, RunOptions, SubmitOptions, UploadProgressEvent, } from './builder.js';
|
|
16
|
+
export { PRESET_VERSION, resolveCompressOptions } from './ergonomic/preset_resolver.js';
|
|
17
|
+
export type { ResolveCompressOptionsInput, ResolveCompressOptionsOutput, } from './ergonomic/preset_resolver.js';
|
|
18
|
+
export type { AudioWatermarkDecodeRequest, AudioWatermarkDecodeResponse, ContactRequest, CreditsBalanceResponse, CreditsUsageResponse, CreditTransaction, ExternalImportCreatedResponse, ExternalImportRequest, LoginUserRequest, LoginUser200ResponseData, LoginUser200ResponseDataUser, WorkflowCancelResponse, WorkflowResumeResponse, WorkflowPausedDetail, WorkflowPausedDetailLinks, UploadResponse, UploadConstraintsApplied, UploadProbeResponse, UploadProbeMediaMetadata, MultipartInitiateRequestMetadataHint, WorkflowCreateResponse, WorkflowStatusResponse, WorkflowDownloadResponse, MetadataResponse, MetadataResponseDimensions, MetadataResponseExif, MetadataResponseExifGps, OperationsSchemaResponse, OperationSchemaDefinition, MimeGroupSchema, OptionSchema, PerValueAvailabilityEntry, PerRoleCardinalityEntry, RetryResponse, JobDownload, OperationDownload, 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';
|
|
9
19
|
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';
|
|
10
20
|
export type { SseOperationProgressData, SseOperationCompletedData, SseOperationFailedData, SseJobCompletedData, SseJobFailedData, SseWorkflowTerminalData, } from '@giveitsmaller/contracts/openapi';
|
|
11
21
|
export type { MultiOutputCompletion, PageIndexed, PositionIndexed, Unindexed, } from '@giveitsmaller/contracts/asyncapi';
|
|
12
22
|
import type { MultiOutputCompletion as _MultiOutputCompletion } from '@giveitsmaller/contracts/asyncapi';
|
|
13
23
|
export type OperationResultOutputEntry = _MultiOutputCompletion['outputs'][number];
|
|
14
|
-
export type { CompressImageOptions, CompressVideoOptions, CompressAudioOptions, CompressDocumentPdfOptions, CompressDocumentOfficeOptions, CompressDocumentOdfOptions, CompressDocumentEpubOptions, ThumbnailImageOptions, ThumbnailVideoOptions, ThumbnailDocumentOptions, ConvertImageOptions, ConvertVideoOptions, ConvertAudioOptions, ConvertDocumentPdfOptions, MergeImageOptions, MergeVideoOptions, MergeVideoPerInputOptions, MergeAudioOptions, MergeAudioPerInputOptions, ArchiveOptions, ImageWatermarkImageOptions, ImageWatermarkImageGifOptions,
|
|
15
|
-
export { ImageWatermarkImageAnchor, ImageWatermarkImageGifAnchor,
|
|
16
|
-
export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata, } from '@giveitsmaller/contracts/operations';
|
|
24
|
+
export type { CompressImageOptions, 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';
|
|
25
|
+
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';
|
|
26
|
+
export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata, audioToVideoMetadata, videoWatermarkMetadata, videoTextWatermarkMetadata, splitMetadata, } from '@giveitsmaller/contracts/operations';
|
|
17
27
|
export type { OperationMetadata, AvailabilityValue, AvailabilityEntry, FeatureEntry, MimeGroupMetadata, OptionMetadata, ProcessingClassConstraints, } from '@giveitsmaller/contracts/operations';
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,33 @@ export { verifyWebhook } from './webhook.js';
|
|
|
4
4
|
export { parseSseStream } from './sse.js';
|
|
5
5
|
export { uploadSource, jobOutputSource, externalImportSource, connectionSource, } from './types.js';
|
|
6
6
|
// Errors
|
|
7
|
-
export { GislError, GislApiError, GislValidationError, GislBalanceExhaustedError, GislTierRestrictedError, GislFeatureTierRestrictedError, GislFeatureNotAvailableError, GislWorkflowExpiredError, GislAuthError, GislUploadCapExceededError, GislMultipartPartError, GislMultipartPartCountError,
|
|
7
|
+
export { GislError, GislApiError, GislValidationError, GislBalanceExhaustedError, GislTierRestrictedError, GislFeatureTierRestrictedError, GislFeatureNotAvailableError, GislWorkflowExpiredError, GislProbePendingError, GislAuthError, GislUploadCapExceededError, GislMultipartPartError, GislMultipartPartCountError,
|
|
8
8
|
// SDK-3 (Wb6ebOMM) — typed errors for the 3 resume-support endpoints.
|
|
9
|
-
GislMultipartSessionNotFoundError, GislMultipartSessionOwnershipError, GislMultipartSessionAuthRequiredError, GislTimeoutError, GislAbortError,
|
|
9
|
+
GislMultipartSessionNotFoundError, GislMultipartSessionOwnershipError, GislMultipartSessionAuthRequiredError, GislTimeoutError, GislAbortError,
|
|
10
|
+
// T1 / wVU4xHx3 — local config-error tree (pre-I/O; sibling of GislApiError).
|
|
11
|
+
GislConfigError, GislMissingCredentialsError, GislFeatureRequiresAuthError,
|
|
12
|
+
// T3 / cuecCmb5 — merge-compose local validation errors.
|
|
13
|
+
GislUndeclaredAssetError, GislUnusedAssetError, GislPerInputOptionsNotSupportedError,
|
|
14
|
+
// T6 / aDR1jnyZ — chain-cardinality validation (dormant until chain
|
|
15
|
+
// methods on OperationBuilder ship; type + audit registration land
|
|
16
|
+
// here so the future chain-method PR is a pure addition).
|
|
17
|
+
GislChainCardinalityMismatchError, } from './errors.js';
|
|
18
|
+
// Ergonomic-layer entrypoint (T1 / wVU4xHx3) — `gisl.create()` factory +
|
|
19
|
+
// credential-chain types. `gisl.anonymous()` (public export) lands once
|
|
20
|
+
// the anonymous-capable operation allowlist is non-empty (plan §12).
|
|
21
|
+
export { gisl, create } from './gisl.js';
|
|
22
|
+
// Ergonomic preset defaults (T4a / VhIj4S7T) — typed leaf DTOs + immutable
|
|
23
|
+
// `PresetDefaults` builder + `presetDefaults()` factory + ergonomic enum
|
|
24
|
+
// re-exports. Resolver wiring (T4b) consumes `PresetDefaults.cellFor()`.
|
|
25
|
+
export { presetDefaults, PresetDefaults, ImageCompressPresetOptions, AudioCompressPresetOptions, VideoCompressPresetOptions, DocumentPdfCompressPresetOptions, DocumentOfficeCompressPresetOptions, DocumentOdfCompressPresetOptions, DocumentEpubCompressPresetOptions, OptimizeFor, ImageMode, ImageFit, ImageMetadataPolicy, IccProfilePolicy, ImageFormat, VideoCodec, VideoPreset, VideoFit, AudioBitrate, AudioCodec, AudioSampleRate, PdfProfile, PdfColorspace, } from './ergonomic/presets/index.js';
|
|
26
|
+
// Operation-builder surface (T2 / xVDTIm8C) — `client.compress/convert/thumbnail`
|
|
27
|
+
// returns an `OperationBuilder`; `.run()` projects to a flat `Result` /
|
|
28
|
+
// `.submit({webhook})` returns a `Handle`. Progress events are the
|
|
29
|
+
// SDK-synthesised `{phase:'upload'|'processing', ...}` discriminated union.
|
|
30
|
+
export { OperationBuilder, MapEachBuilder } from './builder.js';
|
|
31
|
+
export { MergeBuilder, asset, handle, clip } from './merge.js';
|
|
32
|
+
// T4b — preset resolver public surface (PRESET_VERSION constant + types).
|
|
33
|
+
export { PRESET_VERSION, resolveCompressOptions } from './ergonomic/preset_resolver.js';
|
|
10
34
|
export { AudioWatermarkDecodeRequestMethodHintEnum, AudioWatermarkDecodeResponseMethodEnum,
|
|
11
35
|
// OperationInputModel — value-bearing enum (`single` | `multi`).
|
|
12
36
|
// Surfaced on OperationSchemaDefinition.inputModel so form-renderers
|
|
@@ -25,10 +49,14 @@ AuthErrorType, TierRestrictionKind, BalanceExhaustedResponseRequiredActionEnum,
|
|
|
25
49
|
// aliases (no runtime value); the openapi versions carry both the
|
|
26
50
|
// string-union type and a const map. Per audit follow-up.
|
|
27
51
|
UserTier, ProcessingClass, } from '@giveitsmaller/contracts/openapi';
|
|
28
|
-
export { ImageWatermarkImageAnchor, ImageWatermarkImageGifAnchor,
|
|
52
|
+
export { ImageWatermarkImageAnchor, ImageWatermarkImageGifAnchor, TextWatermarkImageAnchor, TextWatermarkImageFontFamily, TextWatermarkImageWatermarkMode, AudioOverlayAudioMode, AudioOverlayVideoMode, AudioOverlayVideoNoAudioTrackBehaviour, AudioWatermarkAudioMethod, AudioWatermarkAudioRobustness, AudioWatermarkAudioDensity, AudioWatermarkVideoMethod, AudioWatermarkVideoRobustness, AudioWatermarkVideoDensity,
|
|
53
|
+
// New planned operation enums — contracts v2.15 (AJCLLGaG).
|
|
54
|
+
AudioToVideoAudioOutputResolution, AudioToVideoAudioImageFit, AudioToVideoAudioOutputFormat, VideoWatermarkVideoAnchor, VideoTextWatermarkVideoFontFamily, VideoTextWatermarkVideoWatermarkMode, VideoTextWatermarkVideoAnchor, SplitImageGifOutputFormat, SplitDocumentPdfMode, SplitAudioMode, SplitAudioPrecision, SplitVideoMode, SplitVideoPrecision, } from '@giveitsmaller/contracts/operations';
|
|
29
55
|
// Per-operation metadata sidecars. Inspect `availability`,
|
|
30
56
|
// `required_tier`, per-value gating, mime-group availability and
|
|
31
57
|
// per-feature flags before submitting a workflow — the API will
|
|
32
58
|
// otherwise reject planned ops with `feature_not_available` (422,
|
|
33
59
|
// surfaces as `GislFeatureNotAvailableError`).
|
|
34
|
-
export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata,
|
|
60
|
+
export { archiveMetadata, audioOverlayMetadata, audioWatermarkMetadata, compressMetadata, convertMetadata, customLumaMetadata, imageWatermarkMetadata, mergeMetadata, textWatermarkMetadata, thumbnailMetadata,
|
|
61
|
+
// New planned operation metadata sidecars — contracts v2.15 (AJCLLGaG).
|
|
62
|
+
audioToVideoMetadata, videoWatermarkMetadata, videoTextWatermarkMetadata, splitMetadata, } from '@giveitsmaller/contracts/operations';
|
package/dist/merge.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge-compose layer for the SDK ergonomic surface (T3 / cuecCmb5).
|
|
3
|
+
*
|
|
4
|
+
* `client.merge(...assets, options?)` returns a `MergeBuilder`. The builder
|
|
5
|
+
* separates WHAT (the asset set) from ORDER (the timeline):
|
|
6
|
+
*
|
|
7
|
+
* - `merge(a, b, c)` declares the asset set — each unique input is uploaded
|
|
8
|
+
* ONCE per run, even if referenced multiple times in the sequence.
|
|
9
|
+
* - `.sequence(...refs)` defines the play order. References may repeat
|
|
10
|
+
* freely; entries may be bare asset refs or `clip(ref, opts)` objects
|
|
11
|
+
* carrying per-position options.
|
|
12
|
+
* - No `.sequence(...)` => play in declared order, no transitions.
|
|
13
|
+
*
|
|
14
|
+
* Wire-truth boundaries (lowering.md §sequences):
|
|
15
|
+
* - Video merge per-input options: `transition`, `crossfadeDuration` only.
|
|
16
|
+
* - Audio merge per-input options: `transition`, `crossfadeDuration`,
|
|
17
|
+
* `gapDuration` only.
|
|
18
|
+
* - Image merge has NO per-input options today — `clip(ref)` is reuse/order
|
|
19
|
+
* only. Per-position transitions on image merges throw locally as
|
|
20
|
+
* `GislPerInputOptionsNotSupportedError`.
|
|
21
|
+
* - No per-clip `trimStart`/`trimEnd` today (contracts ticket iZzn5QrS
|
|
22
|
+
* tracks the fix). Workaround: pre-trim each clip via a chained
|
|
23
|
+
* `compress(file, trimStart, trimEnd)`.
|
|
24
|
+
*
|
|
25
|
+
* Local validation runs BEFORE any upload — undeclared refs and unused
|
|
26
|
+
* assets both fail fast so the caller saves bandwidth on typo'd composes.
|
|
27
|
+
*/
|
|
28
|
+
import type { GislClient } from './client.js';
|
|
29
|
+
import { type Handle, type Result, type RunOptions, type SubmitOptions } from './builder.js';
|
|
30
|
+
/**
|
|
31
|
+
* A declared merge asset. `path` carries a string or Blob (deduped by
|
|
32
|
+
* normalised source key); `handle` wraps an already-uploaded file (deduped
|
|
33
|
+
* by handle identity — same handle reference = same upload regardless of
|
|
34
|
+
* path). Use a handle for guaranteed reuse.
|
|
35
|
+
*/
|
|
36
|
+
export type Asset = {
|
|
37
|
+
readonly type: 'path';
|
|
38
|
+
readonly path: string | Blob;
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: 'handle';
|
|
41
|
+
readonly fileId: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Construct a path-asset. Bare-string arguments to `merge(...)` are
|
|
45
|
+
* implicitly wrapped via this helper.
|
|
46
|
+
*/
|
|
47
|
+
export declare function asset(path: string | Blob): Asset;
|
|
48
|
+
/**
|
|
49
|
+
* Wrap an already-uploaded file_id as a merge asset. Use this when the
|
|
50
|
+
* SAME logical file should be referenced from multiple merge runs with
|
|
51
|
+
* guaranteed-single-upload semantics.
|
|
52
|
+
*/
|
|
53
|
+
export declare function handle(fileId: string): Asset;
|
|
54
|
+
/**
|
|
55
|
+
* Per-position options carried by `clip(ref, opts)` entries. Image merges
|
|
56
|
+
* reject ANY per-input options today (see module docstring).
|
|
57
|
+
*/
|
|
58
|
+
export interface ClipOptions {
|
|
59
|
+
/** Transition to apply at this position (video/audio per-input only). */
|
|
60
|
+
readonly transition?: string;
|
|
61
|
+
/** Crossfade duration in seconds (when `transition` is crossfade). */
|
|
62
|
+
readonly crossfadeDuration?: number;
|
|
63
|
+
/** Gap duration in seconds (audio merge only). */
|
|
64
|
+
readonly gapDuration?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A sequence entry that carries per-position options. Use the `clip(...)`
|
|
68
|
+
* helper to construct.
|
|
69
|
+
*/
|
|
70
|
+
export interface ClipEntry {
|
|
71
|
+
readonly type: 'clip';
|
|
72
|
+
readonly asset: Asset;
|
|
73
|
+
readonly options: ClipOptions;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Construct a clip entry for `.sequence(...)`. The asset MUST already
|
|
77
|
+
* be in the merge's declared asset set.
|
|
78
|
+
*/
|
|
79
|
+
export declare function clip(ref: Asset, options?: ClipOptions): ClipEntry;
|
|
80
|
+
export type SequenceEntry = Asset | ClipEntry;
|
|
81
|
+
/**
|
|
82
|
+
* Inferred media kind. `merge` picks the wire variant from the inferred
|
|
83
|
+
* media; the SDK reads the FIRST asset's path/MIME to decide.
|
|
84
|
+
*/
|
|
85
|
+
export type MergeMediaKind = 'video' | 'audio' | 'image';
|
|
86
|
+
export interface MergeOptions {
|
|
87
|
+
/** Merge-level transition (applies to every join — image merge ONLY uses this). */
|
|
88
|
+
readonly transition?: string;
|
|
89
|
+
readonly crossfadeDuration?: number;
|
|
90
|
+
readonly gapDuration?: number;
|
|
91
|
+
readonly normalizeAudio?: boolean;
|
|
92
|
+
readonly codec?: string;
|
|
93
|
+
readonly crf?: number;
|
|
94
|
+
readonly preset?: string;
|
|
95
|
+
readonly targetSize?: string | number;
|
|
96
|
+
readonly transitionDuration?: number;
|
|
97
|
+
readonly fps?: number;
|
|
98
|
+
readonly durationPerImage?: number;
|
|
99
|
+
readonly loopCount?: number;
|
|
100
|
+
readonly output?: string;
|
|
101
|
+
readonly videoFormat?: string;
|
|
102
|
+
readonly outputType?: string;
|
|
103
|
+
/** Force the inferred media kind (skip the first-asset sniff). */
|
|
104
|
+
readonly mediaKind?: MergeMediaKind;
|
|
105
|
+
/** Bypass the unused-asset validation (rarely needed; usually a bug indicator). */
|
|
106
|
+
readonly allowUnusedAssets?: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Captures the (declared assets, options) for a merge. `.sequence(...)`
|
|
110
|
+
* pins the play order; without it, the declared order is used as-is
|
|
111
|
+
* with no per-input options.
|
|
112
|
+
*
|
|
113
|
+
* Local validation runs at `.run()`/`.submit()` time (BEFORE any upload)
|
|
114
|
+
* and throws one of `GislUndeclaredAssetError`, `GislUnusedAssetError`,
|
|
115
|
+
* or `GislPerInputOptionsNotSupportedError` if the compose is invalid.
|
|
116
|
+
*/
|
|
117
|
+
export declare class MergeBuilder {
|
|
118
|
+
private readonly client;
|
|
119
|
+
private readonly assets;
|
|
120
|
+
private readonly opOptions;
|
|
121
|
+
private sequenceEntries;
|
|
122
|
+
constructor(client: GislClient, assets: readonly Asset[], opOptions: MergeOptions);
|
|
123
|
+
/**
|
|
124
|
+
* Pin the merge play order. Each entry must reference an asset that
|
|
125
|
+
* was declared in the parent `merge(...)` call. Repeats are allowed
|
|
126
|
+
* and deduped on upload (one upload per unique declared asset).
|
|
127
|
+
*/
|
|
128
|
+
sequence(...entries: SequenceEntry[]): this;
|
|
129
|
+
run(options: RunOptions): Promise<Result>;
|
|
130
|
+
submit(options: SubmitOptions): Promise<Handle>;
|
|
131
|
+
/**
|
|
132
|
+
* Resolve the declared assets + sequence (or fall back to declared order),
|
|
133
|
+
* dedupe by identity, and run the local validators. The returned plan
|
|
134
|
+
* carries the SEQUENCE (positional entries) + the UNIQUE assets to upload.
|
|
135
|
+
*/
|
|
136
|
+
private planSequence;
|
|
137
|
+
private inferMediaKind;
|
|
138
|
+
private uploadUniqueAssets;
|
|
139
|
+
private buildPayload;
|
|
140
|
+
private opOptionsForResolved;
|
|
141
|
+
private awaitTerminal;
|
|
142
|
+
}
|