@hatchet-dev/typescript-sdk 0.7.2 → 0.8.0-alpha.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.
@@ -3,7 +3,7 @@ import { CreateWorkflowVersionOpts, RateLimitDuration, WorkflowServiceClient } f
3
3
  import { ClientConfig } from '../hatchet-client/client-config';
4
4
  import { Logger } from '../../util/logger';
5
5
  import { Api } from '../rest';
6
- import { WorkflowRunStatus } from '../rest/generated/data-contracts';
6
+ import { WebhookWorkerCreateRequest, WorkflowRunStatus } from '../rest/generated/data-contracts';
7
7
  type WorkflowMetricsQuery = {
8
8
  workflowId?: string;
9
9
  workflowName?: string;
@@ -40,6 +40,7 @@ export declare class AdminClient {
40
40
  */
41
41
  put_workflow(workflow: CreateWorkflowVersionOpts): Promise<void>;
42
42
  put_rate_limit(key: string, limit: number, duration?: RateLimitDuration): Promise<void>;
43
+ webhook_create(data: WebhookWorkerCreateRequest): Promise<import("axios").AxiosResponse<import("../rest/generated/data-contracts").WebhookWorker, any>>;
43
44
  /**
44
45
  * Run a new instance of a workflow with the given input. This will create a new workflow run and return the ID of the
45
46
  * new run.
@@ -72,6 +72,11 @@ class AdminClient {
72
72
  }
73
73
  });
74
74
  }
75
+ webhook_create(data) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ return this.api.webhookCreate(this.tenantId, data);
78
+ });
79
+ }
75
80
  /**
76
81
  * Run a new instance of a workflow with the given input. This will create a new workflow run and return the ID of the
77
82
  * new run.
@@ -82,11 +87,12 @@ class AdminClient {
82
87
  run_workflow(workflowName, input, options) {
83
88
  return __awaiter(this, void 0, void 0, function* () {
84
89
  try {
90
+ let wfName = workflowName;
85
91
  if (this.config.namespace && !workflowName.startsWith(this.config.namespace)) {
86
- workflowName = this.config.namespace + workflowName;
92
+ wfName = this.config.namespace + workflowName;
87
93
  }
88
94
  const inputStr = JSON.stringify(input);
89
- const resp = yield this.client.triggerWorkflow(Object.assign(Object.assign({ name: workflowName, input: inputStr }, options), { additionalMetadata: (options === null || options === void 0 ? void 0 : options.additionalMetadata)
95
+ const resp = yield this.client.triggerWorkflow(Object.assign(Object.assign({ name: wfName, input: inputStr }, options), { additionalMetadata: (options === null || options === void 0 ? void 0 : options.additionalMetadata)
90
96
  ? JSON.stringify(options === null || options === void 0 ? void 0 : options.additionalMetadata)
91
97
  : undefined }));
92
98
  return resp.workflowRunId;
@@ -1,26 +1,54 @@
1
1
  import { DispatcherClient as PbDispatcherClient, AssignedAction } from '../../protoc/dispatcher';
2
2
  import { ClientConfig } from '../hatchet-client/client-config';
3
3
  import { Logger } from '../../util/logger';
4
+ import { z } from 'zod';
4
5
  import { DispatcherClient } from './dispatcher-client';
5
6
  import { Heartbeat } from './heartbeat/heartbeat-controller';
6
7
  declare enum ListenStrategy {
7
8
  LISTEN_STRATEGY_V1 = 1,
8
9
  LISTEN_STRATEGY_V2 = 2
9
10
  }
10
- export interface Action {
11
+ export declare const ActionObject: z.ZodObject<{
12
+ tenantId: z.ZodString;
13
+ jobId: z.ZodString;
14
+ jobName: z.ZodString;
15
+ jobRunId: z.ZodString;
16
+ stepId: z.ZodString;
17
+ stepRunId: z.ZodString;
18
+ actionId: z.ZodString;
19
+ actionType: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
20
+ actionPayload: z.ZodString;
21
+ workflowRunId: z.ZodString;
22
+ getGroupKeyRunId: z.ZodOptional<z.ZodString>;
23
+ stepName: z.ZodString;
24
+ }, "strip", z.ZodTypeAny, {
11
25
  tenantId: string;
26
+ stepRunId: string;
27
+ workflowRunId: string;
12
28
  jobId: string;
13
29
  jobName: string;
14
30
  jobRunId: string;
15
31
  stepId: string;
16
- stepRunId: string;
17
32
  actionId: string;
18
- actionType: number;
19
33
  actionPayload: string;
34
+ stepName: string;
35
+ getGroupKeyRunId?: string | undefined;
36
+ actionType?: number | undefined;
37
+ }, {
38
+ tenantId: string;
39
+ stepRunId: string;
20
40
  workflowRunId: string;
21
- getGroupKeyRunId: string;
41
+ jobId: string;
42
+ jobName: string;
43
+ jobRunId: string;
44
+ stepId: string;
45
+ actionId: string;
46
+ actionPayload: string;
22
47
  stepName: string;
23
- }
48
+ getGroupKeyRunId?: string | undefined;
49
+ actionType?: unknown;
50
+ }>;
51
+ export type Action = z.infer<typeof ActionObject>;
24
52
  export declare class ActionListener {
25
53
  config: ClientConfig;
26
54
  client: PbDispatcherClient;
@@ -34,7 +62,20 @@ export declare class ActionListener {
34
62
  listenStrategy: ListenStrategy;
35
63
  heartbeat: Heartbeat;
36
64
  constructor(client: DispatcherClient, workerId: string, retryInterval?: number, retryCount?: number);
37
- actions: () => AsyncGenerator<Action, void, unknown>;
65
+ actions: () => AsyncGenerator<{
66
+ tenantId: string;
67
+ stepRunId: string;
68
+ workflowRunId: string;
69
+ jobId: string;
70
+ jobName: string;
71
+ jobRunId: string;
72
+ stepId: string;
73
+ actionId: string;
74
+ actionPayload: string;
75
+ stepName: string;
76
+ getGroupKeyRunId?: string | undefined;
77
+ actionType?: number | undefined;
78
+ }, void, unknown>;
38
79
  setListenStrategy(strategy: ListenStrategy): Promise<void>;
39
80
  getListenStrategy(): Promise<ListenStrategy>;
40
81
  incrementRetries(): Promise<void>;
@@ -32,11 +32,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
32
32
  return (mod && mod.__esModule) ? mod : { "default": mod };
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.ActionListener = void 0;
35
+ exports.ActionListener = exports.ActionObject = void 0;
36
+ const dispatcher_1 = require("../../protoc/dispatcher");
36
37
  const nice_grpc_1 = require("nice-grpc");
37
38
  const sleep_1 = __importDefault(require("../../util/sleep"));
38
39
  const hatchet_error_1 = __importDefault(require("../../util/errors/hatchet-error"));
39
40
  const logger_1 = require("../../util/logger");
41
+ const zod_1 = require("zod");
40
42
  const heartbeat_controller_1 = require("./heartbeat/heartbeat-controller");
41
43
  const DEFAULT_ACTION_LISTENER_RETRY_INTERVAL = 5000; // milliseconds
42
44
  const DEFAULT_ACTION_LISTENER_RETRY_COUNT = 20;
@@ -46,6 +48,20 @@ var ListenStrategy;
46
48
  ListenStrategy[ListenStrategy["LISTEN_STRATEGY_V1"] = 1] = "LISTEN_STRATEGY_V1";
47
49
  ListenStrategy[ListenStrategy["LISTEN_STRATEGY_V2"] = 2] = "LISTEN_STRATEGY_V2";
48
50
  })(ListenStrategy || (ListenStrategy = {}));
51
+ exports.ActionObject = zod_1.z.object({
52
+ tenantId: zod_1.z.string(),
53
+ jobId: zod_1.z.string(),
54
+ jobName: zod_1.z.string(),
55
+ jobRunId: zod_1.z.string(),
56
+ stepId: zod_1.z.string(),
57
+ stepRunId: zod_1.z.string(),
58
+ actionId: zod_1.z.string(),
59
+ actionType: zod_1.z.preprocess((s) => (0, dispatcher_1.actionTypeFromJSON)(s), zod_1.z.number().optional()),
60
+ actionPayload: zod_1.z.string(),
61
+ workflowRunId: zod_1.z.string(),
62
+ getGroupKeyRunId: zod_1.z.string().optional(),
63
+ stepName: zod_1.z.string(),
64
+ });
49
65
  class ActionListener {
50
66
  constructor(client, workerId, retryInterval = DEFAULT_ACTION_LISTENER_RETRY_INTERVAL, retryCount = DEFAULT_ACTION_LISTENER_RETRY_COUNT) {
51
67
  this.lastConnectionAttempt = 0;
@@ -29,4 +29,5 @@ export declare class HatchetClient {
29
29
  static init(config?: Partial<ClientConfig>, options?: HatchetClientOptions, axiosConfig?: AxiosRequestConfig): HatchetClient;
30
30
  run(workflow: string | Workflow): Promise<Worker>;
31
31
  worker(workflow: string | Workflow, maxRuns?: number): Promise<Worker>;
32
+ webhooks(workflow: Workflow): import("../worker/handler").WebhookHandler;
32
33
  }
@@ -142,5 +142,11 @@ class HatchetClient {
142
142
  return worker;
143
143
  });
144
144
  }
145
+ webhooks(workflow) {
146
+ const worker = new worker_1.Worker(this, {
147
+ name: workflow.id,
148
+ });
149
+ return worker.getHandler(workflow);
150
+ }
145
151
  }
146
152
  exports.HatchetClient = HatchetClient;
@@ -1,4 +1,4 @@
1
- import { APIMeta, AcceptInviteRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreatePullRequestFromStepRun, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, GetStepRunDiffResponse, LinkGithubRepositoryRequest, ListAPIMetaIntegration, ListAPITokensResponse, ListGithubAppInstallationsResponse, ListGithubBranchesResponse, ListGithubReposResponse, ListPullRequestsResponse, ListSNSIntegrations, ListSlackWebhooks, LogLineLevelField, LogLineList, LogLineOrderByDirection, LogLineOrderByField, LogLineSearch, PullRequestState, RejectInviteRequest, ReplayEventRequest, RerunStepRunRequest, SNSIntegration, StepRun, StepRunEventList, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMemberList, TriggerWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, Worker, WorkerList, Workflow, WorkflowID, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunStatus, WorkflowRunStatusList, WorkflowRunsCancelRequest, WorkflowRunsMetrics, WorkflowVersion, WorkflowVersionDefinition } from './data-contracts';
1
+ import { APIMeta, AcceptInviteRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreatePullRequestFromStepRun, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, GetStepRunDiffResponse, LinkGithubRepositoryRequest, ListAPIMetaIntegration, ListAPITokensResponse, ListGithubAppInstallationsResponse, ListGithubBranchesResponse, ListGithubReposResponse, ListPullRequestsResponse, ListSNSIntegrations, ListSlackWebhooks, LogLineLevelField, LogLineList, LogLineOrderByDirection, LogLineOrderByField, LogLineSearch, PullRequestState, RejectInviteRequest, ReplayEventRequest, RerunStepRunRequest, SNSIntegration, StepRun, StepRunEventList, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMember, TenantMemberList, TenantResourcePolicy, TriggerWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, WebhookWorker, WebhookWorkerCreateRequest, WebhookWorkerListResponse, Worker, WorkerList, Workflow, WorkflowID, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunStatus, WorkflowRunStatusList, WorkflowRunsCancelRequest, WorkflowRunsMetrics, WorkflowVersion, WorkflowVersionDefinition } from './data-contracts';
2
2
  import { HttpClient, RequestParams } from './http-client';
3
3
  export declare class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
4
4
  /**
@@ -190,6 +190,16 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
190
190
  * @secure
191
191
  */
192
192
  alertEmailGroupList: (tenant: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantAlertEmailGroupList, any>>;
193
+ /**
194
+ * @description Gets the resource policy for a tenant
195
+ *
196
+ * @tags Tenant
197
+ * @name TenantResourcePolicyGet
198
+ * @summary Create tenant alert email group
199
+ * @request GET:/api/v1/tenants/{tenant}/resource-policy
200
+ * @secure
201
+ */
202
+ tenantResourcePolicyGet: (tenant: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantResourcePolicy, any>>;
193
203
  /**
194
204
  * @description Updates a tenant alert email group
195
205
  *
@@ -475,6 +485,16 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
475
485
  * @secure
476
486
  */
477
487
  tenantMemberList: (tenant: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantMemberList, any>>;
488
+ /**
489
+ * @description Delete a member from a tenant
490
+ *
491
+ * @tags Tenant
492
+ * @name TenantMemberDelete
493
+ * @summary Delete a tenant member
494
+ * @request DELETE:/api/v1/tenants/{tenant}/members/{member}
495
+ * @secure
496
+ */
497
+ tenantMemberDelete: (tenant: string, member: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantMember, any>>;
478
498
  /**
479
499
  * @description Get the data for an event.
480
500
  *
@@ -899,4 +919,21 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
899
919
  * @secure
900
920
  */
901
921
  githubAppListBranches: (ghInstallation: string, ghRepoOwner: string, ghRepoName: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<ListGithubBranchesResponse, any>>;
922
+ /**
923
+ * @description Lists all webhooks
924
+ *
925
+ * @name WebhookList
926
+ * @summary List webhooks
927
+ * @request GET:/api/v1/webhook-workers/{tenant}
928
+ * @secure
929
+ */
930
+ webhookList: (tenant: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<WebhookWorkerListResponse, any>>;
931
+ /**
932
+ * @description Creates a webhook
933
+ *
934
+ * @name WebhookCreate
935
+ * @summary Create a webhook
936
+ * @request POST:/api/v1/webhook-workers/{tenant}/create
937
+ */
938
+ webhookCreate: (tenant: string, data: WebhookWorkerCreateRequest, params?: RequestParams) => Promise<import("axios").AxiosResponse<WebhookWorker, any>>;
902
939
  }
@@ -204,6 +204,16 @@ class Api extends http_client_1.HttpClient {
204
204
  * @secure
205
205
  */
206
206
  this.alertEmailGroupList = (tenant, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/alerting-email-groups`, method: 'GET', secure: true, format: 'json' }, params));
207
+ /**
208
+ * @description Gets the resource policy for a tenant
209
+ *
210
+ * @tags Tenant
211
+ * @name TenantResourcePolicyGet
212
+ * @summary Create tenant alert email group
213
+ * @request GET:/api/v1/tenants/{tenant}/resource-policy
214
+ * @secure
215
+ */
216
+ this.tenantResourcePolicyGet = (tenant, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/resource-policy`, method: 'GET', secure: true, format: 'json' }, params));
207
217
  /**
208
218
  * @description Updates a tenant alert email group
209
219
  *
@@ -461,6 +471,16 @@ class Api extends http_client_1.HttpClient {
461
471
  * @secure
462
472
  */
463
473
  this.tenantMemberList = (tenant, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/members`, method: 'GET', secure: true, format: 'json' }, params));
474
+ /**
475
+ * @description Delete a member from a tenant
476
+ *
477
+ * @tags Tenant
478
+ * @name TenantMemberDelete
479
+ * @summary Delete a tenant member
480
+ * @request DELETE:/api/v1/tenants/{tenant}/members/{member}
481
+ * @secure
482
+ */
483
+ this.tenantMemberDelete = (tenant, member, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/members/${member}`, method: 'DELETE', secure: true, format: 'json' }, params));
464
484
  /**
465
485
  * @description Get the data for an event.
466
486
  *
@@ -741,6 +761,23 @@ class Api extends http_client_1.HttpClient {
741
761
  * @secure
742
762
  */
743
763
  this.githubAppListBranches = (ghInstallation, ghRepoOwner, ghRepoName, params = {}) => this.request(Object.assign({ path: `/api/v1/github-app/installations/${ghInstallation}/repos/${ghRepoOwner}/${ghRepoName}/branches`, method: 'GET', secure: true, format: 'json' }, params));
764
+ /**
765
+ * @description Lists all webhooks
766
+ *
767
+ * @name WebhookList
768
+ * @summary List webhooks
769
+ * @request GET:/api/v1/webhook-workers/{tenant}
770
+ * @secure
771
+ */
772
+ this.webhookList = (tenant, params = {}) => this.request(Object.assign({ path: `/api/v1/webhook-workers/${tenant}`, method: 'GET', secure: true, format: 'json' }, params));
773
+ /**
774
+ * @description Creates a webhook
775
+ *
776
+ * @name WebhookCreate
777
+ * @summary Create a webhook
778
+ * @request POST:/api/v1/webhook-workers/{tenant}/create
779
+ */
780
+ this.webhookCreate = (tenant, data, params = {}) => this.request(Object.assign({ path: `/api/v1/webhook-workers/${tenant}/create`, method: 'POST', body: data, type: http_client_1.ContentType.Json, format: 'json' }, params));
744
781
  }
745
782
  }
746
783
  exports.Api = Api;
@@ -168,6 +168,8 @@ export interface Tenant {
168
168
  slug: string;
169
169
  /** Whether the tenant has opted out of analytics. */
170
170
  analyticsOptOut?: boolean;
171
+ /** Whether to alert tenant members. */
172
+ alertMemberEmails?: boolean;
171
173
  }
172
174
  export interface TenantMember {
173
175
  metadata: APIResourceMeta;
@@ -187,6 +189,35 @@ export declare enum TenantMemberRole {
187
189
  ADMIN = "ADMIN",
188
190
  MEMBER = "MEMBER"
189
191
  }
192
+ export declare enum TenantResource {
193
+ WORKER = "WORKER",
194
+ EVENT = "EVENT",
195
+ WORKFLOW_RUN = "WORKFLOW_RUN",
196
+ CRON = "CRON",
197
+ SCHEDULE = "SCHEDULE"
198
+ }
199
+ export interface TenantResourceLimit {
200
+ metadata: APIResourceMeta;
201
+ /** The resource associated with this limit. */
202
+ resource: TenantResource;
203
+ /** The limit associated with this limit. */
204
+ limitValue: number;
205
+ /** The alarm value associated with this limit to warn of approaching limit value. */
206
+ alarmValue?: number;
207
+ /** The current value associated with this limit. */
208
+ value: number;
209
+ /** The meter window for the limit. (i.e. 1 day, 1 week, 1 month) */
210
+ window?: string;
211
+ /**
212
+ * The last time the limit was refilled.
213
+ * @format date-time
214
+ */
215
+ lastRefill?: string;
216
+ }
217
+ export interface TenantResourcePolicy {
218
+ /** A list of resource limits for the tenant. */
219
+ limits: TenantResourceLimit[];
220
+ }
190
221
  export interface CreateTenantInviteRequest {
191
222
  /** The email of the user to invite. */
192
223
  email: string;
@@ -199,6 +230,14 @@ export interface UpdateTenantInviteRequest {
199
230
  }
200
231
  export interface TenantAlertingSettings {
201
232
  metadata: APIResourceMeta;
233
+ /** Whether to alert tenant members. */
234
+ alertMemberEmails?: boolean;
235
+ /** Whether to send alerts when workflow runs fail. */
236
+ enableWorkflowRunFailureAlerts?: boolean;
237
+ /** Whether to enable alerts when tokens are approaching expiration. */
238
+ enableExpiringTokenAlerts?: boolean;
239
+ /** Whether to enable alerts when tenant resources are approaching limits. */
240
+ enableTenantResourceLimitAlerts?: boolean;
202
241
  /** The max frequency at which to alert. */
203
242
  maxAlertingFrequency: string;
204
243
  /**
@@ -275,6 +314,14 @@ export interface UpdateTenantRequest {
275
314
  name?: string;
276
315
  /** Whether the tenant has opted out of analytics. */
277
316
  analyticsOptOut?: boolean;
317
+ /** Whether to alert tenant members. */
318
+ alertMemberEmails?: boolean;
319
+ /** Whether to send alerts when workflow runs fail. */
320
+ enableWorkflowRunFailureAlerts?: boolean;
321
+ /** Whether to enable alerts when tokens are approaching expiration. */
322
+ enableExpiringTokenAlerts?: boolean;
323
+ /** Whether to enable alerts when tenant resources are approaching limits. */
324
+ enableTenantResourceLimitAlerts?: boolean;
278
325
  /** The max frequency at which to alert. */
279
326
  maxAlertingFrequency?: string;
280
327
  }
@@ -847,3 +894,28 @@ export interface WorkflowMetrics {
847
894
  /** The total number of concurrency group keys. */
848
895
  groupKeyCount?: number;
849
896
  }
897
+ export interface WebhookWorker {
898
+ metadata: APIResourceMeta;
899
+ /** The webhook url. */
900
+ url: string;
901
+ /** The secret key for validation. */
902
+ secret: string;
903
+ }
904
+ export interface WebhookWorkerCreateRequest {
905
+ /** The webhook url. */
906
+ url: string;
907
+ /** The workflow IDs or names to register for this webhook worker. If not provided, workflows will be automatically detected. */
908
+ workflows?: string[];
909
+ /**
910
+ * The secret key for validation. If not provided, a random secret will be generated.
911
+ * @minLength 32
912
+ */
913
+ secret?: string;
914
+ }
915
+ export interface WebhookWorkerCreateResponse {
916
+ worker?: WebhookWorker;
917
+ }
918
+ export interface WebhookWorkerListResponse {
919
+ pagination?: PaginationResponse;
920
+ rows?: WebhookWorker[];
921
+ }
@@ -10,13 +10,21 @@
10
10
  * ---------------------------------------------------------------
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.LogLineOrderByDirection = exports.LogLineOrderByField = exports.LogLineLevel = exports.PullRequestState = exports.StepRunEventSeverity = exports.StepRunEventReason = exports.StepRunStatus = exports.JobRunStatus = exports.WorkflowRunStatus = exports.EventOrderByDirection = exports.EventOrderByField = exports.TenantMemberRole = void 0;
13
+ exports.LogLineOrderByDirection = exports.LogLineOrderByField = exports.LogLineLevel = exports.PullRequestState = exports.StepRunEventSeverity = exports.StepRunEventReason = exports.StepRunStatus = exports.JobRunStatus = exports.WorkflowRunStatus = exports.EventOrderByDirection = exports.EventOrderByField = exports.TenantResource = exports.TenantMemberRole = void 0;
14
14
  var TenantMemberRole;
15
15
  (function (TenantMemberRole) {
16
16
  TenantMemberRole["OWNER"] = "OWNER";
17
17
  TenantMemberRole["ADMIN"] = "ADMIN";
18
18
  TenantMemberRole["MEMBER"] = "MEMBER";
19
19
  })(TenantMemberRole || (exports.TenantMemberRole = TenantMemberRole = {}));
20
+ var TenantResource;
21
+ (function (TenantResource) {
22
+ TenantResource["WORKER"] = "WORKER";
23
+ TenantResource["EVENT"] = "EVENT";
24
+ TenantResource["WORKFLOW_RUN"] = "WORKFLOW_RUN";
25
+ TenantResource["CRON"] = "CRON";
26
+ TenantResource["SCHEDULE"] = "SCHEDULE";
27
+ })(TenantResource || (exports.TenantResource = TenantResource = {}));
20
28
  var EventOrderByField;
21
29
  (function (EventOrderByField) {
22
30
  EventOrderByField["CreatedAt"] = "createdAt";
@@ -0,0 +1,56 @@
1
+ /// <reference types="node" />
2
+ import { IncomingMessage, ServerResponse } from 'http';
3
+ import { Worker } from './worker';
4
+ export interface HandlerOpts {
5
+ secret: string;
6
+ }
7
+ export declare class WebhookHandler {
8
+ private worker;
9
+ constructor(worker: Worker);
10
+ /**
11
+ * Handles a request with a provided body, secret, and signature.
12
+ *
13
+ * @param {string | undefined} body - The body of the request.
14
+ * @param {string | undefined} secret - The secret used for signature verification.
15
+ * @param {string | string[] | undefined | null} signature - The signature of the request.
16
+ *
17
+ * @throws {HatchetError} - If no signature is provided or the signature is not a string.
18
+ * @throws {HatchetError} - If no secret is provided.
19
+ * @throws {HatchetError} - If no body is provided.
20
+ */
21
+ handle(body: string | undefined, secret: string | undefined, signature: string | string[] | undefined | null): Promise<void>;
22
+ private getHealthcheckResponse;
23
+ /**
24
+ * Express Handler
25
+ *
26
+ * This method is an asynchronous function that returns an Express middleware handler.
27
+ * The handler function is responsible for handling incoming requests and invoking the
28
+ * corresponding logic based on the provided secret.
29
+ *
30
+ * @param {string} secret - The secret key used to authenticate and authorize the incoming requests.
31
+ *
32
+ * @return {Function} - An Express middleware handler function that receives the request and response objects.
33
+ */
34
+ expressHandler({ secret }: HandlerOpts): (req: any, res: any) => void;
35
+ /**
36
+ * A method that returns an HTTP request handler.
37
+ *
38
+ * @param {string} secret - The secret key used for verification.
39
+ *
40
+ * @returns {function} - An HTTP request handler function.
41
+ */
42
+ httpHandler({ secret }: HandlerOpts): (req: IncomingMessage, res: ServerResponse) => void;
43
+ /**
44
+ * A method that returns a Next.js request handler.
45
+ *
46
+ * @param {any} req - The request object received from Next.js.
47
+ * @param {string} secret - The secret key used to verify the request.
48
+ * @return {Promise<Response>} - A Promise that resolves with a Response object.
49
+ */
50
+ nextJSHandler({ secret }: HandlerOpts): {
51
+ GET: () => Promise<Response>;
52
+ POST: (req: Request) => Promise<Response>;
53
+ PUT: (req: Request) => Promise<Response>;
54
+ };
55
+ private getBody;
56
+ }
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.WebhookHandler = void 0;
16
+ const hatchet_error_1 = __importDefault(require("../../util/errors/hatchet-error"));
17
+ const crypto_1 = require("crypto");
18
+ const action_listener_1 = require("../dispatcher/action-listener");
19
+ class WebhookHandler {
20
+ // eslint-disable-next-line no-useless-constructor,no-empty-function
21
+ constructor(worker) {
22
+ this.worker = worker;
23
+ }
24
+ /**
25
+ * Handles a request with a provided body, secret, and signature.
26
+ *
27
+ * @param {string | undefined} body - The body of the request.
28
+ * @param {string | undefined} secret - The secret used for signature verification.
29
+ * @param {string | string[] | undefined | null} signature - The signature of the request.
30
+ *
31
+ * @throws {HatchetError} - If no signature is provided or the signature is not a string.
32
+ * @throws {HatchetError} - If no secret is provided.
33
+ * @throws {HatchetError} - If no body is provided.
34
+ */
35
+ handle(body, secret, signature) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ if (!signature || typeof signature !== 'string') {
38
+ throw new hatchet_error_1.default('No signature provided');
39
+ }
40
+ if (!secret) {
41
+ throw new hatchet_error_1.default('No secret provided');
42
+ }
43
+ if (!body) {
44
+ throw new hatchet_error_1.default('No body provided');
45
+ }
46
+ // verify hmac signature
47
+ const actualSignature = (0, crypto_1.createHmac)('sha256', secret).update(body).digest('hex');
48
+ if (actualSignature !== signature) {
49
+ throw new hatchet_error_1.default(`Invalid signature, expected ${actualSignature}, got ${signature}`);
50
+ }
51
+ const action = action_listener_1.ActionObject.parse(JSON.parse(body));
52
+ yield this.worker.handleAction(action);
53
+ });
54
+ }
55
+ getHealthcheckResponse() {
56
+ return {
57
+ actions: Object.keys(this.worker.action_registry),
58
+ };
59
+ }
60
+ /**
61
+ * Express Handler
62
+ *
63
+ * This method is an asynchronous function that returns an Express middleware handler.
64
+ * The handler function is responsible for handling incoming requests and invoking the
65
+ * corresponding logic based on the provided secret.
66
+ *
67
+ * @param {string} secret - The secret key used to authenticate and authorize the incoming requests.
68
+ *
69
+ * @return {Function} - An Express middleware handler function that receives the request and response objects.
70
+ */
71
+ expressHandler({ secret }) {
72
+ return (req, res) => {
73
+ if (req.method === 'GET') {
74
+ res.sendStatus(200);
75
+ res.json(this.getHealthcheckResponse());
76
+ return;
77
+ }
78
+ if (req.method !== 'POST') {
79
+ res.sendStatus(405);
80
+ res.json({ error: 'Method not allowed' });
81
+ return;
82
+ }
83
+ this.handle(req.body, req.headers['x-hatchet-signature'], secret)
84
+ .then(() => {
85
+ res.sendStatus(200);
86
+ })
87
+ .catch((e) => {
88
+ res.sendStatus(500);
89
+ this.worker.logger.error(`Error handling request: ${e.message}`);
90
+ });
91
+ };
92
+ }
93
+ /**
94
+ * A method that returns an HTTP request handler.
95
+ *
96
+ * @param {string} secret - The secret key used for verification.
97
+ *
98
+ * @returns {function} - An HTTP request handler function.
99
+ */
100
+ httpHandler({ secret }) {
101
+ return (req, res) => {
102
+ const handle = () => __awaiter(this, void 0, void 0, function* () {
103
+ if (req.method === 'GET') {
104
+ res.writeHead(200, { 'Content-Type': 'application/json' });
105
+ res.write(JSON.stringify(this.getHealthcheckResponse()));
106
+ res.end();
107
+ return;
108
+ }
109
+ if (req.method !== 'POST') {
110
+ res.writeHead(405, { 'Content-Type': 'application/json' });
111
+ res.write(JSON.stringify({ error: 'Method not allowed' }));
112
+ res.end();
113
+ return;
114
+ }
115
+ const body = yield this.getBody(req);
116
+ yield this.handle(body, secret, req.headers['x-hatchet-signature']);
117
+ res.writeHead(200, 'OK');
118
+ res.end();
119
+ });
120
+ handle().catch((e) => {
121
+ this.worker.logger.error(`Error handling request: ${e.message}`);
122
+ res.writeHead(500, 'Internal server error');
123
+ res.end();
124
+ });
125
+ };
126
+ }
127
+ /**
128
+ * A method that returns a Next.js request handler.
129
+ *
130
+ * @param {any} req - The request object received from Next.js.
131
+ * @param {string} secret - The secret key used to verify the request.
132
+ * @return {Promise<Response>} - A Promise that resolves with a Response object.
133
+ */
134
+ nextJSHandler({ secret }) {
135
+ const healthcheck = () => __awaiter(this, void 0, void 0, function* () {
136
+ return new Response(JSON.stringify(this.getHealthcheckResponse()), { status: 200 });
137
+ });
138
+ const f = (req) => __awaiter(this, void 0, void 0, function* () {
139
+ yield this.handle(yield req.text(), secret, req.headers.get('x-hatchet-signature'));
140
+ return new Response('ok', { status: 200 });
141
+ });
142
+ return {
143
+ GET: healthcheck,
144
+ POST: f,
145
+ PUT: f,
146
+ };
147
+ }
148
+ getBody(req) {
149
+ return new Promise((resolve) => {
150
+ let body = '';
151
+ req.on('data', (chunk) => {
152
+ body += chunk;
153
+ });
154
+ req.on('end', () => {
155
+ resolve(body);
156
+ });
157
+ });
158
+ }
159
+ }
160
+ exports.WebhookHandler = WebhookHandler;