@stackshift-cloud/sdk 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +117 -0
  2. package/dist/asset-media-v2.d.ts +65 -0
  3. package/dist/asset-media-v2.js +1 -0
  4. package/dist/asset-workflows.d.ts +269 -0
  5. package/dist/asset-workflows.js +69 -0
  6. package/dist/assets-dam-types.d.ts +225 -0
  7. package/dist/assets-dam-types.js +1 -0
  8. package/dist/assets-dam.d.ts +96 -0
  9. package/dist/assets-dam.js +47 -0
  10. package/dist/assets-platform-types.d.ts +218 -0
  11. package/dist/assets-platform-types.js +1 -0
  12. package/dist/assets-platform.d.ts +55 -0
  13. package/dist/assets-platform.js +90 -0
  14. package/dist/assets-video-types.d.ts +116 -0
  15. package/dist/assets-video-types.js +1 -0
  16. package/dist/assets-video.d.ts +25 -0
  17. package/dist/assets-video.js +19 -0
  18. package/dist/assets.d.ts +21 -1
  19. package/dist/assets.js +85 -132
  20. package/dist/client.d.ts +10 -0
  21. package/dist/client.js +26 -6
  22. package/dist/generated/assets-contract.d.ts +512 -2
  23. package/dist/generated/assets-contract.js +102 -0
  24. package/dist/index.d.ts +21 -0
  25. package/dist/index.js +11 -0
  26. package/dist/mail-advanced-types.d.ts +9 -0
  27. package/dist/mail-billing.d.ts +34 -0
  28. package/dist/mail-billing.js +7 -0
  29. package/dist/mail-brands.d.ts +35 -0
  30. package/dist/mail-brands.js +17 -0
  31. package/dist/mail-campaigns.d.ts +72 -10
  32. package/dist/mail-campaigns.js +25 -2
  33. package/dist/mail-marketing.d.ts +84 -0
  34. package/dist/mail-marketing.js +24 -0
  35. package/dist/mail-migration.d.ts +16 -0
  36. package/dist/mail-migration.js +10 -0
  37. package/dist/mail-otp-types.d.ts +4 -0
  38. package/dist/mail-simulation.d.ts +4 -0
  39. package/dist/mail-simulation.js +1 -0
  40. package/dist/mail-subscribers.d.ts +39 -0
  41. package/dist/mail-subscribers.js +1 -0
  42. package/dist/mail-template-types.d.ts +8 -0
  43. package/dist/mail-tracking.d.ts +59 -0
  44. package/dist/mail-tracking.js +14 -0
  45. package/dist/mail-webhook-types.d.ts +4 -1
  46. package/dist/mail.d.ts +12 -0
  47. package/dist/mail.js +19 -0
  48. package/dist/types.d.ts +19 -0
  49. package/dist/upload-controller.d.ts +70 -0
  50. package/dist/upload-controller.js +223 -0
  51. package/dist/workload-security.d.ts +172 -0
  52. package/dist/workload-security.js +50 -0
  53. package/package.json +2 -2
package/README.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  Official JavaScript and TypeScript SDK for StackShift.
4
4
 
5
+ ## Governed media and galleries
6
+
7
+ Use a separate server-side client for each Assets space; the namespace is fixed on that client. Project membership does not grant Assets access.
8
+
9
+ ```ts
10
+ const studio = new StackShift({
11
+ apiKey: process.env.STACKSHIFT_API_KEY,
12
+ assetSpaceId: 'your-asset-space-uuid',
13
+ })
14
+ const page = await studio.assets.dam.publications({ status: 'published' })
15
+ if (page.next_cursor) {
16
+ const next = await studio.assets.dam.publications({ status: 'published', cursor: page.next_cursor })
17
+ }
18
+ const gallery = await studio.assets.dam.resolveGallery('published-gallery-uuid')
19
+ ```
20
+
21
+ `assets.dam` also exposes collaborators, typed metadata schemas, bucket governance, publication transitions, model processing, gallery drafts and picker capabilities. Updates use explicit revisions. Submission needs `assets:write`, review needs `assets:admin`, and publication/withdrawal needs `assets:publish`, in addition to the corresponding Assets grant.
22
+
23
+ Keep account credentials on your server. Give `@stackshift-cloud/assets-picker` a short-lived, origin-restricted capability; give `@stackshift-cloud/assets-gallery` a server resolver for approved media. Store publication/gallery IDs and versions, never delivery URLs. Model processing is an explicitly enabled pilot and requires the qualified isolated worker described in `packages/assets-model-processor/README.md`.
24
+
5
25
  ## Install
