@abyss-project/probe 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.eslintrc.js +32 -32
  2. package/.prettierrc +5 -5
  3. package/README.md +22 -22
  4. package/package.json +10 -15
  5. package/src/api/index.ts +6 -6
  6. package/src/api/probe-scan.api.test.ts +47 -47
  7. package/src/api/probe-scan.api.ts +203 -203
  8. package/src/api/probe-scan.application.api.test.ts +35 -35
  9. package/src/api/probe-scan.application.api.ts +157 -157
  10. package/src/api/probe-usage.api.ts +47 -47
  11. package/src/api/probe-usage.application.api.ts +25 -25
  12. package/src/api/probe-webhook.api.test.ts +17 -17
  13. package/src/api/probe-webhook.api.ts +119 -119
  14. package/src/api/probe-webhook.application.api.test.ts +18 -18
  15. package/src/api/probe-webhook.application.api.ts +141 -141
  16. package/src/constants/index.ts +1 -1
  17. package/src/index.ts +205 -205
  18. package/src/types/enum/api-error.enum.ts +33 -33
  19. package/src/types/enum/index.ts +2 -2
  20. package/src/types/enum/probe-scan.enum.ts +44 -44
  21. package/src/types/index.ts +2 -2
  22. package/src/types/interface/api/index.ts +5 -5
  23. package/src/types/interface/api/requests/index.ts +3 -3
  24. package/src/types/interface/api/requests/probe-scan.request.ts +54 -54
  25. package/src/types/interface/api/requests/probe-usage.request.ts +7 -7
  26. package/src/types/interface/api/requests/probe-webhook.request.ts +33 -33
  27. package/src/types/interface/api/responses/index.ts +3 -3
  28. package/src/types/interface/api/responses/probe-scan.response.ts +45 -45
  29. package/src/types/interface/api/responses/probe-usage.response.ts +25 -25
  30. package/src/types/interface/api/responses/probe-webhook.response.ts +24 -24
  31. package/src/types/interface/api/type-message/api-error.ts +7 -7
  32. package/src/types/interface/api/type-message/base-paginate.ts +11 -11
  33. package/src/types/interface/api/type-message/response.ts +6 -6
  34. package/src/types/interface/index.ts +2 -2
  35. package/src/types/interface/models/index.ts +3 -3
  36. package/src/types/interface/models/probe-scan.dto.ts +67 -67
  37. package/src/types/interface/models/probe-webhook-delivery.dto.ts +73 -73
  38. package/src/types/interface/models/probe-webhook.dto.ts +29 -29
  39. package/src/types/tests/probe.dto.test.ts +156 -156
  40. package/src/utils/enum.utils.ts +1 -1
  41. package/src/utils/error.utils.ts +30 -30
  42. package/src/utils/index.ts +4 -4
  43. package/src/utils/probe-scan-cost.utils.ts +101 -101
  44. package/src/utils/probe-webhook-signature.utils.ts +56 -56
  45. package/tsconfig.check.json +15 -15
  46. package/tsconfig.json +36 -36
