@refoldai/refold-js 10.0.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/.claude/skills/method/SKILL.md +282 -0
  2. package/.claude/skills/review-pr/SKILL.md +80 -0
  3. package/.claude/skills/style/SKILL.md +67 -0
  4. package/.claude/skills/verify/SKILL.md +85 -0
  5. package/.github/pull_request_template.md +48 -0
  6. package/.github/workflows/npm-publish.yml +35 -0
  7. package/.github/workflows/pr-validation.yml +224 -0
  8. package/CLAUDE.md +127 -0
  9. package/LICENSE +21 -0
  10. package/README.md +63 -0
  11. package/docs/.nojekyll +1 -0
  12. package/docs/assets/hierarchy.js +1 -0
  13. package/docs/assets/highlight.css +113 -0
  14. package/docs/assets/icons.js +18 -0
  15. package/docs/assets/icons.svg +1 -0
  16. package/docs/assets/main.js +60 -0
  17. package/docs/assets/navigation.js +1 -0
  18. package/docs/assets/search.js +1 -0
  19. package/docs/assets/style.css +1633 -0
  20. package/docs/classes/Refold.html +123 -0
  21. package/docs/enums/AuthStatus.html +3 -0
  22. package/docs/enums/AuthType.html +4 -0
  23. package/docs/hierarchy.html +1 -0
  24. package/docs/index.html +36 -0
  25. package/docs/interfaces/Application.html +37 -0
  26. package/docs/interfaces/Config.html +6 -0
  27. package/docs/interfaces/ConfigField.html +17 -0
  28. package/docs/interfaces/ConfigPayload.html +8 -0
  29. package/docs/interfaces/ConfigWorkflow.html +6 -0
  30. package/docs/interfaces/ExecuteWorkflowPayload.html +9 -0
  31. package/docs/interfaces/Execution.html +19 -0
  32. package/docs/interfaces/ExecutionFilters.html +16 -0
  33. package/docs/interfaces/GetExecutionsParams.html +19 -0
  34. package/docs/interfaces/InputField.html +18 -0
  35. package/docs/interfaces/Label.html +6 -0
  36. package/docs/interfaces/PublicWorkflow.html +16 -0
  37. package/docs/interfaces/PublicWorkflowPayload.html +8 -0
  38. package/docs/interfaces/PublicWorkflowsPayload.html +15 -0
  39. package/docs/interfaces/RefoldOptions.html +5 -0
  40. package/docs/interfaces/RuleOptions.html +4 -0
  41. package/docs/interfaces/UpdateConfigPayload.html +10 -0
  42. package/docs/interfaces/WorkflowPayload.html +8 -0
  43. package/docs/interfaces/WorkflowPayloadResponse.html +4 -0
  44. package/docs/llms.txt +986 -0
  45. package/docs/modules.html +1 -0
  46. package/docs/types/ExecutionSource.html +2 -0
  47. package/docs/types/ExecutionStatus.html +2 -0
  48. package/docs/types/ExecutionType.html +2 -0
  49. package/package.json +38 -0
  50. package/refold.d.ts +556 -0
  51. package/refold.js +667 -0
  52. package/refold.ts +1044 -0
  53. package/tsconfig.json +12 -0