6
26
 
7
27
  ```bash
@@ -218,6 +238,66 @@ export class AssetsService {
218
238
  }
219
239
  ```
220
240
 
241
+ ## Storage connections and migrations
242
+
243
+ Use AWS AssumeRole for S3 whenever possible. The returned `external_id` belongs in the role trust policy; credentials are write-only and are never returned by Stackshift.
244
+
245
+ ```ts
246
+ const connection = await stackshift.assets.connections.create({
247
+ provider: 'aws_s3',
248
+ name: 'Production media',
249
+ configuration: {
250
+ bucket: 'acme-media',
251
+ region: 'us-east-1',
252
+ role_arn: 'arn:aws:iam::123456789012:role/StackshiftAssets',
253
+ auth_type: 'assume_role',
254
+ },
255
+ })
256
+
257
+ await stackshift.assets.connections.verify(connection.id)
258
+
259
+ const dryRun = await stackshift.assets.migrations.start({
260
+ source_connection_id: connection.id,
261
+ destination_bucket_id: 'assets_bucket_id',
262
+ source_prefix: 'legacy',
263
+ conflict_policy: 'skip',
264
+ dry_run: true,
265
+ })
266
+
267
+ const report = await stackshift.assets.migrations.downloadReport(dryRun.id, 'csv')
268
+ ```
269
+
270
+ Native Stackshift S2 storage uses a bucket reference and internal authorization, never copied S2 access keys:
271
+
272
+ ```ts
273
+ const s2 = await stackshift.assets.storage.createS2Bucket({ name: 'asset-originals', region: 'us-east-1' })
274
+ await stackshift.assets.storage.configure('assets_bucket_id', 3, {
275
+ storage_mode: 'stackshift_s2',
276
+ s2_bucket_id: s2.id,
277
+ object_prefix: 'originals',
278
+ derivative_prefix: 'derived',
279
+ auto_extract_text: true,
280
+ })
281
+ ```
282
+
283
+ ## OCR and browser upload capabilities
284
+
285
+ ```ts
286
+ const extraction = await stackshift.assets.text.start('asset_id', { language: 'eng' })
287
+ const current = await stackshift.assets.text.get('asset_id')
288
+
289
+ const capability = await stackshift.assets.uploadCapabilities.create({
290
+ bucket: 'uploads',
291
+ key_prefix: 'customers/user_123',
292
+ allowed_mime_types: ['image/png', 'image/jpeg'],
293
+ allowed_origins: ['https://app.example.com'],
294
+ max_bytes: 25 * 1024 * 1024,
295
+ expires_in: '15m',
296
+ })
297
+ ```
298
+
299
+ Create capabilities only in trusted backend code. Send `capability.token` to `@stackshift-cloud/assets-widget`; never put the Stackshift API key in a browser bundle.
300
+
221
301
  For larger uploads, create a signed upload URL on your NestJS server and let the browser upload directly.
222
302
 
223
303
  ## Direct browser uploads
