@orthacms/webhooks-admin 0.5.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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/lib/application/useContentTypeOptions/index.d.ts +18 -0
- package/dist/lib/application/useContentTypeOptions/index.d.ts.map +1 -0
- package/dist/lib/application/useContentTypeOptions/index.js +40 -0
- package/dist/lib/application/useWebhookDeliveries/index.d.ts +19 -0
- package/dist/lib/application/useWebhookDeliveries/index.d.ts.map +1 -0
- package/dist/lib/application/useWebhookDeliveries/index.js +48 -0
- package/dist/lib/application/useWebhookEndpoints/index.d.ts +12 -0
- package/dist/lib/application/useWebhookEndpoints/index.d.ts.map +1 -0
- package/dist/lib/application/useWebhookEndpoints/index.js +26 -0
- package/dist/lib/application/useWebhookEvents/index.d.ts +9 -0
- package/dist/lib/application/useWebhookEvents/index.d.ts.map +1 -0
- package/dist/lib/application/useWebhookEvents/index.js +20 -0
- package/dist/lib/application/useWebhookMutations/index.d.ts +25 -0
- package/dist/lib/application/useWebhookMutations/index.d.ts.map +1 -0
- package/dist/lib/application/useWebhookMutations/index.js +79 -0
- package/dist/lib/application/useWorkspaceOptions/index.d.ts +9 -0
- package/dist/lib/application/useWorkspaceOptions/index.d.ts.map +1 -0
- package/dist/lib/application/useWorkspaceOptions/index.js +19 -0
- package/dist/lib/domain/contentTypeChoices/index.d.ts +65 -0
- package/dist/lib/domain/contentTypeChoices/index.d.ts.map +1 -0
- package/dist/lib/domain/contentTypeChoices/index.js +70 -0
- package/dist/lib/domain/headerRules/index.d.ts +37 -0
- package/dist/lib/domain/headerRules/index.d.ts.map +1 -0
- package/dist/lib/domain/headerRules/index.js +66 -0
- package/dist/lib/domain/types/contentTypeOption/index.d.ts +14 -0
- package/dist/lib/domain/types/contentTypeOption/index.d.ts.map +1 -0
- package/dist/lib/domain/types/contentTypeOption/index.js +1 -0
- package/dist/lib/domain/types/webhook/index.d.ts +102 -0
- package/dist/lib/domain/types/webhook/index.d.ts.map +1 -0
- package/dist/lib/domain/types/webhook/index.js +18 -0
- package/dist/lib/domain/types/workspaceOption/index.d.ts +16 -0
- package/dist/lib/domain/types/workspaceOption/index.d.ts.map +1 -0
- package/dist/lib/domain/types/workspaceOption/index.js +1 -0
- package/dist/lib/infrastructure/httpWebhookGateway/index.d.ts +11 -0
- package/dist/lib/infrastructure/httpWebhookGateway/index.d.ts.map +1 -0
- package/dist/lib/infrastructure/httpWebhookGateway/index.js +138 -0
- package/dist/lib/infrastructure/serverMessageOf/index.d.ts +16 -0
- package/dist/lib/infrastructure/serverMessageOf/index.d.ts.map +1 -0
- package/dist/lib/infrastructure/serverMessageOf/index.js +24 -0
- package/dist/lib/infrastructure/webhookGateway/index.d.ts +62 -0
- package/dist/lib/infrastructure/webhookGateway/index.d.ts.map +1 -0
- package/dist/lib/infrastructure/webhookGateway/index.js +1 -0
- package/dist/lib/infrastructure/webhookMapper/index.d.ts +104 -0
- package/dist/lib/infrastructure/webhookMapper/index.d.ts.map +1 -0
- package/dist/lib/infrastructure/webhookMapper/index.js +49 -0
- package/dist/lib/infrastructure/webhooksKeys/index.d.ts +35 -0
- package/dist/lib/infrastructure/webhooksKeys/index.d.ts.map +1 -0
- package/dist/lib/infrastructure/webhooksKeys/index.js +23 -0
- package/dist/lib/presentation/components/DeliveryStatusBadge/index.d.ts +6 -0
- package/dist/lib/presentation/components/DeliveryStatusBadge/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/DeliveryStatusBadge/index.js +30 -0
- package/dist/lib/presentation/components/RevealWebhookSecretDialog/index.d.ts +25 -0
- package/dist/lib/presentation/components/RevealWebhookSecretDialog/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/RevealWebhookSecretDialog/index.js +107 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/DeliveryDetailSheet/index.d.ts +19 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/DeliveryDetailSheet/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/DeliveryDetailSheet/index.js +72 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/index.d.ts +12 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhookDeliveriesPanel/index.js +132 -0
- package/dist/lib/presentation/components/WebhookForm/index.d.ts +46 -0
- package/dist/lib/presentation/components/WebhookForm/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhookForm/index.js +412 -0
- package/dist/lib/presentation/components/WebhooksEmpty/index.d.ts +5 -0
- package/dist/lib/presentation/components/WebhooksEmpty/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhooksEmpty/index.js +23 -0
- package/dist/lib/presentation/components/WebhooksNoAccess/index.d.ts +3 -0
- package/dist/lib/presentation/components/WebhooksNoAccess/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhooksNoAccess/index.js +18 -0
- package/dist/lib/presentation/components/WebhooksSkeleton/index.d.ts +20 -0
- package/dist/lib/presentation/components/WebhooksSkeleton/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhooksSkeleton/index.js +45 -0
- package/dist/lib/presentation/components/WebhooksTable/index.d.ts +12 -0
- package/dist/lib/presentation/components/WebhooksTable/index.d.ts.map +1 -0
- package/dist/lib/presentation/components/WebhooksTable/index.js +79 -0
- package/dist/lib/presentation/pages/WebhookDetailPage/index.d.ts +10 -0
- package/dist/lib/presentation/pages/WebhookDetailPage/index.d.ts.map +1 -0
- package/dist/lib/presentation/pages/WebhookDetailPage/index.js +191 -0
- package/dist/lib/presentation/pages/WebhookEditorPage/index.d.ts +28 -0
- package/dist/lib/presentation/pages/WebhookEditorPage/index.d.ts.map +1 -0
- package/dist/lib/presentation/pages/WebhookEditorPage/index.js +149 -0
- package/dist/lib/presentation/pages/WebhooksPage/index.d.ts +11 -0
- package/dist/lib/presentation/pages/WebhooksPage/index.d.ts.map +1 -0
- package/dist/lib/presentation/pages/WebhooksPage/index.js +65 -0
- package/dist/lib/utils/webhooksPlugin/index.d.ts +35 -0
- package/dist/lib/utils/webhooksPlugin/index.d.ts.map +1 -0
- package/dist/lib/utils/webhooksPlugin/index.js +88 -0
- package/package.json +46 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which custom headers an endpoint may set.
|
|
3
|
+
*
|
|
4
|
+
* A **deliberate copy** of `@orthacms/webhooks-domain`'s `isAllowedCustomHeader`
|
|
5
|
+
* rather than an import: that package's barrel reaches `node:crypto` through
|
|
6
|
+
* the signature helpers, and pulling it into the browser bundle takes the whole
|
|
7
|
+
* admin down at load. The server enforces the same rule on every write — this
|
|
8
|
+
* copy only turns a `422` into an error beside the field that caused it.
|
|
9
|
+
*/
|
|
10
|
+
/** Header prefixes reserved for the delivery's own metadata. */
|
|
11
|
+
const RESERVED_PREFIXES = ['x-ortha-'];
|
|
12
|
+
/** Headers the transport owns, which an endpoint may never overwrite. */
|
|
13
|
+
const RESERVED_NAMES = [
|
|
14
|
+
'host',
|
|
15
|
+
'content-type',
|
|
16
|
+
'content-length',
|
|
17
|
+
'transfer-encoding',
|
|
18
|
+
'connection',
|
|
19
|
+
'user-agent'
|
|
20
|
+
];
|
|
21
|
+
/** A valid HTTP field name (RFC 9110 token characters). */
|
|
22
|
+
const TOKEN = /^[a-z0-9!#$%&'*+.^_`|~-]+$/;
|
|
23
|
+
/**
|
|
24
|
+
* Checks one header name.
|
|
25
|
+
*
|
|
26
|
+
* Overwriting `X-Ortha-Signature` or `X-Ortha-Event` would let a delivery claim
|
|
27
|
+
* to be something it is not, and `Host` is how a request aimed at one virtual
|
|
28
|
+
* host gets served by another — so both are refused rather than silently
|
|
29
|
+
* dropped at send time.
|
|
30
|
+
*/
|
|
31
|
+
export function rejectionFor(name) {
|
|
32
|
+
const lower = name.trim().toLowerCase();
|
|
33
|
+
if (lower.length === 0 || !TOKEN.test(lower))
|
|
34
|
+
return 'malformed';
|
|
35
|
+
if (RESERVED_NAMES.includes(lower))
|
|
36
|
+
return 'reserved';
|
|
37
|
+
if (RESERVED_PREFIXES.some((prefix) => lower.startsWith(prefix))) {
|
|
38
|
+
return 'reserved';
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/** Turns the stored map into rows, in a stable order. */
|
|
43
|
+
export function toHeaderRows(headers) {
|
|
44
|
+
return Object.entries(headers).map(([name, value], index) => ({
|
|
45
|
+
key: `${index}-${name}`,
|
|
46
|
+
name,
|
|
47
|
+
value
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Turns rows back into the map the API takes.
|
|
52
|
+
*
|
|
53
|
+
* Blank rows are dropped — an editor that has one empty row open is not
|
|
54
|
+
* expressing "send an empty header" — and a later row of the same name wins,
|
|
55
|
+
* because that is what the map would have done anyway.
|
|
56
|
+
*/
|
|
57
|
+
export function fromHeaderRows(rows) {
|
|
58
|
+
const headers = {};
|
|
59
|
+
for (const row of rows) {
|
|
60
|
+
const name = row.name.trim();
|
|
61
|
+
if (name.length === 0)
|
|
62
|
+
continue;
|
|
63
|
+
headers[name] = row.value.trim();
|
|
64
|
+
}
|
|
65
|
+
return headers;
|
|
66
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A content type as the endpoint editor's picker renders it — one row of the
|
|
3
|
+
* code-defined registry (`GET /api/content-schema`).
|
|
4
|
+
*
|
|
5
|
+
* The picker is a convenience over a free-text filter, not a closed list: an
|
|
6
|
+
* endpoint may legitimately name a type this build does not define yet.
|
|
7
|
+
*/
|
|
8
|
+
export type ContentTypeOption = {
|
|
9
|
+
/** The machine name, which is what the subscription filter matches on. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** The human label from the registry. */
|
|
12
|
+
label: string;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/domain/types/contentTypeOption/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every state a delivery can be in.
|
|
3
|
+
*
|
|
4
|
+
* Restated here rather than imported from `@orthacms/webhooks-domain`, and that
|
|
5
|
+
* is deliberate twice over. It is the convention — the admin restates the
|
|
6
|
+
* server's contracts locally, so a server-side rename surfaces as a type error
|
|
7
|
+
* here instead of as `undefined` in a cell. And it is a hard requirement: that
|
|
8
|
+
* package's barrel re-exports the HMAC helpers, which import `node:crypto`, so
|
|
9
|
+
* importing anything at all from it puts a Node built-in in the browser bundle
|
|
10
|
+
* and the whole admin fails to render.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DELIVERY_STATUSES: readonly ["pending", "delivering", "succeeded", "failed", "dead"];
|
|
13
|
+
/** One of {@link DELIVERY_STATUSES}. */
|
|
14
|
+
export type DeliveryStatus = (typeof DELIVERY_STATUSES)[number];
|
|
15
|
+
/** One configured endpoint, as the admin renders it. */
|
|
16
|
+
export type WebhookEndpoint = {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
url: string;
|
|
20
|
+
/** The trailing characters of the signing secret. Never the secret itself. */
|
|
21
|
+
secretHint: string;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
/** Empty means every kind. */
|
|
24
|
+
eventKinds: string[];
|
|
25
|
+
/** Empty means every content type. */
|
|
26
|
+
contentTypes: string[];
|
|
27
|
+
allWorkspaces: boolean;
|
|
28
|
+
/** Empty when {@link allWorkspaces} is true. */
|
|
29
|
+
workspaceIds: string[];
|
|
30
|
+
headers: Record<string, string>;
|
|
31
|
+
/** Set when the endpoint switched itself off after repeated failures. */
|
|
32
|
+
disabledReason: string | null;
|
|
33
|
+
consecutiveFailures: number;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
lastDelivery: WebhookLastDelivery | null;
|
|
37
|
+
};
|
|
38
|
+
/** The one-line delivery summary shown against an endpoint in the list. */
|
|
39
|
+
export type WebhookLastDelivery = {
|
|
40
|
+
id: string;
|
|
41
|
+
status: DeliveryStatus;
|
|
42
|
+
eventKind: string;
|
|
43
|
+
statusCode: number | null;
|
|
44
|
+
createdAt: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* An endpoint together with its freshly minted secret.
|
|
48
|
+
*
|
|
49
|
+
* Returned only by create and rotate — the one moment the plaintext exists
|
|
50
|
+
* outside the server.
|
|
51
|
+
*/
|
|
52
|
+
export type CreatedWebhookEndpoint = {
|
|
53
|
+
endpoint: WebhookEndpoint;
|
|
54
|
+
secret: string;
|
|
55
|
+
};
|
|
56
|
+
/** One row of an endpoint's delivery log. */
|
|
57
|
+
export type WebhookDelivery = {
|
|
58
|
+
id: string;
|
|
59
|
+
endpointId: string;
|
|
60
|
+
eventId: string;
|
|
61
|
+
eventKind: string;
|
|
62
|
+
workspaceId: string | null;
|
|
63
|
+
contentType: string | null;
|
|
64
|
+
status: DeliveryStatus;
|
|
65
|
+
attempts: number;
|
|
66
|
+
nextAttemptAt: string | null;
|
|
67
|
+
statusCode: number | null;
|
|
68
|
+
error: string | null;
|
|
69
|
+
durationMs: number | null;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
completedAt: string | null;
|
|
72
|
+
};
|
|
73
|
+
/** A delivery with the body that was sent and the response that came back. */
|
|
74
|
+
export type WebhookDeliveryDetail = WebhookDelivery & {
|
|
75
|
+
payload: unknown;
|
|
76
|
+
responseSnippet: string | null;
|
|
77
|
+
};
|
|
78
|
+
/** A page of deliveries. */
|
|
79
|
+
export type WebhookDeliveryPage = {
|
|
80
|
+
items: WebhookDelivery[];
|
|
81
|
+
total: number;
|
|
82
|
+
page: number;
|
|
83
|
+
pageSize: number;
|
|
84
|
+
pageCount: number;
|
|
85
|
+
};
|
|
86
|
+
/** The outcome of "Send test", reported in the dialog that asked for it. */
|
|
87
|
+
export type WebhookTestResult = {
|
|
88
|
+
ok: boolean;
|
|
89
|
+
statusCode: number | null;
|
|
90
|
+
error: string | null;
|
|
91
|
+
durationMs: number;
|
|
92
|
+
responseSnippet: string | null;
|
|
93
|
+
};
|
|
94
|
+
/** One subscribable event kind, as the picker renders it. */
|
|
95
|
+
export type WebhookEventOption = {
|
|
96
|
+
kind: string;
|
|
97
|
+
group: string;
|
|
98
|
+
label: string;
|
|
99
|
+
scopedByContentType: boolean;
|
|
100
|
+
carriesWorkspace: boolean;
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/domain/types/webhook/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every state a delivery can be in.
|
|
3
|
+
*
|
|
4
|
+
* Restated here rather than imported from `@orthacms/webhooks-domain`, and that
|
|
5
|
+
* is deliberate twice over. It is the convention — the admin restates the
|
|
6
|
+
* server's contracts locally, so a server-side rename surfaces as a type error
|
|
7
|
+
* here instead of as `undefined` in a cell. And it is a hard requirement: that
|
|
8
|
+
* package's barrel re-exports the HMAC helpers, which import `node:crypto`, so
|
|
9
|
+
* importing anything at all from it puts a Node built-in in the browser bundle
|
|
10
|
+
* and the whole admin fails to render.
|
|
11
|
+
*/
|
|
12
|
+
export const DELIVERY_STATUSES = [
|
|
13
|
+
'pending',
|
|
14
|
+
'delivering',
|
|
15
|
+
'succeeded',
|
|
16
|
+
'failed',
|
|
17
|
+
'dead'
|
|
18
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** A workspace as the endpoint editor's picker renders it. */
|
|
2
|
+
export type WorkspaceOption = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string | null;
|
|
6
|
+
/**
|
|
7
|
+
* The content-type slugs this workspace was granted (`workspace_content`).
|
|
8
|
+
*
|
|
9
|
+
* Empty means **granted nothing**, never "no filtering" — the same rule the
|
|
10
|
+
* server's own `WorkspaceGrantsQuery` states. The editor narrows its type
|
|
11
|
+
* picker to the union of the chosen workspaces' grants, because a type this
|
|
12
|
+
* workspace cannot hold can never produce an event here.
|
|
13
|
+
*/
|
|
14
|
+
contentTypes: string[];
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/domain/types/workspaceOption/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WebhookGateway } from '../webhookGateway';
|
|
2
|
+
/**
|
|
3
|
+
* HTTP implementation of {@link WebhookGateway} over the shared `apiClient`
|
|
4
|
+
* (axios, same-origin, cookie-authed; paths omit the `/api` dev-proxy prefix).
|
|
5
|
+
*
|
|
6
|
+
* Every response goes through a mapper and every failure through `toApiError`,
|
|
7
|
+
* so callers see this plugin's models and `ApiError` rather than axios
|
|
8
|
+
* internals. The single place `apiClient` is used in this package.
|
|
9
|
+
*/
|
|
10
|
+
export declare const httpWebhookGateway: WebhookGateway;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/infrastructure/httpWebhookGateway/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAkC1E;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,cA8JhC,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { apiClient, toApiError } from '@orthacms/utils-admin';
|
|
2
|
+
import { toWebhookDelivery, toWebhookDeliveryDetail, toWebhookEndpoint, toContentTypeOption, toWebhookEventOption, toWorkspaceOption } from '../webhookMapper';
|
|
3
|
+
/** Maps a created/rotated endpoint, secret included. */
|
|
4
|
+
function toCreated(dto) {
|
|
5
|
+
return { endpoint: toWebhookEndpoint(dto.endpoint), secret: dto.secret };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* HTTP implementation of {@link WebhookGateway} over the shared `apiClient`
|
|
9
|
+
* (axios, same-origin, cookie-authed; paths omit the `/api` dev-proxy prefix).
|
|
10
|
+
*
|
|
11
|
+
* Every response goes through a mapper and every failure through `toApiError`,
|
|
12
|
+
* so callers see this plugin's models and `ApiError` rather than axios
|
|
13
|
+
* internals. The single place `apiClient` is used in this package.
|
|
14
|
+
*/
|
|
15
|
+
export const httpWebhookGateway = {
|
|
16
|
+
async list() {
|
|
17
|
+
try {
|
|
18
|
+
const { data } = await apiClient.get('/webhooks');
|
|
19
|
+
return data.map(toWebhookEndpoint);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw toApiError(error);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
async get(id) {
|
|
26
|
+
try {
|
|
27
|
+
const { data } = await apiClient.get(`/webhooks/${id}`);
|
|
28
|
+
return toWebhookEndpoint(data);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw toApiError(error);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
async create(input) {
|
|
35
|
+
try {
|
|
36
|
+
const { data } = await apiClient.post('/webhooks', input);
|
|
37
|
+
return toCreated(data);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw toApiError(error);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async update(id, input) {
|
|
44
|
+
try {
|
|
45
|
+
const { data } = await apiClient.patch(`/webhooks/${id}`, input);
|
|
46
|
+
return toWebhookEndpoint(data);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw toApiError(error);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
async remove(id) {
|
|
53
|
+
try {
|
|
54
|
+
await apiClient.delete(`/webhooks/${id}`);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw toApiError(error);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async rotateSecret(id) {
|
|
61
|
+
try {
|
|
62
|
+
const { data } = await apiClient.post(`/webhooks/${id}/secret`);
|
|
63
|
+
return toCreated(data);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw toApiError(error);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
async test(id) {
|
|
70
|
+
try {
|
|
71
|
+
const { data } = await apiClient.post(`/webhooks/${id}/test`);
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw toApiError(error);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
async listDeliveries(id, params) {
|
|
79
|
+
try {
|
|
80
|
+
const { data } = await apiClient.get(`/webhooks/${id}/deliveries`, { params });
|
|
81
|
+
return { ...data, items: data.items.map(toWebhookDelivery) };
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw toApiError(error);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
async getDelivery(id, deliveryId) {
|
|
88
|
+
try {
|
|
89
|
+
const { data } = await apiClient.get(`/webhooks/${id}/deliveries/${deliveryId}`);
|
|
90
|
+
return toWebhookDeliveryDetail(data);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw toApiError(error);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
async redeliver(id, deliveryId) {
|
|
97
|
+
try {
|
|
98
|
+
const { data } = await apiClient.post(`/webhooks/${id}/deliveries/${deliveryId}/redeliver`);
|
|
99
|
+
return toWebhookDelivery(data);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw toApiError(error);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
async listEvents() {
|
|
106
|
+
try {
|
|
107
|
+
const { data } = await apiClient.get('/webhook-events');
|
|
108
|
+
return data.map(toWebhookEventOption);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
throw toApiError(error);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
async listWorkspaceOptions() {
|
|
115
|
+
try {
|
|
116
|
+
// Unpaginated and scoped to the caller's memberships by the server
|
|
117
|
+
// — `GET /api/workspaces` returns a bare array, which is also what
|
|
118
|
+
// the API-tokens picker reads.
|
|
119
|
+
const { data } = await apiClient.get('/workspaces');
|
|
120
|
+
return data.map(toWorkspaceOption);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
throw toApiError(error);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
async listContentTypeOptions() {
|
|
127
|
+
try {
|
|
128
|
+
// The registry the Content Library reads, not a webhooks-owned
|
|
129
|
+
// list: there is one source of truth for what types exist, and it
|
|
130
|
+
// is code, so this plugin borrows it rather than storing its own.
|
|
131
|
+
const { data } = await apiClient.get('/content-schema');
|
|
132
|
+
return data.map(toContentTypeOption);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
throw toApiError(error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The message the **server** wrote, when it wrote one.
|
|
3
|
+
*
|
|
4
|
+
* `ApiError.message` is axios's own text ("Request failed with status code
|
|
5
|
+
* 422"), which is useless in a form. The server's message — the one written for
|
|
6
|
+
* whoever typed the URL — is in the parsed body, which `ApiError` deliberately
|
|
7
|
+
* leaves opaque as `details` so the transport layer does not decide what an
|
|
8
|
+
* endpoint's error shape means.
|
|
9
|
+
*
|
|
10
|
+
* This decides it for this endpoint: NestJS's exception filter puts a human
|
|
11
|
+
* message on `message`, and a `ValidationPipe` failure puts an array there
|
|
12
|
+
* instead. An array is not shown — those are field-level messages the form
|
|
13
|
+
* already renders — so the caller falls back to its own copy.
|
|
14
|
+
*/
|
|
15
|
+
export declare function serverMessageOf(error: unknown): string | null;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/infrastructure/serverMessageOf/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ApiError } from '@orthacms/utils-admin';
|
|
2
|
+
/**
|
|
3
|
+
* The message the **server** wrote, when it wrote one.
|
|
4
|
+
*
|
|
5
|
+
* `ApiError.message` is axios's own text ("Request failed with status code
|
|
6
|
+
* 422"), which is useless in a form. The server's message — the one written for
|
|
7
|
+
* whoever typed the URL — is in the parsed body, which `ApiError` deliberately
|
|
8
|
+
* leaves opaque as `details` so the transport layer does not decide what an
|
|
9
|
+
* endpoint's error shape means.
|
|
10
|
+
*
|
|
11
|
+
* This decides it for this endpoint: NestJS's exception filter puts a human
|
|
12
|
+
* message on `message`, and a `ValidationPipe` failure puts an array there
|
|
13
|
+
* instead. An array is not shown — those are field-level messages the form
|
|
14
|
+
* already renders — so the caller falls back to its own copy.
|
|
15
|
+
*/
|
|
16
|
+
export function serverMessageOf(error) {
|
|
17
|
+
if (!(error instanceof ApiError))
|
|
18
|
+
return null;
|
|
19
|
+
const details = error.details;
|
|
20
|
+
if (typeof details !== 'object' || details === null)
|
|
21
|
+
return null;
|
|
22
|
+
const message = details['message'];
|
|
23
|
+
return typeof message === 'string' && message.length > 0 ? message : null;
|
|
24
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { CreatedWebhookEndpoint, WebhookDelivery, WebhookDeliveryDetail, WebhookDeliveryPage, WebhookEndpoint, WebhookEventOption, WebhookTestResult } from '../../domain/types/webhook';
|
|
2
|
+
import type { ContentTypeOption } from '../../domain/types/contentTypeOption';
|
|
3
|
+
import type { WorkspaceOption } from '../../domain/types/workspaceOption';
|
|
4
|
+
import type { DeliveriesListParams } from '../webhooksKeys';
|
|
5
|
+
/**
|
|
6
|
+
* What the endpoint editor submits.
|
|
7
|
+
*
|
|
8
|
+
* The three filters are all optional and all mean "everything" when omitted —
|
|
9
|
+
* which is also what the server does with them, so the dialog's "All" toggles
|
|
10
|
+
* map to simply not sending the field.
|
|
11
|
+
*/
|
|
12
|
+
export type SaveWebhookInput = {
|
|
13
|
+
name: string;
|
|
14
|
+
url: string;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
eventKinds?: string[];
|
|
17
|
+
contentTypes?: string[];
|
|
18
|
+
allWorkspaces?: boolean;
|
|
19
|
+
workspaceIds?: string[];
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The port over the webhooks management API — the one seam this plugin talks
|
|
24
|
+
* to instead of `apiClient`. {@link httpWebhookGateway} is the implementation.
|
|
25
|
+
*/
|
|
26
|
+
export type WebhookGateway = {
|
|
27
|
+
/** Every endpoint via `GET /api/webhooks`. */
|
|
28
|
+
list(): Promise<WebhookEndpoint[]>;
|
|
29
|
+
/** One endpoint via `GET /api/webhooks/:id`. */
|
|
30
|
+
get(id: string): Promise<WebhookEndpoint>;
|
|
31
|
+
/**
|
|
32
|
+
* Creates one via `POST /api/webhooks`. The result carries the one-time
|
|
33
|
+
* signing secret — it is never returned again.
|
|
34
|
+
*/
|
|
35
|
+
create(input: SaveWebhookInput): Promise<CreatedWebhookEndpoint>;
|
|
36
|
+
/** Updates one via `PATCH /api/webhooks/:id`. */
|
|
37
|
+
update(id: string, input: SaveWebhookInput): Promise<WebhookEndpoint>;
|
|
38
|
+
/** Deletes one, and its log, via `DELETE /api/webhooks/:id`. */
|
|
39
|
+
remove(id: string): Promise<void>;
|
|
40
|
+
/** Mints a new signing secret via `POST /api/webhooks/:id/secret`. */
|
|
41
|
+
rotateSecret(id: string): Promise<CreatedWebhookEndpoint>;
|
|
42
|
+
/** Sends a `ping` and reports the response via `POST /api/webhooks/:id/test`. */
|
|
43
|
+
test(id: string): Promise<WebhookTestResult>;
|
|
44
|
+
/** One page of the delivery log. */
|
|
45
|
+
listDeliveries(id: string, params: DeliveriesListParams): Promise<WebhookDeliveryPage>;
|
|
46
|
+
/** One delivery with its request and response bodies. */
|
|
47
|
+
getDelivery(id: string, deliveryId: string): Promise<WebhookDeliveryDetail>;
|
|
48
|
+
/** Queues the same event again. */
|
|
49
|
+
redeliver(id: string, deliveryId: string): Promise<WebhookDelivery>;
|
|
50
|
+
/** The subscribable event catalogue, for the editor's picker. */
|
|
51
|
+
listEvents(): Promise<WebhookEventOption[]>;
|
|
52
|
+
/** Every workspace, for the editor's workspace picker. */
|
|
53
|
+
listWorkspaceOptions(): Promise<WorkspaceOption[]>;
|
|
54
|
+
/**
|
|
55
|
+
* The code-defined content types, for the editor's type picker.
|
|
56
|
+
*
|
|
57
|
+
* A convenience over a free-text filter rather than the set of legal
|
|
58
|
+
* values: an endpoint may name a type this build does not define.
|
|
59
|
+
*/
|
|
60
|
+
listContentTypeOptions(): Promise<ContentTypeOption[]>;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/infrastructure/webhookGateway/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB,8CAA8C;IAC9C,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACnC,gDAAgD;IAChD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC1C;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE,iDAAiD;IACjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACtE,gEAAgE;IAChE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,sEAAsE;IACtE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC1D,iFAAiF;IACjF,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7C,oCAAoC;IACpC,cAAc,CACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,yDAAyD;IACzD,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC5E,mCAAmC;IACnC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACpE,iEAAiE;IACjE,UAAU,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC5C,0DAA0D;IAC1D,oBAAoB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACnD;;;;;OAKG;IACH,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;CAC1D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { WebhookDelivery, WebhookDeliveryDetail, WebhookEndpoint, WebhookEventOption } from '../../domain/types/webhook';
|
|
2
|
+
import type { ContentTypeOption } from '../../domain/types/contentTypeOption';
|
|
3
|
+
import type { WorkspaceOption } from '../../domain/types/workspaceOption';
|
|
4
|
+
/**
|
|
5
|
+
* The wire shapes and the mapping into the admin's models — the
|
|
6
|
+
* anti-corruption layer for this plugin.
|
|
7
|
+
*
|
|
8
|
+
* The admin restates the server's view types locally rather than importing
|
|
9
|
+
* them: the module boundary forbids reaching into a server package, and the
|
|
10
|
+
* restatement is what makes a server-side rename show up here as a type error
|
|
11
|
+
* instead of as `undefined` in a cell.
|
|
12
|
+
*/
|
|
13
|
+
/** `GET /api/webhooks` and `GET /api/webhooks/:id`. */
|
|
14
|
+
export type WebhookEndpointResponse = {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
url: string;
|
|
18
|
+
secretHint: string;
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
eventKinds: string[];
|
|
21
|
+
contentTypes: string[];
|
|
22
|
+
allWorkspaces: boolean;
|
|
23
|
+
workspaceIds: string[];
|
|
24
|
+
headers: Record<string, string>;
|
|
25
|
+
disabledReason: string | null;
|
|
26
|
+
consecutiveFailures: number;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
lastDelivery: WebhookLastDeliveryResponse | null;
|
|
30
|
+
};
|
|
31
|
+
/** The last-delivery summary carried on an endpoint row. */
|
|
32
|
+
export type WebhookLastDeliveryResponse = {
|
|
33
|
+
id: string;
|
|
34
|
+
status: string;
|
|
35
|
+
eventKind: string;
|
|
36
|
+
statusCode: number | null;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
};
|
|
39
|
+
/** The create/rotate response — the only one carrying a secret. */
|
|
40
|
+
export type CreatedWebhookEndpointResponse = {
|
|
41
|
+
endpoint: WebhookEndpointResponse;
|
|
42
|
+
secret: string;
|
|
43
|
+
};
|
|
44
|
+
/** One row of `GET /api/webhooks/:id/deliveries`. */
|
|
45
|
+
export type WebhookDeliveryResponse = {
|
|
46
|
+
id: string;
|
|
47
|
+
endpointId: string;
|
|
48
|
+
eventId: string;
|
|
49
|
+
eventKind: string;
|
|
50
|
+
workspaceId: string | null;
|
|
51
|
+
contentType: string | null;
|
|
52
|
+
status: string;
|
|
53
|
+
attempts: number;
|
|
54
|
+
nextAttemptAt: string | null;
|
|
55
|
+
statusCode: number | null;
|
|
56
|
+
error: string | null;
|
|
57
|
+
durationMs: number | null;
|
|
58
|
+
createdAt: string;
|
|
59
|
+
completedAt: string | null;
|
|
60
|
+
};
|
|
61
|
+
/** `GET /api/webhooks/:id/deliveries/:deliveryId`. */
|
|
62
|
+
export type WebhookDeliveryDetailResponse = WebhookDeliveryResponse & {
|
|
63
|
+
payload: unknown;
|
|
64
|
+
responseSnippet: string | null;
|
|
65
|
+
};
|
|
66
|
+
/** `GET /api/webhook-events`. */
|
|
67
|
+
export type WebhookEventResponse = {
|
|
68
|
+
kind: string;
|
|
69
|
+
group: string;
|
|
70
|
+
label: string;
|
|
71
|
+
scopedByContentType: boolean;
|
|
72
|
+
carriesWorkspace: boolean;
|
|
73
|
+
};
|
|
74
|
+
/** Only the fields the workspace picker needs from `GET /api/workspaces`. */
|
|
75
|
+
export type ContentTypeSummaryResponse = {
|
|
76
|
+
name: string;
|
|
77
|
+
label: string;
|
|
78
|
+
};
|
|
79
|
+
export type WorkspaceOptionResponse = {
|
|
80
|
+
id: string;
|
|
81
|
+
name: string;
|
|
82
|
+
description: string | null;
|
|
83
|
+
/** Granted content-type slugs; absent on an older server. */
|
|
84
|
+
content?: string[];
|
|
85
|
+
};
|
|
86
|
+
/** Maps an endpoint from the wire. */
|
|
87
|
+
export declare function toWebhookEndpoint(dto: WebhookEndpointResponse): WebhookEndpoint;
|
|
88
|
+
/** Maps one delivery row. */
|
|
89
|
+
export declare function toWebhookDelivery(dto: WebhookDeliveryResponse): WebhookDelivery;
|
|
90
|
+
/** Maps one delivery with its bodies. */
|
|
91
|
+
export declare function toWebhookDeliveryDetail(dto: WebhookDeliveryDetailResponse): WebhookDeliveryDetail;
|
|
92
|
+
/** Maps one event descriptor. */
|
|
93
|
+
export declare function toWebhookEventOption(dto: WebhookEventResponse): WebhookEventOption;
|
|
94
|
+
/** Maps a workspace row to the picker's option shape. */
|
|
95
|
+
export declare function toWorkspaceOption(dto: WorkspaceOptionResponse): WorkspaceOption;
|
|
96
|
+
/**
|
|
97
|
+
* Maps one content type from the registry.
|
|
98
|
+
*
|
|
99
|
+
* Only the two fields the picker needs — the rest of a summary (kind, path,
|
|
100
|
+
* `i18n`, …) describes how the type behaves, which the subscription filter has
|
|
101
|
+
* no opinion about.
|
|
102
|
+
*/
|
|
103
|
+
export declare function toContentTypeOption(dto: ContentTypeSummaryResponse): ContentTypeOption;
|
|
104
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/infrastructure/webhookMapper/index.ts"],"names":[],"mappings":"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"}
|