@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.
- package/clients/admin/admin-client.d.ts +2 -1
- package/clients/admin/admin-client.js +8 -2
- package/clients/dispatcher/action-listener.d.ts +47 -6
- package/clients/dispatcher/action-listener.js +17 -1
- package/clients/hatchet-client/hatchet-client.d.ts +1 -0
- package/clients/hatchet-client/hatchet-client.js +6 -0
- package/clients/rest/generated/Api.d.ts +38 -1
- package/clients/rest/generated/Api.js +37 -0
- package/clients/rest/generated/data-contracts.d.ts +72 -0
- package/clients/rest/generated/data-contracts.js +9 -1
- package/clients/worker/handler.d.ts +56 -0
- package/clients/worker/handler.js +160 -0
- package/clients/worker/worker.d.ts +10 -3
- package/clients/worker/worker.js +189 -149
- package/package.json +3 -3
- package/protoc/dispatcher/dispatcher.d.ts +3 -1
- package/protoc/dispatcher/dispatcher.js +23 -3
- package/protoc/events/events.d.ts +1 -1
- package/protoc/events/events.js +5 -0
- package/protoc/google/protobuf/timestamp.js +8 -0
- package/protoc/workflows/workflows.d.ts +1 -1
- package/protoc/workflows/workflows.js +5 -0
- package/util/parse.js +5 -0
|
@@ -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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
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<
|
|
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;
|