package/refold.ts ADDED
@@ -0,0 +1,1044 @@
1
+ /**
2
+ * Refold Frontend SDK
3
+ */
4
+
5
+ export enum AuthType {
6
+ OAuth2 = "oauth2",
7
+ KeyBased = "keybased",
8
+ }
9
+
10
+ export enum AuthStatus {
11
+ Active = "active",
12
+ Expired = "expired",
13
+ }
14
+
15
+ /** An application in Refold. */
16
+ export interface Application {
17
+ /** Application ID */
18
+ app_id: string;
19
+ /**The application name. */
20
+ name: string;
21
+ /**The application description. */
22
+ description: string;
23
+ /**The application icon. */
24
+ icon: string;
25
+ /**
26
+ * @deprecated Use `slug` instead.
27
+ * The application slug for native apps and `custom` for custom apps.
28
+ */
29
+ type: string | "custom";
30
+ /** The application slug. */
31
+ slug: string;
32
+ /** The categories/tags for the application. */
33
+ tags?: string[];
34
+ /** The supported auth types for the application, and the fields required from the user to connect the application. */
35
+ auth_type_options?: {
36
+ /** The fields required from the user to connect the application. */
37
+ [key in AuthType]: InputField[];
38
+ };
39
+ /** The list of connected accounts for this application */
40
+ connected_accounts?: {
41
+ /** The identifier (username, email, etc.) of the connected account. */
42
+ identifier: unknown;
43
+ /** The auth type used to connect the account. */
44
+ auth_type: AuthType;
45
+ /** The timestamp at which the account was connected. */
46
+ connectedAt: string;
47
+ /** The current status of the connection. */
48
+ status?: AuthStatus;
49
+ }[];
50
+ /**
51
+ * The type of auth used by application.
52
+ * @deprecated Check `auth_type_options` and `connected_accounts` for multiple auth types support.
53
+ */
54
+ auth_type: "oauth2" | "keybased";
55
+ /**
56
+ * Whether the user has connected the application.
57
+ * @deprecated Check `connected_accounts` for multiple auth types support.
58
+ */
59
+ connected?: boolean;
60
+ /**
61
+ * Whether the connection has expired and re-auth is required.
62
+ * @deprecated Check `connected_accounts` for multiple auth types support.
63
+ */
64
+ reauth_required?: boolean;
65
+ /**
66
+ * The fields required from the user to connect the application (for `keybased` auth type).
67
+ * @deprecated Check `auth_type_options` for multiple auth types support.
68
+ */
69
+ auth_input_map?: InputField[];
70
+ }
71
+
72
+ /** An Input field to take input from the user. */
73
+ export interface InputField {
74
+ /** Key name of the field. */
75
+ name: string;
76
+ /** Input type of the field. */
77
+ type: string;
78
+ /** Whether the field is required. */
79
+ required: boolean;
80
+ /** Whether the field accepts multiple values. */
81
+ multiple?: boolean;
82
+ /** The placeholder of the field. */
83
+ placeholder: string;
84
+ /** The label of the field. */
85
+ label: string;
86
+ /** The help text for the field. */
87
+ help_text?: string;
88
+ /** The options for the field. */
89
+ options?: {
90
+ name?: string;
91
+ value: string;
92
+ }[];
93
+ }
94
+
95
+ /** The payload object for config. */
96
+ export interface ConfigPayload {
97
+ /** The application slug. */
98
+ slug: string;
99
+ /** Unique ID for the config. */
100
+ config_id?: string;
101
+ /** The dynamic label mappings. */
102
+ labels?: Label[];
103
+ }
104
+
105
+ /** Label Mapping */
106
+ export interface Label {
107
+ /** The label name. */
108
+ name: string;
109
+ /** The label value. */
110
+ value: string | number | boolean;
111
+ }
112
+
113
+ /** The configuration data for an application. */
114
+ export interface UpdateConfigPayload {
115
+ /** The application slug */
116
+ slug: string;
117
+ /** Unique ID for the config. */
118
+ config_id?: string;
119
+ /** A map of application fields and their values. */
120
+ fields: Record<string, string | number | boolean>;
121
+ /** The config workflows data. */
122
+ workflows: WorkflowPayload[];
123
+ }
124
+
125
+ /** The workflow. */
126
+ export interface WorkflowPayload {
127
+ /** The ID of the workflow. */
128
+ id: string;
129
+ /** Whether the workflow is enabled. */
130
+ enabled: boolean;
131
+ /** A map of workflow field names and their values. */
132
+ fields: Record<string, string | number | boolean>;
133
+ }
134
+
135
+ export interface RefoldOptions {
136
+ /** The base URL of the Refold API. You don't need to set this. */
137
+ baseUrl?: string;
138
+ /** The session token. */
139
+ token?: string;
140
+ }
141
+
142
+ export interface RuleOptions {
143
+ rule_column: {
144
+ rhs: {
145
+ name: string,
146
+ type: "text" | "select",
147
+ options?: Label[],
148
+ },
149
+ operator: {
150
+ name: string,
151
+ type: "select",
152
+ options: Label[],
153
+ },
154
+ },
155
+ conditional_code_stdout?: string[],
156
+ error?: {
157
+ message?: string,
158
+ stack?: string
159
+ }
160
+ }
161
+
162
+ /** A public workflow in Refold. */
163
+ export interface PublicWorkflow {
164
+ /**The workflow ID. */
165
+ _id: string;
166
+ /**The workflow name. */
167
+ name: string;
168
+ /**The workflow description. */
169
+ description?: string;
170
+ /**The application's slug in which this workflow exists. */
171
+ slug?: string;
172
+ /**The workflow created at. */
173
+ createdAt: string;
174
+ /**The workflow updated at. */
175
+ updatedAt: string;
176
+ /**Whether the workflow is published. */
177
+ published: boolean;
178
+ }
179
+
180
+ /** The payload for creating a public workflow for the linked account. */
181
+ export interface PublicWorkflowPayload {
182
+ /**The workflow name. */
183
+ name: string;
184
+ /**The workflow description. */
185
+ description?: string;
186
+ /** The application slug in which this workflow should be created. */
187
+ slug?: string;
188
+ }
189
+
190
+ /** Parameters for filtering and paginating the list of workflows. */
191
+ export interface PublicWorkflowsPayload extends PaginationProps {
192
+ /** Filter workflows by the application slug. */
193
+ slug?: string;
194
+ /** Filter workflows by name (partial match). */
195
+ name?: string;
196
+ /** Filter workflows created on or after this ISO 8601 date string. */
197
+ start_date?: string;
198
+ /** Filter workflows created on or before this ISO 8601 date string. */
199
+ end_date?: string;
200
+ /** Filter by workflow published status. `true` returns only published workflows, `false` returns only drafts. */
201
+ published?: boolean;
202
+ /** Any additional filter keys supported by the API. */
203
+ [key: string]: string | number | boolean | undefined;
204
+ }
205
+
206
+ interface PaginationProps {
207
+ page?: number;
208
+ limit?: number;
209
+ }
210
+
211
+ /** The current status of a workflow execution. */
212
+ export type ExecutionStatus = "COMPLETED" | "RUNNING" | "ERRORED" | "STOPPED" | "STOPPING" | "TIMED_OUT";
213
+ /** The trigger source that initiated a workflow execution. */
214
+ export type ExecutionSource = "Event" | "Schedule" | "API Call";
215
+ /** Whether a workflow execution runs synchronously (waits for result) or asynchronously (fire-and-forget). */
216
+ export type ExecutionType = "SYNC" | "ASYNC";
217
+
218
+ /** Filters for narrowing down the list of workflow executions. */
219
+ export interface ExecutionFilters {
220
+ /** Filter executions by their current status. */
221
+ status?: ExecutionStatus;
222
+ /** Filter executions by workflow name (partial match). */
223
+ workflow_name?: string;
224
+ /** Filter executions by workflow ID. */
225
+ workflow_id?: string;
226
+ /** Filter executions that started on or after this ISO 8601 date string. */
227
+ start_date?: string;
228
+ /** Filter executions that started on or before this ISO 8601 date string. */
229
+ end_date?: string;
230
+ /** Filter by how the execution was invoked — synchronously or asynchronously. */
231
+ execution_type?: ExecutionType;
232
+ /** Filter by the trigger source that initiated the execution. */
233
+ execution_source?: ExecutionSource;
234
+ }
235
+
236
+ /** Parameters for filtering and paginating the list of workflow executions. */
237
+ export interface GetExecutionsParams extends PaginationProps, ExecutionFilters {
238
+ /** Any additional filter keys supported by the API. */
239
+ [key: string]: string | number | undefined;
240
+ }
241
+
242
+ interface PaginatedResponse<T> {
243
+ docs: T[];
244
+ totalDocs: number;
245
+ limit: number;
246
+ totalPages: number;
247
+ page: number;
248
+ }
249
+
250
+ export interface Config {
251
+ slug: string;
252
+ config_id?: string;
253
+ fields?: ConfigField[];
254
+ workflows?: ConfigWorkflow[];
255
+ field_errors?: {
256
+ id: string;
257
+ name: string;
258
+ error: {
259
+ message: string;
260
+ error?: unknown;
261
+ };
262
+ }[];
263
+ }
264
+
265
+ export interface ConfigField {
266
+ id: string;
267
+ name: string;
268
+ field_type: "text" | "date" | "number" | "url" | "email" | "textarea" | "select" | "json" | "map" | "map_v2" | "rule_engine" | string;
269
+ options?: {
270
+ name?: string;
271
+ value: string;
272
+ }[];
273
+ parent?: string;
274
+ labels?: {
275
+ name?: string;
276
+ value: string;
277
+ }[];
278
+ multiple?: boolean;
279
+ required?: boolean;
280
+ hidden?: boolean;
281
+ value?: any;
282
+ /** The placeholder for the field. */
283
+ placeholder?: string;
284
+ /** The help text for the field. */
285
+ help_text?: string;
286
+ /** The page this field is associated with. */
287
+ associated_page?: string;
288
+ }
289
+
290
+ export interface ConfigWorkflow {
291
+ id: string;
292
+ name: string;
293
+ description?: string;
294
+ enabled: boolean;
295
+ fields?: ConfigField[];
296
+ }
297
+
298
+ export interface WorkflowPayloadResponse {
299
+ payload: Record<string, any>;
300
+ schema?: unknown;
301
+ schema_interpreted?: unknown;
302
+ }
303
+
304
+ export interface ExecuteWorkflowPayload {
305
+ /**The workflow id or alias. */
306
+ worklfow: string;
307
+ /** The application's slug this workflow belongs to. */
308
+ slug?: string;
309
+ /** The payload to execute the workflow. */
310
+ payload?: Record<string, any>;
311
+ /** Whether to execute the workflow synchronously. */
312
+ sync_execution?: boolean;
313
+ }
314
+
315
+ export interface Execution {
316
+ _id: string;
317
+ id?: string;
318
+ name: string;
319
+ org_id: string;
320
+ associated_application: {
321
+ _id: string;
322
+ name: string;
323
+ icon?: string;
324
+ };
325
+ status: ExecutionStatus;
326
+ associated_workflow: {
327
+ _id: string;
328
+ name: string;
329
+ };
330
+ associated_trigger_application: {
331
+ _id: string;
332
+ name: string;
333
+ icon?: string;
334
+ app_type?: "custom" | string;
335
+ origin_trigger: {
336
+ _id: string;
337
+ name: string;
338
+ }
339
+ };
340
+ trigger_application_event?: string;
341
+ linked_account_id: string;
342
+ environment: "test" | "production";
343
+ config_id: string;
344
+ associated_event_id: string;
345
+ custom_trigger_id?: string;
346
+ custom_application_id?: string;
347
+ completion_percentage?: number;
348
+ nodes?: {
349
+ node_id: string;
350
+ node_name: string;
351
+ node_type: string;
352
+ node_status: "Success" | "Ready" | "Errored" | "Waiting" | "Stopped" | "Rejected"| "Errored_and_Skipped" | "Timed_Out";
353
+ is_batch?: boolean;
354
+ attempts_made: number;
355
+ maximum_attempts: number;
356
+ input_data: unknown;
357
+ latest_output: unknown;
358
+ }[];
359
+ createdAt: string;
360
+ }
361
+
362
+ type Field = any;
363
+
364
+ class Refold {
365
+ private baseUrl: string;
366
+ public token: string;
367
+
368
+ /**
369
+ * Refold Frontend SDK
370
+ * @param {Object} options The options to configure the Refold SDK.
371
+ * @param {String} [options.token] The session token.
372
+ * @param {String} [options.baseUrl=https://app.refold.ai] The base URL of the Refold API.
373
+ */
374
+ constructor(options: RefoldOptions = {}) {
375
+ this.baseUrl = options.baseUrl
376
+ ? /^https?:\/\//.test(options.baseUrl)
377
+ ? options.baseUrl
378
+ : "https://" + options.baseUrl
379
+ : "https://app.refold.ai";
380
+ this.token = options.token || "";
381
+ }
382
+
383
+ /**
384
+ * Returns the org & customer details for the associated token.
385
+ * @private
386
+ * @returns {Promise<unknown>}
387
+ */
388
+ public async getAccountDetails(): Promise<unknown> {
389
+ const res = await fetch(`${this.baseUrl}/api/v3/org/basics`, {
390
+ headers: {
391
+ authorization: `Bearer ${this.token}`,
392
+ },
393
+ });
394
+
395
+ if (res.status >= 400 && res.status < 600) {
396
+ const error = await res.json();
397
+ throw error;
398
+ }
399
+
400
+ const data = await res.json();
401
+ return data;
402
+ }
403
+
404
+ /**
405
+ * Returns the org & customer details for the associated token.
406
+ * @private
407
+ * @returns {Promise<unknown>}
408
+ */
409
+ public async updateAccount(payload: Record<string, unknown>): Promise<unknown> {
410
+ const res = await fetch(`${this.baseUrl}/api/v2/public/linked-account`, {
411
+ method: "PUT",
412
+ headers: {
413
+ authorization: `Bearer ${this.token}`,
414
+ "content-type": "application/json",
415
+ },
416
+ body: JSON.stringify({
417
+ ...payload,
418
+ }),
419
+ });
420
+
421
+ if (res.status >= 400 && res.status < 600) {
422
+ const error = await res.json();
423
+ throw error;
424
+ }
425
+
426
+ const data = await res.json();
427
+ return data;
428
+ }
429
+
430
+ /**
431
+ * Returns the list of enabled applications and their details.
432
+ * @returns {Promise<Application[]>} The list of applications.
433
+ */
434
+ public async getApp(): Promise<Application[]>;
435
+ /**
436
+ * Returns the application details for the specified application, provided
437
+ * the application is enabled in Refold.
438
+ * @param {String} slug The application slug.
439
+ * @returns {Promise<Application>} The application details.
440
+ */
441
+ public async getApp(slug: string): Promise<Application>;
442
+ /**
443
+ * Returns the application details for the specified application, provided
444
+ * the application is enabled in Refold. If no application is specified,
445
+ * it returns all the enabled applications.
446
+ * @param {String} [slug] The application slug.
447
+ * @returns {Promise<Application | Application[]>} The application details.
448
+ */
449
+ public async getApp(slug?: string): Promise<Application | Application[]> {
450
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/application${slug ? `/${slug}` : ""}`, {
451
+ headers: {
452
+ authorization: `Bearer ${this.token}`,
453
+ },
454
+ });
455
+
456
+ if (res.status >= 400 && res.status < 600) {
457
+ const error = await res.json();
458
+ throw error;
459
+ }
460
+
461
+ const data = await res.json();
462
+ return data;
463
+ }
464
+
465
+ /**
466
+ * Returns all the enabled apps.
467
+ * @returns {Promise<Application[]>} The list of applications.
468
+ */
469
+ public async getApps(): Promise<Application[]> {
470
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/application`, {
471
+ headers: {
472
+ authorization: `Bearer ${this.token}`,
473
+ },
474
+ });
475
+
476
+ if (res.status >= 400 && res.status < 600) {
477
+ const error = await res.json();
478
+ throw error;
479
+ }
480
+
481
+ const data = await res.json();
482
+ return data;
483
+ }
484
+
485
+ /**
486
+ * Returns the auth URL that users can use to authenticate themselves to the
487
+ * specified application.
488
+ * @private
489
+ * @param {String} slug The application slug.
490
+ * @param {Object.<string, string>} [params] The key value pairs of auth data.
491
+ * @returns {Promise<String>} The auth URL where users can authenticate themselves.
492
+ */
493
+ private async getOAuthUrl(slug: string, params?: Record<string, string>): Promise<string> {
494
+ const res = await fetch(`${this.baseUrl}/api/v1/${slug}/integrate?${new URLSearchParams(params).toString()}`, {
495
+ headers: {
496
+ authorization: `Bearer ${this.token}`,
497
+ },
498
+ });
499
+
500
+ if (res.status >= 400 && res.status < 600) {
501
+ const error = await res.json();
502
+ throw error;
503
+ }
504
+
505
+ const data = await res.json();
506
+ return data.auth_url;
507
+ }
508
+
509
+ /**
510
+ * Handle OAuth for the specified application.
511
+ * @private
512
+ * @param {String} slug The application slug.
513
+ * @param {Object.<string, string>} [params] The key value pairs of auth data.
514
+ * @returns {Promise<Boolean>} Whether the user authenticated.
515
+ */
516
+ private async oauth(slug: string, params?: Record<string, string>): Promise<boolean> {
517
+ return new Promise((resolve, reject) => {
518
+ this.getOAuthUrl(slug, params)
519
+ .then(oauthUrl => {
520
+ const connectWindow = window.open(oauthUrl);
521
+
522
+ // keep checking connection status
523
+ const interval = setInterval(() => {
524
+ this.getApp(slug)
525
+ .then(app => {
526
+ if (app && app.connected_accounts?.filter(a => a.auth_type === AuthType.OAuth2).some(a => a.status === AuthStatus.Active)) {
527
+ // close auth window
528
+ connectWindow && connectWindow.close();
529
+ // clear interval
530
+ clearInterval(interval);
531
+ // resovle status
532
+ resolve(true);
533
+ } else {
534
+ // user closed oauth window without authenticating
535
+ if (connectWindow && connectWindow.closed) {
536
+ // clear interval
537
+ clearInterval(interval);
538
+ // resolve status
539
+ resolve(false);
540
+ }
541
+ }
542
+ })
543
+ .catch(e => {
544
+ console.error(e);
545
+ // connectWindow?.close();
546
+ clearInterval(interval);
547
+ reject(e);
548
+ });
549
+ }, 3e3);
550
+ })
551
+ .catch(reject);
552
+ });
553
+ }
554
+
555
+ /**
556
+ * Save auth data for the specified keybased application.
557
+ * @param {String} slug The application slug.
558
+ * @param {Object.<string, string>} [payload] The key value pairs of auth data.
559
+ * @returns {Promise<Boolean>} Whether the auth data was saved successfully.
560
+ */
561
+ private async keybased(slug: string, payload?: Record<string, string>): Promise<boolean> {
562
+ const res = await fetch(`${this.baseUrl}/api/v2/app/${slug}/save`, {
563
+ method: "POST",
564
+ headers: {
565
+ authorization: `Bearer ${this.token}`,
566
+ "content-type": "application/json",
567
+ },
568
+ body: JSON.stringify({
569
+ ...payload,
570
+ }),
571
+ });
572
+
573
+ if (res.status >= 400 && res.status < 600) {
574
+ const error = await res.json();
575
+ throw error;
576
+ }
577
+
578
+ const data = await res.json();
579
+ return data.success;
580
+ }
581
+
582
+ /**
583
+ * Connects the specified application using the provided authentication type and optional auth data.
584
+ * @param params - The parameters for connecting the application.
585
+ * @param params.slug - The application slug.
586
+ * @param params.type - The authentication type to use. If not provided, it defaults to `keybased` if payload is provided, otherwise `oauth2`.
587
+ * @param params.payload - key-value pairs of authentication data required for the specified auth type.
588
+ * @returns A promise that resolves to true if the connection was successful, otherwise false.
589
+ * @throws Throws an error if the authentication type is invalid or the connection fails.
590
+ */
591
+ public async connect({
592
+ slug,
593
+ type,
594
+ payload,
595
+ }: {
596
+ slug: string;
597
+ type?: AuthType;
598
+ payload?: Record<string, string>;
599
+ }): Promise<boolean> {
600
+ switch (type) {
601
+ case AuthType.OAuth2:
602
+ return this.oauth(slug, payload);
603
+ case AuthType.KeyBased:
604
+ return this.keybased(slug, payload);
605
+ default:
606
+ if (payload) return this.keybased(slug, payload);
607
+ return this.oauth(slug);
608
+ }
609
+ }
610
+
611
+ /**
612
+ * Disconnect the specified application and remove any associated data from Refold.
613
+ * @param {String} slug The application slug.
614
+ * @param {AuthType} [type] The authentication type to use. If not provided, it'll remove all the connected accounts.
615
+ * @returns {Promise<unknown>}
616
+ */
617
+ public async disconnect(slug: string, type?: AuthType): Promise<unknown> {
618
+ const res = await fetch(`${this.baseUrl}/api/v1/linked-acc/integration/${slug}${type ? `?auth_type=${type}` : ""}`, {
619
+ method: "DELETE",
620
+ headers: {
621
+ authorization: `Bearer ${this.token}`,
622
+ },
623
+ });
624
+
625
+ if (res.status >= 400 && res.status < 600) {
626
+ const error = await res.json();
627
+ throw error;
628
+ }
629
+
630
+ return await res.json();
631
+ }
632
+
633
+ /**
634
+ * Returns the specified config, or creates one if it doesn't exist.
635
+ * @param {ConfigPayload} payload The payload object for config.
636
+ * @returns {Promise<Config>} The specified config.
637
+ */
638
+ public async config(payload: ConfigPayload): Promise<Config> {
639
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/config`, {
640
+ method: "POST",
641
+ headers: {
642
+ authorization: `Bearer ${this.token}`,
643
+ "content-type": "application/json",
644
+ },
645
+ body: JSON.stringify({
646
+ ...payload,
647
+ labels: payload.labels || [],
648
+ }),
649
+ });
650
+
651
+ if (res.status >= 400 && res.status < 600) {
652
+ const error = await res.json();
653
+ throw error;
654
+ }
655
+
656
+ return await res.json();
657
+ }
658
+
659
+ /**
660
+ * Returns the configs created for the specified application.
661
+ * @param {String} slug The application slug.
662
+ * @returns {Promise<{ config_id: string; }[]>} The configs created for the specified application.
663
+ */
664
+ async getConfigs(slug: string): Promise<{ config_id: string; }[]> {
665
+ const res = await fetch(`${this.baseUrl}/api/v2/public/slug/${slug}/configs`, {
666
+ headers: {
667
+ authorization: `Bearer ${this.token}`,
668
+ },
669
+ });
670
+
671
+ if (res.status >= 400 && res.status < 600) {
672
+ const error = await res.json();
673
+ throw error;
674
+ }
675
+
676
+ return await res.json();
677
+ }
678
+
679
+ /**
680
+ * Returns the specified config.
681
+ * @param {String} slug The application slug.
682
+ * @param {String} [configId] The unique ID of the config.
683
+ * @param {Boolean} [excludeOptions] Whether to exclude the options from the fields in the response.
684
+ * @returns {Promise<Config>} The specified config.
685
+ */
686
+ async getConfig(slug: string, configId: string, excludeOptions?: boolean): Promise<Config> {
687
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/slug/${slug}/config${configId ? `/${configId}` : ""}`, {
688
+ headers: {
689
+ authorization: `Bearer ${this.token}`,
690
+ ...(excludeOptions ? { disable_field_options: "true" } : {}),
691
+ },
692
+ });
693
+
694
+ if (res.status >= 400 && res.status < 600) {
695
+ const error = await res.json();
696
+ throw error;
697
+ }
698
+
699
+ return await res.json();
700
+ }
701
+
702
+ /**
703
+ * Update the specified config.
704
+ * @param {UpdateConfigPayload} payload The update payload.
705
+ * @returns {Promise<Config>} The specified config.
706
+ */
707
+ async updateConfig(payload: UpdateConfigPayload): Promise<Config> {
708
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/config`, {
709
+ method: "PUT",
710
+ headers: {
711
+ authorization: `Bearer ${this.token}`,
712
+ "content-type": "application/json",
713
+ },
714
+ body: JSON.stringify(payload),
715
+ });
716
+
717
+ if (res.status >= 400 && res.status < 600) {
718
+ const error = await res.json();
719
+ throw error;
720
+ }
721
+
722
+ return await res.json();
723
+ }
724
+
725
+ /**
726
+ * Delete the specified config.
727
+ * @param {String} slug The application slug.
728
+ * @param {String} [configId] The unique ID of the config.
729
+ * @returns {Promise<unknown>}
730
+ */
731
+ async deleteConfig(slug: string, configId?: string): Promise<unknown> {
732
+ const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/slug/${slug}/config${configId ? `/${configId}` : ""}`, {
733
+ method: "DELETE",
734
+ headers: {
735
+ authorization: `Bearer ${this.token}`,
736
+ },
737
+ });
738
+
739
+ if (res.status >= 400 && res.status < 600) {
740
+ const error = await res.json();
741
+ throw error;
742
+ }
743
+
744
+ return await res.json();
745
+ }
746
+
747
+ /**
748
+ * Returns the specified field of the config.
749
+ * @param {String} slug The application slug.
750
+ * @param {String} fieldId The unique ID of the field.
751
+ * @param {String} [workflowId] The unique ID of the workflow.
752
+ * @param {Record<string, unknown>} [payload] The payload to be sent in the request body.
753
+ * @returns {Promise<Field>} The specified config field.
754
+ */
755
+ async getConfigField(slug: string, fieldId: string, workflowId?: string, payload?: Record<string, unknown>): Promise<Config> {
756
+ const res = await fetch(`${this.baseUrl}/api/v2/public/config/field/${fieldId}${workflowId ? `?workflow_id=${workflowId}` : ""}`, {
757
+ method: "POST",
758
+ headers: {
759
+ authorization: `Bearer ${this.token}`,
760
+ "content-type": "application/json",
761
+ slug,
762
+ },
763
+ body: JSON.stringify(payload || {}),
764
+ });
765
+
766
+ if (res.status >= 400 && res.status < 600) {
767
+ const error = await res.json();
768
+ throw error;
769
+ }
770
+
771
+ return await res.json();
772
+ }
773
+
774
+ /**
775
+ * Update the specified config field value.
776
+ * @param {String} slug The application slug.
777
+ * @param {String} fieldId The unique ID of the field.
778
+ * @param {String | Number | Boolean | null} value The new value for the field.
779
+ * @param {String} [workflowId] The unique ID of the workflow.
780
+ * @returns {Promise<Field>} The updated config field.
781
+ */
782
+ async updateConfigField(slug: string, fieldId: string, value: string | number | boolean | null, workflowId?: string): Promise<Config> {
783
+ const res = await fetch(`${this.baseUrl}/api/v2/public/config/field/${fieldId}${workflowId ? `?workflow_id=${workflowId}` : ""}`, {
784
+ method: "PUT",
785
+ headers: {
786
+ authorization: `Bearer ${this.token}`,
787
+ "content-type": "application/json",
788
+ slug,
789
+ },
790
+ body: JSON.stringify({ value }),
791
+ });
792
+
793
+ if (res.status >= 400 && res.status < 600) {
794
+ const error = await res.json();
795
+ throw error;
796
+ }
797
+
798
+ return await res.json();
799
+ }
800
+
801
+ /**
802
+ * Delete the specified config field value.
803
+ * @param {String} slug The application slug.
804
+ * @param {String} fieldId The unique ID of the field.
805
+ * @param {String} [workflowId] The unique ID of the workflow.
806
+ * @returns {Promise<unknown>}
807
+ */
808
+ async deleteConfigField(slug: string, fieldId: string, workflowId?: string): Promise<unknown> {
809
+ const res = await fetch(`${this.baseUrl}/api/v2/public/config/field/${fieldId}${workflowId ? `?workflow_id=${workflowId}` : ""}`, {
810
+ method: "DELETE",
811
+ headers: {
812
+ authorization: `Bearer ${this.token}`,
813
+ slug,
814
+ },
815
+ });
816
+
817
+ if (res.status >= 400 && res.status < 600) {
818
+ const error = await res.json();
819
+ throw error;
820
+ }
821
+
822
+ return await res.json();
823
+ }
824
+
825
+ /**
826
+ * Returns the options for the specified field.
827
+ * @param {String} lhs The selected value of the lhs field.
828
+ * @param {String} slug The application slug.
829
+ * @param {String} fieldId The unique ID of the field.
830
+ * @param {String} [workflowId] The unique ID of the workflow, if this is a workflow field.
831
+ * @returns {Promise<RuleOptions>} The specified rule field's options.
832
+ */
833
+ async getFieldOptions(lhs: string, slug: string, fieldId: string, workflowId?: string): Promise<RuleOptions> {
834
+ const res = await fetch(`${this.baseUrl}/api/v2/public/config/rule-engine/${fieldId}${workflowId ? `?workflow_id=${workflowId}` : ""}`, {
835
+ method: "POST",
836
+ headers: {
837
+ authorization: `Bearer ${this.token}`,
838
+ "content-type": "application/json",
839
+ slug,
840
+ },
841
+ body: JSON.stringify({
842
+ rule_column: { lhs },
843
+ }),
844
+ });
845
+
846
+ if (res.status >= 400 && res.status < 600) {
847
+ const error = await res.json();
848
+ throw error;
849
+ }
850
+
851
+ return await res.json();
852
+ }
853
+
854
+ /**
855
+ * Returns the private workflows for the specified application.
856
+ * @param {Object} params
857
+ * @param {String} [params.slug]
858
+ * @param {String} [params.name]
859
+ * @param {Number} [params.page]
860
+ * @param {Number} [params.limit]
861
+ * @param {String} [params.start_date] ISO date string — filter workflows created on or after this date.
862
+ * @param {String} [params.end_date] ISO date string — filter workflows created on or before this date.
863
+ * @param {Boolean} [params.published] Filter by workflow published status.
864
+ * @returns
865
+ */
866
+ async getWorkflows({ page = 1, limit = 100, ...rest }: PublicWorkflowsPayload = {}): Promise<PaginatedResponse<PublicWorkflow>> {
867
+ const query = new URLSearchParams({ page: String(page), limit: String(limit) });
868
+ for (const key of Object.keys(rest)) {
869
+ const value = rest[key];
870
+ if (value !== undefined && value !== "") query.set(key, String(value));
871
+ }
872
+
873
+ const res = await fetch(`${this.baseUrl}/api/v2/public/workflow?${query}`, {
874
+ headers: {
875
+ authorization: `Bearer ${this.token}`,
876
+ },
877
+ });
878
+
879
+ if (res.status >= 400 && res.status < 600) {
880
+ const error = await res.json();
881
+ throw error;
882
+ }
883
+
884
+ return await res.json();
885
+ }
886
+
887
+ /**
888
+ * Create a public workflow for the linked account.
889
+ * @param {Object} params
890
+ * @param {String} params.name The workflow name.
891
+ * @param {String} [params.description] The workflow description.
892
+ * @param {String} [params.slug] The application slug in which this workflow should be created.
893
+ * If slug isn't set, the workflow will be created in the organization's default application.
894
+ * @returns {Promise<PublicWorkflow>} The created public workflow.
895
+ */
896
+ async createWorkflow(params: PublicWorkflowPayload): Promise<PublicWorkflow> {
897
+ const res = await fetch(`${this.baseUrl}/api/v2/public/workflow`, {
898
+ method: "POST",
899
+ headers: {
900
+ authorization: `Bearer ${this.token}`,
901
+ "content-type": "application/json",
902
+ },
903
+ body: JSON.stringify({
904
+ name: params.name,
905
+ description: params.description,
906
+ slug: params.slug,
907
+ }),
908
+ });
909
+
910
+ if (res.status >= 400 && res.status < 600) {
911
+ const error = await res.json();
912
+ throw error;
913
+ }
914
+
915
+ const data = await res.json();
916
+ return data?.workflow ?? data;
917
+ }
918
+
919
+ /**
920
+ * Delete the specified public workflow.
921
+ * @param {String} workflowId The workflow ID.
922
+ * @returns {Promise<unknown>}
923
+ */
924
+ async deleteWorkflow(workflowId: string): Promise<unknown> {
925
+ const res = await fetch(`${this.baseUrl}/api/v2/public/workflow/${workflowId}`, {
926
+ method: "DELETE",
927
+ headers: {
928
+ authorization: `Bearer ${this.token}`,
929
+ },
930
+ });
931
+
932
+ if (res.status >= 400 && res.status < 600) {
933
+ const error = await res.json();
934
+ throw error;
935
+ }
936
+
937
+ return await res.json();
938
+ }
939
+
940
+ /**
941
+ * Returns the execution payload for the specified public workflow.
942
+ * @param {String} workflowId The workflow ID.
943
+ * @returns {Promise<WorkflowPayloadResponse>} The workflow payload response.
944
+ */
945
+ async getWorkflowPayload(workflowId: string): Promise<WorkflowPayloadResponse> {
946
+ const res = await fetch(`${this.baseUrl}/api/v2/public/workflow/request-structure/${workflowId}`, {
947
+ headers: {
948
+ authorization: `Bearer ${this.token}`,
949
+ },
950
+ });
951
+
952
+ if (res.status >= 400 && res.status < 600) {
953
+ const error = await res.json();
954
+ throw error;
955
+ }
956
+
957
+ return await res.json();
958
+ }
959
+
960
+ /**
961
+ * Execute the specified public workflow.
962
+ * @param {ExecuteWorkflowPayload} options The execution payload.
963
+ * @param {String} options.worklfow The workflow id or alias.
964
+ * @param {String} [options.slug] The application's slug this workflow belongs to. Slug is required if you're using workflow alias.
965
+ * @param {Record<string, any>} [options.payload] The execution payload.
966
+ * @returns {Promise<unknown>}
967
+ */
968
+ async executeWorkflow(options: ExecuteWorkflowPayload): Promise<unknown> {
969
+ const res = await fetch(`${this.baseUrl}/api/v2/public/workflow/${options?.worklfow}/execute`, {
970
+ method: "POST",
971
+ headers: {
972
+ authorization: `Bearer ${this.token}`,
973
+ "content-type": "application/json",
974
+ slug: options?.slug || "",
975
+ sync_execution: options?.sync_execution ? "true" : "false",
976
+ },
977
+ body: JSON.stringify(options?.payload),
978
+ });
979
+
980
+ if (res.status >= 400 && res.status < 600) {
981
+ const error = await res.json();
982
+ throw error;
983
+ }
984
+
985
+ return await res.json();
986
+ }
987
+
988
+ /**
989
+ * Returns the workflow execution logs for the linked account.
990
+ * @param {Object} [params]
991
+ * @param {Number} [params.page]
992
+ * @param {Number} [params.limit]
993
+ * @param {String} [params.status] - Filter by execution status (COMPLETED, RUNNING, ERRORED, STOPPED, STOPPING, TIMED_OUT)
994
+ * @param {String} [params.workflow_name] - Filter by workflow name
995
+ * @param {String} [params.workflow_id] - Filter by workflow ID
996
+ * @param {String} [params.start_date] - Filter executions after this date
997
+ * @param {String} [params.end_date] - Filter executions before this date
998
+ * @param {String} [params.execution_type] - Filter by execution type (SYNC, ASYNC)
999
+ * @param {String} [params.execution_source] - Filter by execution source (Event, Schedule, API Call)
1000
+ * @returns {Promise<PaginatedResponse<Execution>>} The paginated workflow execution logs.
1001
+ */
1002
+ async getExecutions({ page = 1, limit = 10, ...rest }: GetExecutionsParams = {}): Promise<PaginatedResponse<Execution>> {
1003
+ const query = new URLSearchParams({ page: String(page), limit: String(limit) });
1004
+ for (const key of Object.keys(rest)) {
1005
+ const value = rest[key];
1006
+ if (value !== undefined && value !== "") query.set(key, String(value));
1007
+ }
1008
+
1009
+ const res = await fetch(`${this.baseUrl}/api/v2/public/execution?${query}`, {
1010
+ headers: {
1011
+ authorization: `Bearer ${this.token}`,
1012
+ },
1013
+ });
1014
+
1015
+ if (res.status >= 400 && res.status < 600) {
1016
+ const error = await res.json();
1017
+ throw error;
1018
+ }
1019
+
1020
+ return await res.json();
1021
+ }
1022
+
1023
+ /**
1024
+ * Returns the specified workflow execution log.
1025
+ * @param {String} executionId The execution ID.
1026
+ * @returns {Promise<Execution>} The specified execution log.
1027
+ */
1028
+ async getExecution(executionId: string): Promise<Execution> {
1029
+ const res = await fetch(`${this.baseUrl}/api/v2/public/execution/${executionId}`, {
1030
+ headers: {
1031
+ authorization: `Bearer ${this.token}`,
1032
+ },
1033
+ });
1034
+
1035
+ if (res.status >= 400 && res.status < 600) {
1036
+ const error = await res.json();
1037
+ throw error;
1038
+ }
1039
+
1040
+ return await res.json();
1041
+ }
1042
+ }
1043
+
1044
+ export { Refold };