@@ -1,119 +1,119 @@
1
- // ──────────────────────────────────────────────
2
- // AbyssProbe webhook subscription API — CRUD over registered `probe_webhooks`
3
- // (create / list / delete / update, + paginated delivery history — mirrors
4
- // apps/api/src/api/controllers/probe-webhook.controller.ts EXACTLY, see that
5
- // file's header comment). No `probe/` path prefix — `@Controller({
6
- // prefixPath: '/webhook' })` mounts directly at `webhook`.
7
- //
8
- // See probe-webhook.application.api.ts for the application/API-key-auth
9
- // counterpart of this client (`/application/:applicationId/webhook...`,
10
- // Phase 3a) — it reuses every request/response type verbatim; only the URL
11
- // prefix, the extra `applicationId` argument, and the auth header differ.
12
- // ──────────────────────────────────────────────
13
-
14
- import { AbyssProbeCore } from '..';
15
- import type {
16
- ICreateProbeWebhookBody,
17
- IUpdateProbeWebhookBody,
18
- IProbeWebhookScopeQuery,
19
- IListProbeWebhookDeliveriesQuery,
20
- ICreateProbeWebhookResponse,
21
- IListProbeWebhookResponse,
22
- IDeleteProbeWebhookResponse,
23
- IUpdateProbeWebhookResponse,
24
- IListProbeWebhookDeliveriesResponse,
25
- } from '../types';
26
-
27
- const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
28
-
29
- function authHeader(apiKey?: string): Record<string, string> {
30
- return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
31
- }
32
-
33
- /** Renames `organizationId` to the wire's `organization_id` (see probe-scan.api.ts). */
34
- function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
35
- const out: Record<string, unknown> = {};
36
- for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
37
- if (value === undefined || value === null) continue;
38
- const wireKey = key === 'organizationId' ? 'organization_id' : key;
39
- out[wireKey] = value instanceof Date ? value.toISOString() : value;
40
- }
41
- return out;
42
- }
43
-
44
- /**
45
- * `POST /webhook` — register a callbackUrl for the caller's scope. The
46
- * response's `secret` field (HMAC signing secret) is returned ONLY here —
47
- * store it immediately, it cannot be re-revealed later.
48
- */
49
- export const createProbeWebhook = async (
50
- body: ICreateProbeWebhookBody,
51
- scope: IProbeWebhookScopeQuery = {},
52
- apiKey?: string,
53
- ): Promise<ICreateProbeWebhookResponse> =>
54
- (
55
- await AbyssProbeCore.axios.post<ICreateProbeWebhookResponse>('webhook', body, {
56
- params: serializeProbeQuery(scope),
57
- headers: authHeader(apiKey),
58
- })
59
- ).data;
60
-
61
- /** `GET /webhook` — flat, scope-filtered list (not paginated — bounded by WEBHOOK_MAX_PER_SCOPE server-side). */
62
- export const listProbeWebhook = async (
63
- scope: IProbeWebhookScopeQuery = {},
64
- apiKey?: string,
65
- ): Promise<IListProbeWebhookResponse> =>
66
- (
67
- await AbyssProbeCore.axios.get<IListProbeWebhookResponse>('webhook', {
68
- params: serializeProbeQuery(scope),
69
- headers: authHeader(apiKey),
70
- })
71
- ).data;
72
-
73
- /** `DELETE /webhook/:webhookId`. */
74
- export const deleteProbeWebhook = async (
75
- webhookId: string,
76
- scope: IProbeWebhookScopeQuery = {},
77
- apiKey?: string,
78
- ): Promise<IDeleteProbeWebhookResponse> =>
79
- (
80
- await AbyssProbeCore.axios.delete<IDeleteProbeWebhookResponse>(`webhook/${webhookId}`, {
81
- params: serializeProbeQuery(scope),
82
- headers: authHeader(apiKey),
83
- })
84
- ).data;
85
-
86
- /**
87
- * `PATCH /webhook/:webhookId` (WS5-5) — edit `callbackUrl` and/or `active`.
88
- * At least one field is required. Scoped like {@link deleteProbeWebhook}
89
- * (404, never 403, for a webhookId outside the resolved scope). The response
90
- * includes `secret` — re-displayable now, see {@link IProbeWebhook}.
91
- */
92
- export const updateProbeWebhook = async (
93
- webhookId: string,
94
- body: IUpdateProbeWebhookBody,
95
- scope: IProbeWebhookScopeQuery = {},
96
- apiKey?: string,
97
- ): Promise<IUpdateProbeWebhookResponse> =>
98
- (
99
- await AbyssProbeCore.axios.patch<IUpdateProbeWebhookResponse>(`webhook/${webhookId}`, body, {
100
- params: serializeProbeQuery(scope),
101
- headers: authHeader(apiKey),
102
- })
103
- ).data;
104
-
105
- /**
106
- * `GET /webhook/:webhookId/deliveries` (WS5-6) — paginated delivery-attempt
107
- * history for one registered webhook. Scoped like {@link deleteProbeWebhook}.
108
- */
109
- export const listProbeWebhookDeliveries = async (
110
- webhookId: string,
111
- query: IListProbeWebhookDeliveriesQuery = {},
112
- apiKey?: string,
113
- ): Promise<IListProbeWebhookDeliveriesResponse> =>
114
- (
115
- await AbyssProbeCore.axios.get<IListProbeWebhookDeliveriesResponse>(
116
- `webhook/${webhookId}/deliveries`,
117
- { params: serializeProbeQuery(query), headers: authHeader(apiKey) },
118
- )
119
- ).data;
1
+ // ──────────────────────────────────────────────
2
+ // AbyssProbe webhook subscription API — CRUD over registered `probe_webhooks`
3
+ // (create / list / delete / update, + paginated delivery history — mirrors
4
+ // apps/api/src/api/controllers/probe-webhook.controller.ts EXACTLY, see that
5
+ // file's header comment). No `probe/` path prefix — `@Controller({
6
+ // prefixPath: '/webhook' })` mounts directly at `webhook`.
7
+ //
8
+ // See probe-webhook.application.api.ts for the application/API-key-auth
9
+ // counterpart of this client (`/application/:applicationId/webhook...`,
10
+ // Phase 3a) — it reuses every request/response type verbatim; only the URL
11
+ // prefix, the extra `applicationId` argument, and the auth header differ.
12
+ // ──────────────────────────────────────────────
13
+
14
+ import { AbyssProbeCore } from '..';
15
+ import type {
16
+ ICreateProbeWebhookBody,
17
+ IUpdateProbeWebhookBody,
18
+ IProbeWebhookScopeQuery,
19
+ IListProbeWebhookDeliveriesQuery,
20
+ ICreateProbeWebhookResponse,
21
+ IListProbeWebhookResponse,
22
+ IDeleteProbeWebhookResponse,
23
+ IUpdateProbeWebhookResponse,
24
+ IListProbeWebhookDeliveriesResponse,
25
+ } from '../types';
26
+
27
+ const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
28
+
29
+ function authHeader(apiKey?: string): Record<string, string> {
30
+ return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
31
+ }
32
+
33
+ /** Renames `organizationId` to the wire's `organization_id` (see probe-scan.api.ts). */
34
+ function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
35
+ const out: Record<string, unknown> = {};
36
+ for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
37
+ if (value === undefined || value === null) continue;
38
+ const wireKey = key === 'organizationId' ? 'organization_id' : key;
39
+ out[wireKey] = value instanceof Date ? value.toISOString() : value;
40
+ }
41
+ return out;
42
+ }
43
+
44
+ /**
45
+ * `POST /webhook` — register a callbackUrl for the caller's scope. The
46
+ * response's `secret` field (HMAC signing secret) is returned ONLY here —
47
+ * store it immediately, it cannot be re-revealed later.
48
+ */
49
+ export const createProbeWebhook = async (
50
+ body: ICreateProbeWebhookBody,
51
+ scope: IProbeWebhookScopeQuery = {},
52
+ apiKey?: string,
53
+ ): Promise<ICreateProbeWebhookResponse> =>
54
+ (
55
+ await AbyssProbeCore.axios.post<ICreateProbeWebhookResponse>('webhook', body, {
56
+ params: serializeProbeQuery(scope),
57
+ headers: authHeader(apiKey),
58
+ })
59
+ ).data;
60
+
61
+ /** `GET /webhook` — flat, scope-filtered list (not paginated — bounded by WEBHOOK_MAX_PER_SCOPE server-side). */
62
+ export const listProbeWebhook = async (
63
+ scope: IProbeWebhookScopeQuery = {},
64
+ apiKey?: string,
65
+ ): Promise<IListProbeWebhookResponse> =>
66
+ (
67
+ await AbyssProbeCore.axios.get<IListProbeWebhookResponse>('webhook', {
68
+ params: serializeProbeQuery(scope),
69
+ headers: authHeader(apiKey),
70
+ })
71
+ ).data;
72
+
73
+ /** `DELETE /webhook/:webhookId`. */
74
+ export const deleteProbeWebhook = async (
75
+ webhookId: string,
76
+ scope: IProbeWebhookScopeQuery = {},
77
+ apiKey?: string,
78
+ ): Promise<IDeleteProbeWebhookResponse> =>
79
+ (
80
+ await AbyssProbeCore.axios.delete<IDeleteProbeWebhookResponse>(`webhook/${webhookId}`, {
81
+ params: serializeProbeQuery(scope),
82
+ headers: authHeader(apiKey),
83
+ })
84
+ ).data;
85
+
86
+ /**
87
+ * `PATCH /webhook/:webhookId` (WS5-5) — edit `callbackUrl` and/or `active`.
88
+ * At least one field is required. Scoped like {@link deleteProbeWebhook}
89
+ * (404, never 403, for a webhookId outside the resolved scope). The response
90
+ * includes `secret` — re-displayable now, see {@link IProbeWebhook}.
91
+ */
92
+ export const updateProbeWebhook = async (
93
+ webhookId: string,
94
+ body: IUpdateProbeWebhookBody,
95
+ scope: IProbeWebhookScopeQuery = {},
96
+ apiKey?: string,
97
+ ): Promise<IUpdateProbeWebhookResponse> =>
98
+ (
99
+ await AbyssProbeCore.axios.patch<IUpdateProbeWebhookResponse>(`webhook/${webhookId}`, body, {
100
+ params: serializeProbeQuery(scope),
101
+ headers: authHeader(apiKey),
102
+ })
103
+ ).data;
104
+
105
+ /**
106
+ * `GET /webhook/:webhookId/deliveries` (WS5-6) — paginated delivery-attempt
107
+ * history for one registered webhook. Scoped like {@link deleteProbeWebhook}.
108
+ */
109
+ export const listProbeWebhookDeliveries = async (
110
+ webhookId: string,
111
+ query: IListProbeWebhookDeliveriesQuery = {},
112
+ apiKey?: string,
113
+ ): Promise<IListProbeWebhookDeliveriesResponse> =>
114
+ (
115
+ await AbyssProbeCore.axios.get<IListProbeWebhookDeliveriesResponse>(
116
+ `webhook/${webhookId}/deliveries`,
117
+ { params: serializeProbeQuery(query), headers: authHeader(apiKey) },
118
+ )
119
+ ).data;
@@ -1,18 +1,18 @@
1
- // Type-level compile test for the probe-webhook APPLICATION api surface.
2
- // No jest runner in this SDK package; compile guard only (mirrors
3
- // probe-webhook.api.test.ts).
4
- // Run: npx tsc --noEmit (from packages/abyss_probe_core), or `npm run build`.
5
-
6
- import * as api from './probe-webhook.application.api';
7
-
8
- // All three functions must be exported — deliberately no update/reset-secret
9
- // (see probe-webhook.api.ts's header comment on the small CRUD surface).
10
- const _create: typeof api.createProbeWebhookApplication = api.createProbeWebhookApplication;
11
- const _list: typeof api.listProbeWebhookApplication = api.listProbeWebhookApplication;
12
- const _delete: typeof api.deleteProbeWebhookApplication = api.deleteProbeWebhookApplication;
13
-
14
- void _create;
15
- void _list;
16
- void _delete;
17
-
18
- export {};
1
+ // Type-level compile test for the probe-webhook APPLICATION api surface.
2
+ // No jest runner in this SDK package; compile guard only (mirrors
3
+ // probe-webhook.api.test.ts).
4
+ // Run: npx tsc --noEmit (from packages/abyss_probe_core), or `npm run build`.
5
+
6
+ import * as api from './probe-webhook.application.api';
7
+
8
+ // All three functions must be exported — deliberately no update/reset-secret
9
+ // (see probe-webhook.api.ts's header comment on the small CRUD surface).
10
+ const _create: typeof api.createProbeWebhookApplication = api.createProbeWebhookApplication;
11
+ const _list: typeof api.listProbeWebhookApplication = api.listProbeWebhookApplication;
12
+ const _delete: typeof api.deleteProbeWebhookApplication = api.deleteProbeWebhookApplication;
13
+
14
+ void _create;
15
+ void _list;
16
+ void _delete;
17
+
18
+ export {};
@@ -1,141 +1,141 @@
1
- // ──────────────────────────────────────────────
2
- // AbyssProbe APPLICATION webhook subscription API — CRUD over registered
3
- // `probe_webhooks` owned by a calling application (create / list / delete /
4
- // update, + paginated delivery history — same surface as the personal/org
5
- // client, see probe-webhook.api.ts's header comment). Mirrors
6
- // apps/api/src/api/controllers/probe-webhook-application.controller.ts
7
- // EXACTLY — the application counterpart of probe-webhook.api.ts, for
8
- // inter-service callers (abyss-storage, external integrations)
9
- // authenticating with a project API key instead of a personal/org session.
10
- //
11
- // Reuses every request/response TYPE verbatim (`ICreateProbeWebhookBody`,
12
- // `ICreateProbeWebhookResponse`, `IListProbeWebhookResponse`,
13
- // `IDeleteProbeWebhookResponse`, `IUpdateProbeWebhookBody`,
14
- // `IUpdateProbeWebhookResponse`, `IListProbeWebhookDeliveriesQuery`,
15
- // `IListProbeWebhookDeliveriesResponse`) — never redefined here. No scope
16
- // argument/query on any of these calls (unlike the personal/org client's
17
- // `IProbeWebhookScopeQuery`) — an application caller's scope is entirely its
18
- // `:applicationId` URL segment, resolved server-side by
19
- // ProbeApplicationMiddleware; there is nothing to select between.
20
- //
21
- // `authHeaderApplication` is kept LOCAL and unexported, same convention as
22
- // the personal/org client's own `authHeader` — it sends
23
- // `API_KEY_APPLICATION_HEADER` (`abyss-api-key-application`, imported from
24
- // this package's root) instead of the personal `abyss-api-key` header.
25
- // ──────────────────────────────────────────────
26
-
27
- import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
28
- import type {
29
- ICreateProbeWebhookBody,
30
- IUpdateProbeWebhookBody,
31
- IListProbeWebhookDeliveriesQuery,
32
- ICreateProbeWebhookResponse,
33
- IListProbeWebhookResponse,
34
- IDeleteProbeWebhookResponse,
35
- IUpdateProbeWebhookResponse,
36
- IListProbeWebhookDeliveriesResponse,
37
- } from '../types';
38
-
39
- function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
40
- return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
41
- }
42
-
43
- /** Renames nothing (no `organizationId` ever travels on an application call) — drops undefined/null and ISO-stringifies `Date`s, mirroring probe-scan.application.api.ts's own local helper. */
44
- function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
45
- const out: Record<string, unknown> = {};
46
- for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
47
- if (value === undefined || value === null) continue;
48
- out[key] = value instanceof Date ? value.toISOString() : value;
49
- }
50
- return out;
51
- }
52
-
53
- /**
54
- * `POST /application/:applicationId/webhook` — register a callbackUrl owned
55
- * by the calling application. The response's `secret` field (HMAC signing
56
- * secret) is returned ONLY here — store it immediately, it cannot be
57
- * re-revealed later.
58
- */
59
- export const createProbeWebhookApplication = async (
60
- applicationId: string,
61
- body: ICreateProbeWebhookBody,
62
- applicationApiKey?: string,
63
- ): Promise<ICreateProbeWebhookResponse> =>
64
- (
65
- await AbyssProbeCore.axios.post<ICreateProbeWebhookResponse>(
66
- `application/${applicationId}/webhook`,
67
- body,
68
- { headers: authHeaderApplication(applicationApiKey) },
69
- )
70
- ).data;
71
-
72
- /**
73
- * `GET /application/:applicationId/webhook` — flat list of the calling
74
- * application's own webhooks (not paginated — bounded by
75
- * WEBHOOK_MAX_PER_SCOPE server-side).
76
- */
77
- export const listProbeWebhookApplication = async (
78
- applicationId: string,
79
- applicationApiKey?: string,
80
- ): Promise<IListProbeWebhookResponse> =>
81
- (
82
- await AbyssProbeCore.axios.get<IListProbeWebhookResponse>(
83
- `application/${applicationId}/webhook`,
84
- { headers: authHeaderApplication(applicationApiKey) },
85
- )
86
- ).data;
87
-
88
- /**
89
- * `DELETE /application/:applicationId/webhook/:webhookId` — cross-tenant
90
- * guarded server-side by a direct `applicationId` comparison (404, never
91
- * 403).
92
- */
93
- export const deleteProbeWebhookApplication = async (
94
- applicationId: string,
95
- webhookId: string,
96
- applicationApiKey?: string,
97
- ): Promise<IDeleteProbeWebhookResponse> =>
98
- (
99
- await AbyssProbeCore.axios.delete<IDeleteProbeWebhookResponse>(
100
- `application/${applicationId}/webhook/${webhookId}`,
101
- { headers: authHeaderApplication(applicationApiKey) },
102
- )
103
- ).data;
104
-
105
- /**
106
- * `PATCH /application/:applicationId/webhook/:webhookId` (WS5-5) — edit
107
- * `callbackUrl` and/or `active` on a webhook owned by the calling
108
- * application. Cross-tenant guarded server-side (404, never 403). The
109
- * response includes `secret` — re-displayable now, see {@link IProbeWebhook}.
110
- */
111
- export const updateProbeWebhookApplication = async (
112
- applicationId: string,
113
- webhookId: string,
114
- body: IUpdateProbeWebhookBody,
115
- applicationApiKey?: string,
116
- ): Promise<IUpdateProbeWebhookResponse> =>
117
- (
118
- await AbyssProbeCore.axios.patch<IUpdateProbeWebhookResponse>(
119
- `application/${applicationId}/webhook/${webhookId}`,
120
- body,
121
- { headers: authHeaderApplication(applicationApiKey) },
122
- )
123
- ).data;
124
-
125
- /**
126
- * `GET /application/:applicationId/webhook/:webhookId/deliveries` (WS5-6) —
127
- * paginated delivery-attempt history for one webhook owned by the calling
128
- * application. Cross-tenant guarded server-side (404, never 403).
129
- */
130
- export const listProbeWebhookDeliveriesApplication = async (
131
- applicationId: string,
132
- webhookId: string,
133
- query: Omit<IListProbeWebhookDeliveriesQuery, 'organizationId'> = {},
134
- applicationApiKey?: string,
135
- ): Promise<IListProbeWebhookDeliveriesResponse> =>
136
- (
137
- await AbyssProbeCore.axios.get<IListProbeWebhookDeliveriesResponse>(
138
- `application/${applicationId}/webhook/${webhookId}/deliveries`,
139
- { params: serializeProbeQuery(query), headers: authHeaderApplication(applicationApiKey) },
140
- )
141
- ).data;
1
+ // ──────────────────────────────────────────────
2
+ // AbyssProbe APPLICATION webhook subscription API — CRUD over registered
3
+ // `probe_webhooks` owned by a calling application (create / list / delete /
4
+ // update, + paginated delivery history — same surface as the personal/org
5
+ // client, see probe-webhook.api.ts's header comment). Mirrors
6
+ // apps/api/src/api/controllers/probe-webhook-application.controller.ts
7
+ // EXACTLY — the application counterpart of probe-webhook.api.ts, for
8
+ // inter-service callers (abyss-storage, external integrations)
9
+ // authenticating with a project API key instead of a personal/org session.
10
+ //
11
+ // Reuses every request/response TYPE verbatim (`ICreateProbeWebhookBody`,
12
+ // `ICreateProbeWebhookResponse`, `IListProbeWebhookResponse`,
13
+ // `IDeleteProbeWebhookResponse`, `IUpdateProbeWebhookBody`,
14
+ // `IUpdateProbeWebhookResponse`, `IListProbeWebhookDeliveriesQuery`,
15
+ // `IListProbeWebhookDeliveriesResponse`) — never redefined here. No scope
16
+ // argument/query on any of these calls (unlike the personal/org client's
17
+ // `IProbeWebhookScopeQuery`) — an application caller's scope is entirely its
18
+ // `:applicationId` URL segment, resolved server-side by
19
+ // ProbeApplicationMiddleware; there is nothing to select between.
20
+ //
21
+ // `authHeaderApplication` is kept LOCAL and unexported, same convention as
22
+ // the personal/org client's own `authHeader` — it sends
23
+ // `API_KEY_APPLICATION_HEADER` (`abyss-api-key-application`, imported from
24
+ // this package's root) instead of the personal `abyss-api-key` header.
25
+ // ──────────────────────────────────────────────
26
+
27
+ import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
28
+ import type {
29
+ ICreateProbeWebhookBody,
30
+ IUpdateProbeWebhookBody,
31
+ IListProbeWebhookDeliveriesQuery,
32
+ ICreateProbeWebhookResponse,
33
+ IListProbeWebhookResponse,
34
+ IDeleteProbeWebhookResponse,
35
+ IUpdateProbeWebhookResponse,
36
+ IListProbeWebhookDeliveriesResponse,
37
+ } from '../types';
38
+
39
+ function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
40
+ return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
41
+ }
42
+
43
+ /** Renames nothing (no `organizationId` ever travels on an application call) — drops undefined/null and ISO-stringifies `Date`s, mirroring probe-scan.application.api.ts's own local helper. */
44
+ function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
45
+ const out: Record<string, unknown> = {};
46
+ for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
47
+ if (value === undefined || value === null) continue;
48
+ out[key] = value instanceof Date ? value.toISOString() : value;
49
+ }
50
+ return out;
51
+ }
52
+
53
+ /**
54
+ * `POST /application/:applicationId/webhook` — register a callbackUrl owned
55
+ * by the calling application. The response's `secret` field (HMAC signing
56
+ * secret) is returned ONLY here — store it immediately, it cannot be
57
+ * re-revealed later.
58
+ */
59
+ export const createProbeWebhookApplication = async (
60
+ applicationId: string,
61
+ body: ICreateProbeWebhookBody,
62
+ applicationApiKey?: string,
63
+ ): Promise<ICreateProbeWebhookResponse> =>
64
+ (
65
+ await AbyssProbeCore.axios.post<ICreateProbeWebhookResponse>(
66
+ `application/${applicationId}/webhook`,
67
+ body,
68
+ { headers: authHeaderApplication(applicationApiKey) },
69
+ )
70
+ ).data;
71
+
72
+ /**
73
+ * `GET /application/:applicationId/webhook` — flat list of the calling
74
+ * application's own webhooks (not paginated — bounded by
75
+ * WEBHOOK_MAX_PER_SCOPE server-side).
76
+ */
77
+ export const listProbeWebhookApplication = async (
78
+ applicationId: string,
79
+ applicationApiKey?: string,
80
+ ): Promise<IListProbeWebhookResponse> =>
81
+ (
82
+ await AbyssProbeCore.axios.get<IListProbeWebhookResponse>(
83
+ `application/${applicationId}/webhook`,
84
+ { headers: authHeaderApplication(applicationApiKey) },
85
+ )
86
+ ).data;
87
+
88
+ /**
89
+ * `DELETE /application/:applicationId/webhook/:webhookId` — cross-tenant
90
+ * guarded server-side by a direct `applicationId` comparison (404, never
91
+ * 403).
92
+ */
93
+ export const deleteProbeWebhookApplication = async (
94
+ applicationId: string,
95
+ webhookId: string,
96
+ applicationApiKey?: string,
97
+ ): Promise<IDeleteProbeWebhookResponse> =>
98
+ (
99
+ await AbyssProbeCore.axios.delete<IDeleteProbeWebhookResponse>(
100
+ `application/${applicationId}/webhook/${webhookId}`,
101
+ { headers: authHeaderApplication(applicationApiKey) },
102
+ )
103
+ ).data;
104
+
105
+ /**
106
+ * `PATCH /application/:applicationId/webhook/:webhookId` (WS5-5) — edit
107
+ * `callbackUrl` and/or `active` on a webhook owned by the calling
108
+ * application. Cross-tenant guarded server-side (404, never 403). The
109
+ * response includes `secret` — re-displayable now, see {@link IProbeWebhook}.
110
+ */
111
+ export const updateProbeWebhookApplication = async (
112
+ applicationId: string,
113
+ webhookId: string,
114
+ body: IUpdateProbeWebhookBody,
115
+ applicationApiKey?: string,
116
+ ): Promise<IUpdateProbeWebhookResponse> =>
117
+ (
118
+ await AbyssProbeCore.axios.patch<IUpdateProbeWebhookResponse>(
119
+ `application/${applicationId}/webhook/${webhookId}`,
120
+ body,
121
+ { headers: authHeaderApplication(applicationApiKey) },
122
+ )
123
+ ).data;
124
+
125
+ /**
126
+ * `GET /application/:applicationId/webhook/:webhookId/deliveries` (WS5-6) —
127
+ * paginated delivery-attempt history for one webhook owned by the calling
128
+ * application. Cross-tenant guarded server-side (404, never 403).
129
+ */
130
+ export const listProbeWebhookDeliveriesApplication = async (
131
+ applicationId: string,
132
+ webhookId: string,
133
+ query: Omit<IListProbeWebhookDeliveriesQuery, 'organizationId'> = {},
134
+ applicationApiKey?: string,
135
+ ): Promise<IListProbeWebhookDeliveriesResponse> =>
136
+ (
137
+ await AbyssProbeCore.axios.get<IListProbeWebhookDeliveriesResponse>(
138
+ `application/${applicationId}/webhook/${webhookId}/deliveries`,
139
+ { params: serializeProbeQuery(query), headers: authHeaderApplication(applicationApiKey) },
140
+ )
141
+ ).data;
@@ -1 +1 @@
1
- export {};
1
+ export {};