@@ -247,3 +327,40 @@ await fetch(upload.url, {
247
327
  This is the recommended pattern for React, Next.js, TanStack Start, and any browser app. The browser never receives your StackShift API key.
248
328
 
249
329
  StackShift chooses storage nodes, writes to StackShift-owned disks, replicates internally, and returns CDN-ready asset URLs. SDK users never choose storage nodes and never receive disk paths.
330
+
331
+ ### Campaign drafts and engagement
332
+
333
+ Create campaigns with `content: { subject, html, text, editorMode: 'code' }`, or keep using a template/version. `mail.campaigns.update(id, { ...draft, revision })` saves a full draft; `preview`, `test`, `send(id, revision)`, and `schedule(id, sendAt, revision)` support review and dispatch. A stale revision returns 409.
334
+
335
+ Mail send inputs accept `tracking: { opens: false, clicks: true }`. Each omitted setting inherits the workspace default. Use `mail.tracking.settings()` / `updateSettings()`, `message(id)` / `campaign(id)` for reports, and `domains()` / `createDomain()` / `verifyDomain()` / `updateDomain()` for branded hosts. Features must be enabled on the deployment. Opens are approximate; suspected automation is reported separately. Detailed activity expires after 90 days. Tests and OTPs never track.
336
+
337
+ ### Isolated testing, brands, migration, and spending
338
+
339
+ Use a `sspat_test_` credential with `simulation: { scenario: 'delayed' }` for a 60-second simulated delay. Other outcomes are delivered, bounced, and complained. Test resources are isolated; no real email is delivered.
340
+
341
+ ```ts
342
+ const brand = await client.mail.brands.create({ name: 'Product', editableFields: ['company'] })
343
+ const audience = await client.mail.audiences.create({ brandId: brand.id, name: 'Product news' })
344
+ ```
345
+
346
+ Every audience requires an explicit brand. Contact names/attributes are shared within that brand while consent stays per audience. `mail.automations`, `mail.forms`, and `mail.segments` expose audience-owned resources.
347
+
348
+ `mail.migration` supports public DNS audits/plans and authenticated checklists. `mail.billing.summary()` and `mail.campaigns.estimate(id)` expose allowance, credit, and blocking reasons. Pass approved maximum kobo as the third argument to `send(id, revision, approvedMaxKobo)` or the fourth to `schedule(id, sendAt, revision, approvedMaxKobo)`. Zero is a valid hard maximum. Billing is inactive until a rate card is explicitly published and activated; funding and prepaid opt-in are separate owner-only dashboard actions.
349
+
350
+ ## Native video, governed DAM and product rendering
351
+
352
+ Use the space-scoped DAM and video clients for collaborators, metadata schemas, bucket governance, reviewed publications, picker capabilities, model preparation, product rendering, galleries, version-pinned encoding, captions and playback sessions.
353
+
354
+ ```ts
355
+ const dam = sdk.assets.dam
356
+ const video = sdk.assets.video
357
+ const schema = await dam.createMetadataSchema({ name: 'Products', fields: [{
358
+ key: 'product_name', label: 'Product name', type: 'text', required: true,
359
+ }] })
360
+ const published = await dam.publishMetadataSchema(schema.id, schema.revision)
361
+ const workspace = await video.workspace(assetId)
362
+ ```
363
+
364
+ Mutations carry the supplied revision in `If-Match`. Model preparation and rendering carry an idempotency key; render submission also carries the accepted maximum units. Playback renewal and events authenticate with the session credential, not the account key. Keep these clients on your backend and return grants with `Cache-Control: private, no-store`.
365
+
366
+ See the [Assets SDK guide](https://docs.stackshift.cloud/assets/sdk-media-workflows) and its linked feature guides for complete language examples, inputs, permissions, review transitions and browser callbacks.
@@ -0,0 +1,65 @@
1
+ export type AssetMediaKind = 'image' | 'video';
2
+ export type AssetTransformOutputKind = 'image' | 'video' | 'audio' | 'thumbnail';
3
+ export type AssetAnimationPolicy = 'first' | 'preserve' | 'reject';
4
+ export interface AssetTransformOperation {
5
+ type: 'crop' | 'resize' | 'rotate' | 'blur' | 'radius' | 'dpr' | 'background' | 'overlay' | 'trim' | 'fps' | 'timestamp';
6
+ mode?: 'explicit' | 'fit' | 'fill' | 'pad';
7
+ gravity?: 'northwest' | 'north' | 'northeast' | 'west' | 'centre' | 'east' | 'southwest' | 'south' | 'southeast';
8
+ width?: number;
9
+ height?: number;
10
+ x?: number;
11
+ y?: number;
12
+ degrees?: number;
13
+ sigma?: number;
14
+ radius?: number;
15
+ dpr?: number;
16
+ color?: string;
17
+ asset_id?: string;
18
+ opacity?: number;
19
+ start_seconds?: number;
20
+ end_seconds?: number;
21
+ fps?: number;
22
+ timestamp_seconds?: number;
23
+ }
24
+ export interface AssetTransformDefinition {
25
+ version: 2;
26
+ media_kind: AssetMediaKind;
27
+ animation?: AssetAnimationPolicy;
28
+ operations: AssetTransformOperation[];
29
+ output: {
30
+ kind: AssetTransformOutputKind;
31
+ format: 'jpeg' | 'png' | 'webp' | 'avif' | 'mp4' | 'mp3' | 'aac' | 'wav';
32
+ quality?: number;
33
+ };
34
+ }
35
+ export type AssetTransformMaterializeInput = {
36
+ definition: AssetTransformDefinition;
37
+ preset?: never;
38
+ } | {
39
+ preset: string;
40
+ definition?: never;
41
+ };
42
+ export interface AssetDerivedAsset {
43
+ id: string;
44
+ asset_id: string;
45
+ source_checksum_sha256: string;
46
+ transform_hash: string;
47
+ normalized_spec: string;
48
+ definition_version: number;
49
+ output_kind: AssetTransformOutputKind;
50
+ dependency_checksum_sha256?: string;
51
+ processor_revision: string;
52
+ mime_type: string;
53
+ size: number;
54
+ status: string;
55
+ created_at: string;
56
+ updated_at: string;
57
+ last_accessed_at?: string;
58
+ }
59
+ export interface AssetImageGenerationInput {
60
+ prompt: string;
61
+ size: string;
62
+ format: 'png' | 'jpeg' | 'webp';
63
+ bucket: string;
64
+ key?: string;
65
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,269 @@
1
+ import type { StackShift } from './client.js';
2
+ export interface AssetWorkflowDefinition {
3
+ version: 1;
4
+ nodes: AssetWorkflowNode[];
5
+ edges: AssetWorkflowEdge[];
6
+ }
7
+ export interface AssetWorkflowNode {
8
+ id: string;
9
+ type: string;
10
+ action?: string;
11
+ action_version?: string;
12
+ config?: Record<string, unknown>;
13
+ retry?: {
14
+ max_attempts?: number;
15
+ backoff_seconds?: number;
16
+ };
17
+ timeout_seconds?: number;
18
+ failure_policy?: string;
19
+ }
20
+ export interface AssetWorkflowEdge {
21
+ id: string;
22
+ source: string;
23
+ source_port?: string;
24
+ target: string;
25
+ target_port?: string;
26
+ }
27
+ export interface AssetWorkflowLayout {
28
+ nodes: Array<{
29
+ id: string;
30
+ x: number;
31
+ y: number;
32
+ width?: number;
33
+ height?: number;
34
+ }>;
35
+ viewport: {
36
+ x: number;
37
+ y: number;
38
+ zoom: number;
39
+ };
40
+ groups?: Array<{
41
+ id: string;
42
+ label: string;
43
+ node_ids: string[];
44
+ }>;
45
+ }
46
+ export interface AssetWorkflow {
47
+ id: string;
48
+ name: string;
49
+ description?: string;
50
+ status: 'draft' | 'active' | 'disabled';
51
+ revision: number;
52
+ execution_principal_id: string;
53
+ draft_definition: AssetWorkflowDefinition;
54
+ draft_layout: AssetWorkflowLayout;
55
+ current_version_id?: string;
56
+ active_version_id?: string;
57
+ created_at: string;
58
+ updated_at: string;
59
+ }
60
+ export interface AssetWorkflowVersion {
61
+ id: string;
62
+ workflow_id: string;
63
+ version: number;
64
+ semantic_digest: string;
65
+ definition: AssetWorkflowDefinition;
66
+ layout: AssetWorkflowLayout;
67
+ created_by: string;
68
+ created_at: string;
69
+ }
70
+ export interface AssetWorkflowRun {
71
+ id: string;
72
+ workflow_id: string;
73
+ version_id: string;
74
+ durable_run_id?: string;
75
+ trigger_type: string;
76
+ trigger_key?: string;
77
+ status: 'queued' | 'running' | 'waiting' | 'completed' | 'completed_with_warning' | 'failed' | 'canceled';
78
+ input: unknown;
79
+ output?: unknown;
80
+ error?: unknown;
81
+ started_at?: string;
82
+ completed_at?: string;
83
+ created_at: string;
84
+ updated_at: string;
85
+ }
86
+ export interface AssetWorkflowNodeExecution {
87
+ id: string;
88
+ run_id: string;
89
+ node_id: string;
90
+ node_type: string;
91
+ status: string;
92
+ attempt: number;
93
+ input?: unknown;
94
+ output?: unknown;
95
+ error?: unknown;
96
+ selected_ports: string[];
97
+ wait_event?: string;
98
+ wait_correlation?: string;
99
+ wait_until?: string;
100
+ started_at?: string;
101
+ completed_at?: string;
102
+ stackie_activity?: Array<Record<string, unknown>>;
103
+ }
104
+ export interface AssetWorkflowValidation {
105
+ valid: boolean;
106
+ semantic_digest?: string;
107
+ definition: AssetWorkflowDefinition;
108
+ issues: Array<{
109
+ code: string;
110
+ message: string;
111
+ node_id?: string;
112
+ edge_id?: string;
113
+ }>;
114
+ }
115
+ export interface AssetWorkflowNodeDefinition {
116
+ type: string;
117
+ version: string;
118
+ name: string;
119
+ category: string;
120
+ description: string;
121
+ input_ports: Array<{
122
+ name: string;
123
+ data_type: string;
124
+ required?: boolean;
125
+ }>;
126
+ output_ports: Array<{
127
+ name: string;
128
+ data_type: string;
129
+ required?: boolean;
130
+ }>;
131
+ config_schema: Record<string, unknown>;
132
+ risk: 'read' | 'reversible' | 'costly' | 'production' | 'external';
133
+ requires_approval: boolean;
134
+ approval_mode: 'none' | 'version' | 'per_run';
135
+ }
136
+ export interface AssetWorkflowTemplate {
137
+ key: string;
138
+ name: string;
139
+ description: string;
140
+ definition: AssetWorkflowDefinition;
141
+ layout: AssetWorkflowLayout;
142
+ valid: boolean;
143
+ issues: AssetWorkflowValidation['issues'];
144
+ }
145
+ export interface AssetWorkflowApproval {
146
+ id: string;
147
+ workflow_id: string;
148
+ version_id: string;
149
+ run_id?: string;
150
+ node_id?: string;
151
+ approval_mode: 'version' | 'per_run';
152
+ semantic_digest: string;
153
+ status: 'pending' | 'approved' | 'rejected';
154
+ risk_summary: unknown;
155
+ constraints: unknown;
156
+ requested_by: string;
157
+ decided_by?: string;
158
+ decision_reason?: string;
159
+ expires_at?: string;
160
+ created_at: string;
161
+ updated_at: string;
162
+ }
163
+ export interface AssetWorkflowHTTPConnection {
164
+ id?: string;
165
+ name: string;
166
+ host: string;
167
+ allowed_path_prefixes: string[];
168
+ credential_reference?: string;
169
+ credential?: AssetWorkflowHTTPCredentialInput;
170
+ default_headers: Record<string, string>;
171
+ revision?: number;
172
+ created_at?: string;
173
+ updated_at?: string;
174
+ }
175
+ export interface AssetWorkflowHTTPCredentialInput {
176
+ name: string;
177
+ header: string;
178
+ prefix?: string;
179
+ value: string;
180
+ }
181
+ export interface AssetAutomationOverview {
182
+ mcp_endpoint: '/api/v1/assets/mcp';
183
+ auth_method: 'pat';
184
+ tools: Array<{
185
+ name: string;
186
+ description: string;
187
+ required_scope: string;
188
+ required_scopes?: string[];
189
+ risk: string;
190
+ }>;
191
+ recent_executions: Array<{
192
+ id: string;
193
+ tool: string;
194
+ transport: string;
195
+ status: string;
196
+ created_at: string;
197
+ }>;
198
+ }
199
+ export declare class AssetWorkflowsClient {
200
+ private readonly client;
201
+ constructor(client: StackShift);
202
+ catalog(): Promise<{
203
+ nodes: AssetWorkflowNodeDefinition[];
204
+ templates: AssetWorkflowTemplate[];
205
+ }>;
206
+ create(input: {
207
+ name: string;
208
+ description?: string;
209
+ template_key?: string;
210
+ definition?: AssetWorkflowDefinition;
211
+ layout?: AssetWorkflowLayout;
212
+ }): Promise<AssetWorkflow>;
213
+ list(page?: number, perPage?: number): Promise<AssetWorkflow[]>;
214
+ get(workflowId: string): Promise<AssetWorkflow>;
215
+ updateDraft(workflowId: string, input: {
216
+ name: string;
217
+ description?: string;
218
+ definition: AssetWorkflowDefinition;
219
+ layout: AssetWorkflowLayout;
220
+ expected_revision: number;
221
+ }): Promise<AssetWorkflow>;
222
+ validate(workflowId: string): Promise<AssetWorkflowValidation>;
223
+ publish(workflowId: string, expectedRevision: number): Promise<AssetWorkflowVersion>;
224
+ activate(workflowId: string, versionId: string, expectedRevision: number): Promise<void>;
225
+ versions(workflowId: string): Promise<AssetWorkflowVersion[]>;
226
+ run(workflowId: string, input?: {
227
+ version_id?: string;
228
+ input?: unknown;
229
+ idempotency_key?: string;
230
+ }): Promise<AssetWorkflowRun>;
231
+ runs(workflowId: string, page?: number, perPage?: number): Promise<AssetWorkflowRun[]>;
232
+ runDetail(runId: string): Promise<{
233
+ run: AssetWorkflowRun;
234
+ nodes: AssetWorkflowNodeExecution[];
235
+ }>;
236
+ cancelRun(runId: string): Promise<AssetWorkflowRun>;
237
+ retryRun(runId: string): Promise<AssetWorkflowRun>;
238
+ approvals(status?: AssetWorkflowApproval['status']): Promise<AssetWorkflowApproval[]>;
239
+ decideApproval(approvalId: string, approved: boolean, input?: {
240
+ reason?: string;
241
+ expires_at?: string;
242
+ }): Promise<AssetWorkflowApproval>;
243
+ approve(approvalId: string, input?: {
244
+ reason?: string;
245
+ expires_at?: string;
246
+ }): Promise<AssetWorkflowApproval>;
247
+ reject(approvalId: string, input?: {
248
+ reason?: string;
249
+ }): Promise<AssetWorkflowApproval>;
250
+ connections(): Promise<AssetWorkflowHTTPConnection[]>;
251
+ createConnection(input: AssetWorkflowHTTPConnection): Promise<AssetWorkflowHTTPConnection>;
252
+ rotateConnectionCredential(connectionId: string, input: AssetWorkflowHTTPCredentialInput): Promise<{
253
+ id: string;
254
+ name: string;
255
+ header: string;
256
+ prefix?: string;
257
+ revision: number;
258
+ }>;
259
+ rotateInboundHook(workflowId: string): Promise<{
260
+ hook: {
261
+ id: string;
262
+ workflow_id: string;
263
+ secret_version: number;
264
+ enabled: boolean;
265
+ };
266
+ token: string;
267
+ secret: string;
268
+ }>;
269
+ }
@@ -0,0 +1,69 @@
1
+ export class AssetWorkflowsClient {
2
+ client;
3
+ constructor(client) {
4
+ this.client = client;
5
+ }
6
+ catalog() {
7
+ return this.client.request('/assets/workflows/catalog');
8
+ }
9
+ create(input) {
10
+ return this.client.request('/assets/workflows', { method: 'POST', body: input });
11
+ }
12
+ list(page = 1, perPage = 20) {
13
+ return this.client.request(`/assets/workflows?page=${page}&per_page=${perPage}`);
14
+ }
15
+ get(workflowId) { return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}`); }
16
+ updateDraft(workflowId, input) {
17
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/draft`, { method: 'PUT', body: input });
18
+ }
19
+ validate(workflowId) {
20
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/validate`, { method: 'POST' });
21
+ }
22
+ publish(workflowId, expectedRevision) {
23
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/publish`, { method: 'POST', body: { expected_revision: expectedRevision } });
24
+ }
25
+ activate(workflowId, versionId, expectedRevision) {
26
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/activate`, { method: 'POST', body: { version_id: versionId, expected_revision: expectedRevision } });
27
+ }
28
+ versions(workflowId) { return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/versions`); }
29
+ run(workflowId, input = {}) {
30
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/run`, {
31
+ method: 'POST', body: input,
32
+ headers: input.idempotency_key ? { 'Idempotency-Key': input.idempotency_key } : undefined,
33
+ });
34
+ }
35
+ runs(workflowId, page = 1, perPage = 20) {
36
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/runs?page=${page}&per_page=${perPage}`);
37
+ }
38
+ runDetail(runId) {
39
+ return this.client.request(`/assets/workflows/runs/${encodeURIComponent(runId)}`);
40
+ }
41
+ cancelRun(runId) {
42
+ return this.client.request(`/assets/workflows/runs/${encodeURIComponent(runId)}/cancel`, { method: 'POST' });
43
+ }
44
+ retryRun(runId) {
45
+ return this.client.request(`/assets/workflows/runs/${encodeURIComponent(runId)}/retry`, { method: 'POST' });
46
+ }
47
+ approvals(status) {
48
+ if (status)
49
+ return this.client.request(`/assets/workflows/approvals?status=${encodeURIComponent(status)}`);
50
+ return this.client.request('/assets/workflows/approvals');
51
+ }
52
+ decideApproval(approvalId, approved, input = {}) {
53
+ return approved ? this.approve(approvalId, input) : this.reject(approvalId, input);
54
+ }
55
+ approve(approvalId, input = {}) {
56
+ return this.client.request(`/assets/workflows/approvals/${encodeURIComponent(approvalId)}/approve`, { method: 'POST', body: input });
57
+ }
58
+ reject(approvalId, input = {}) {
59
+ return this.client.request(`/assets/workflows/approvals/${encodeURIComponent(approvalId)}/reject`, { method: 'POST', body: input });
60
+ }
61
+ connections() { return this.client.request('/assets/workflows/connections'); }
62
+ createConnection(input) { return this.client.request('/assets/workflows/connections', { method: 'POST', body: input }); }
63
+ rotateConnectionCredential(connectionId, input) {
64
+ return this.client.request(`/assets/workflows/connections/${encodeURIComponent(connectionId)}/credential/rotate`, { method: 'POST', body: input });
65
+ }
66
+ rotateInboundHook(workflowId) {
67
+ return this.client.request(`/assets/workflows/${encodeURIComponent(workflowId)}/inbound-hook/rotate`, { method: 'POST' });
68
+ }
69
+ }