@abyss-project/probe 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +32 -32
- package/.prettierrc +5 -5
- package/README.md +22 -22
- package/dist/api/index.d.ts +2 -1
- package/dist/api/index.js +2 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/probe-delivery-subscription.api.d.ts +11 -0
- package/dist/api/probe-delivery-subscription.api.js +42 -0
- package/dist/api/probe-delivery-subscription.api.js.map +1 -0
- package/dist/api/probe-delivery-subscription.application.api.d.ts +11 -0
- package/dist/api/probe-delivery-subscription.application.api.js +38 -0
- package/dist/api/probe-delivery-subscription.application.api.js.map +1 -0
- package/dist/api/probe-webhook.application.api.d.ts +1 -1
- package/dist/api/probe-webhook.application.api.js.map +1 -1
- package/dist/index.d.ts +29 -7
- package/dist/index.js +29 -7
- package/dist/index.js.map +1 -1
- package/dist/types/enum/api-error.enum.d.ts +2 -1
- package/dist/types/enum/api-error.enum.js +1 -0
- package/dist/types/enum/api-error.enum.js.map +1 -1
- package/dist/types/enum/probe-scan.enum.js.map +1 -1
- package/dist/types/interface/api/requests/index.d.ts +1 -0
- package/dist/types/interface/api/requests/index.js +1 -0
- package/dist/types/interface/api/requests/index.js.map +1 -1
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.d.ts +23 -0
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.js +3 -0
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.js.map +1 -0
- package/dist/types/interface/api/requests/probe-webhook.request.d.ts +1 -4
- package/dist/types/interface/api/responses/index.d.ts +1 -0
- package/dist/types/interface/api/responses/index.js +1 -0
- package/dist/types/interface/api/responses/index.js.map +1 -1
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.d.ts +10 -0
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.js +3 -0
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.js.map +1 -0
- package/dist/types/tests/probe.dto.test.js +22 -0
- package/dist/types/tests/probe.dto.test.js.map +1 -1
- package/dist/utils/probe-webhook-signature.utils.js.map +1 -1
- package/package.json +19 -15
- package/src/api/index.ts +2 -1
- package/src/api/probe-delivery-subscription.api.ts +183 -0
- package/src/api/probe-delivery-subscription.application.api.ts +186 -0
- package/src/api/probe-scan.api.test.ts +47 -47
- package/src/api/probe-scan.api.ts +203 -203
- package/src/api/probe-scan.application.api.test.ts +35 -35
- package/src/api/probe-scan.application.api.ts +157 -157
- package/src/api/probe-usage.api.ts +47 -47
- package/src/api/probe-usage.application.api.ts +25 -25
- package/src/api/probe-webhook.application.api.test.ts +18 -18
- package/src/api/probe-webhook.application.api.ts +10 -23
- package/src/constants/index.ts +1 -1
- package/src/index.ts +73 -16
- package/src/types/enum/api-error.enum.ts +2 -0
- package/src/types/enum/index.ts +2 -2
- package/src/types/enum/probe-scan.enum.ts +3 -2
- package/src/types/index.ts +2 -2
- package/src/types/interface/api/index.ts +5 -5
- package/src/types/interface/api/requests/index.ts +1 -0
- package/src/types/interface/api/requests/probe-delivery-subscription.request.ts +42 -0
- package/src/types/interface/api/requests/probe-scan.request.ts +54 -54
- package/src/types/interface/api/requests/probe-usage.request.ts +7 -7
- package/src/types/interface/api/requests/probe-webhook.request.ts +9 -11
- package/src/types/interface/api/responses/index.ts +1 -0
- package/src/types/interface/api/responses/probe-delivery-subscription.response.ts +27 -0
- package/src/types/interface/api/responses/probe-scan.response.ts +45 -45
- package/src/types/interface/api/responses/probe-usage.response.ts +25 -25
- package/src/types/interface/api/responses/probe-webhook.response.ts +24 -24
- package/src/types/interface/api/type-message/api-error.ts +7 -7
- package/src/types/interface/api/type-message/base-paginate.ts +11 -11
- package/src/types/interface/api/type-message/response.ts +6 -6
- package/src/types/interface/index.ts +2 -2
- package/src/types/interface/models/index.ts +3 -3
- package/src/types/interface/models/probe-scan.dto.ts +67 -67
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +11 -14
- package/src/types/interface/models/probe-webhook.dto.ts +29 -29
- package/src/types/tests/probe.dto.test.ts +40 -4
- package/src/utils/enum.utils.ts +1 -1
- package/src/utils/error.utils.ts +30 -30
- package/src/utils/index.ts +4 -4
- package/src/utils/probe-scan-cost.utils.ts +101 -101
- package/src/utils/probe-webhook-signature.utils.ts +4 -3
- package/tsconfig.check.json +15 -15
- package/tsconfig.json +36 -36
- package/dist/api/probe-webhook.api.d.ts +0 -6
- package/dist/api/probe-webhook.api.js +0 -41
- package/dist/api/probe-webhook.api.js.map +0 -1
- package/dist/api/probe-webhook.api.test.d.ts +0 -1
- package/dist/api/probe-webhook.api.test.js +0 -43
- package/dist/api/probe-webhook.api.test.js.map +0 -1
- package/src/api/probe-webhook.api.test.ts +0 -17
- package/src/api/probe-webhook.api.ts +0 -119
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
// ──────────────────────────────────────────────
|
|
2
|
-
// AbyssProbe APPLICATION scan API — POST /application/:applicationId/scan
|
|
3
|
-
// (sync + async), GET /application/:applicationId/scan/:scanId (poll),
|
|
4
|
-
// GET /application/:applicationId/scan (history/search). Mirrors
|
|
5
|
-
// apps/api/src/api/controllers/probe-scan-application.controller.ts EXACTLY
|
|
6
|
-
// (see that file for the full contract this client targets) — the
|
|
7
|
-
// application counterpart of probe-scan.api.ts, for inter-service callers
|
|
8
|
-
// (abyss-storage, external integrations) authenticating with a project API
|
|
9
|
-
// key instead of a personal/org session.
|
|
10
|
-
//
|
|
11
|
-
// Reuses probe-scan.api.ts's `buildScanForm` (the global `FormData` + `Blob`,
|
|
12
|
-
// one code path for the browser and for Node — see that file's header for what
|
|
13
|
-
// a Node caller passes) and every request/response TYPE verbatim
|
|
14
|
-
// (`IScanOptions`, `IListScansQuery`, `IScanResponse`, `IScanSyncResponse`,
|
|
15
|
-
// `IScanAsyncResponse`, `IGetScanResponse`, `IPaginateScanResponse`) — never
|
|
16
|
-
// redefined here. `organizationId` is `Omit`'d from every option/query type
|
|
17
|
-
// below: unlike the personal/org route's `?organization_id=` override, an
|
|
18
|
-
// application caller's scope is entirely its `:applicationId` URL segment,
|
|
19
|
-
// resolved server-side by ProbeApplicationMiddleware (round-trips to
|
|
20
|
-
// abyss-main) — there is no scope query param to send.
|
|
21
|
-
//
|
|
22
|
-
// `authHeaderApplication` is kept LOCAL and unexported, same convention as
|
|
23
|
-
// the personal/org client's own `authHeader` (see probe-scan.api.ts's header
|
|
24
|
-
// comment) — it sends `API_KEY_APPLICATION_HEADER` (`abyss-api-key-
|
|
25
|
-
// application`, imported from this package's root) instead of the personal
|
|
26
|
-
// `abyss-api-key` header.
|
|
27
|
-
// ──────────────────────────────────────────────
|
|
28
|
-
|
|
29
|
-
import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
30
|
-
import { ProbeScanMode } from '../types';
|
|
31
|
-
import type {
|
|
32
|
-
IScanOptions,
|
|
33
|
-
IListScansQuery,
|
|
34
|
-
IScanResponse,
|
|
35
|
-
IScanSyncResponse,
|
|
36
|
-
IScanAsyncResponse,
|
|
37
|
-
IGetScanResponse,
|
|
38
|
-
IPaginateScanResponse,
|
|
39
|
-
} from '../types';
|
|
40
|
-
import { buildScanForm } from './probe-scan.api';
|
|
41
|
-
import type { ProbeScanFileInput } from './probe-scan.api';
|
|
42
|
-
|
|
43
|
-
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
44
|
-
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Turn a request/query options object into axios `params`: drops
|
|
49
|
-
* undefined/null and ISO-stringifies `Date`s. No key-renaming here (unlike
|
|
50
|
-
* probe-scan.api.ts#serializeProbeQuery's `organizationId` -> `organization_id`
|
|
51
|
-
* rename) — an application call never carries `organizationId` (`Omit`'d
|
|
52
|
-
* from every option/query type in this file), so there is nothing to rename.
|
|
53
|
-
*/
|
|
54
|
-
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
55
|
-
const out: Record<string, unknown> = {};
|
|
56
|
-
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
57
|
-
if (value === undefined || value === null) continue;
|
|
58
|
-
out[key] = value instanceof Date ? value.toISOString() : value;
|
|
59
|
-
}
|
|
60
|
-
return out;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* `POST /application/:applicationId/scan` — SYNC by default, ASYNC when
|
|
65
|
-
* `options.mode = ProbeScanMode.ASYNC` (identical contract to {@link
|
|
66
|
-
* ../probe-scan.api.scan | the personal/org `scan`} — see that function's
|
|
67
|
-
* doc comment for the full sequence). `mode` travels as a query param;
|
|
68
|
-
* `context` (JSON-encoded) and `callbackUrl` travel as multipart text fields
|
|
69
|
-
* alongside the file.
|
|
70
|
-
*
|
|
71
|
-
* Returns the SYNC (200, verdict inline) or ASYNC (202, `{ scanId, status:
|
|
72
|
-
* 'queued' }`) shape depending on `options.mode` — see {@link IScanResponse}.
|
|
73
|
-
* Prefer {@link scanSyncApplication} / {@link scanAsyncApplication} for a
|
|
74
|
-
* precisely-typed return instead of the union.
|
|
75
|
-
*/
|
|
76
|
-
export const scanApplication = async (
|
|
77
|
-
applicationId: string,
|
|
78
|
-
file: ProbeScanFileInput,
|
|
79
|
-
options: Omit<IScanOptions, 'organizationId'> = {},
|
|
80
|
-
applicationApiKey?: string,
|
|
81
|
-
): Promise<IScanResponse> => {
|
|
82
|
-
const form = buildScanForm(file, options);
|
|
83
|
-
return (
|
|
84
|
-
await AbyssProbeCore.axios.post<IScanResponse>(`application/${applicationId}/scan`, form, {
|
|
85
|
-
params: serializeProbeQuery({ mode: options.mode }),
|
|
86
|
-
headers: authHeaderApplication(applicationApiKey),
|
|
87
|
-
maxBodyLength: Infinity,
|
|
88
|
-
maxContentLength: Infinity,
|
|
89
|
-
})
|
|
90
|
-
).data;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/** {@link scanApplication}, forced to `mode: sync` — HTTP 200, verdict returned inline. */
|
|
94
|
-
export const scanSyncApplication = async (
|
|
95
|
-
applicationId: string,
|
|
96
|
-
file: ProbeScanFileInput,
|
|
97
|
-
options: Omit<IScanOptions, 'organizationId' | 'mode' | 'callbackUrl'> = {},
|
|
98
|
-
applicationApiKey?: string,
|
|
99
|
-
): Promise<IScanSyncResponse> =>
|
|
100
|
-
scanApplication(
|
|
101
|
-
applicationId,
|
|
102
|
-
file,
|
|
103
|
-
{ ...options, mode: ProbeScanMode.SYNC },
|
|
104
|
-
applicationApiKey,
|
|
105
|
-
) as Promise<IScanSyncResponse>;
|
|
106
|
-
|
|
107
|
-
/** {@link scanApplication}, forced to `mode: async` — HTTP 202, job queued. */
|
|
108
|
-
export const scanAsyncApplication = async (
|
|
109
|
-
applicationId: string,
|
|
110
|
-
file: ProbeScanFileInput,
|
|
111
|
-
options: Omit<IScanOptions, 'organizationId' | 'mode'> = {},
|
|
112
|
-
applicationApiKey?: string,
|
|
113
|
-
): Promise<IScanAsyncResponse> =>
|
|
114
|
-
scanApplication(
|
|
115
|
-
applicationId,
|
|
116
|
-
file,
|
|
117
|
-
{ ...options, mode: ProbeScanMode.ASYNC },
|
|
118
|
-
applicationApiKey,
|
|
119
|
-
) as Promise<IScanAsyncResponse>;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* `GET /application/:applicationId/scan/:scanId` — poll the queued ->
|
|
123
|
-
* scanning -> done/error progression of an ASYNC scan (also answers for a
|
|
124
|
-
* SYNC scan's row). Cross-tenant guarded server-side by a direct
|
|
125
|
-
* `applicationId` column comparison (404, never 403) — needs no scope
|
|
126
|
-
* argument beyond `applicationId` itself, the scanId alone determines the
|
|
127
|
-
* rest.
|
|
128
|
-
*/
|
|
129
|
-
export const getScanApplication = async (
|
|
130
|
-
applicationId: string,
|
|
131
|
-
scanId: string,
|
|
132
|
-
applicationApiKey?: string,
|
|
133
|
-
): Promise<IGetScanResponse> =>
|
|
134
|
-
(
|
|
135
|
-
await AbyssProbeCore.axios.get<IGetScanResponse>(
|
|
136
|
-
`application/${applicationId}/scan/${scanId}`,
|
|
137
|
-
{ headers: authHeaderApplication(applicationApiKey) },
|
|
138
|
-
)
|
|
139
|
-
).data;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* `GET /application/:applicationId/scan` — paginated scan history/search for
|
|
143
|
-
* the calling application, newest first. Same filters as the personal/org
|
|
144
|
-
* `GET /scan` minus `organizationId` (see {@link IListScansQuery}) — the
|
|
145
|
-
* `:applicationId` URL segment is already the entire scope.
|
|
146
|
-
*/
|
|
147
|
-
export const listScansApplication = async (
|
|
148
|
-
applicationId: string,
|
|
149
|
-
query: Omit<IListScansQuery, 'organizationId'> = {},
|
|
150
|
-
applicationApiKey?: string,
|
|
151
|
-
): Promise<IPaginateScanResponse> =>
|
|
152
|
-
(
|
|
153
|
-
await AbyssProbeCore.axios.get<IPaginateScanResponse>(`application/${applicationId}/scan`, {
|
|
154
|
-
params: serializeProbeQuery(query),
|
|
155
|
-
headers: authHeaderApplication(applicationApiKey),
|
|
156
|
-
})
|
|
157
|
-
).data;
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe APPLICATION scan API — POST /application/:applicationId/scan
|
|
3
|
+
// (sync + async), GET /application/:applicationId/scan/:scanId (poll),
|
|
4
|
+
// GET /application/:applicationId/scan (history/search). Mirrors
|
|
5
|
+
// apps/api/src/api/controllers/probe-scan-application.controller.ts EXACTLY
|
|
6
|
+
// (see that file for the full contract this client targets) — the
|
|
7
|
+
// application counterpart of probe-scan.api.ts, for inter-service callers
|
|
8
|
+
// (abyss-storage, external integrations) authenticating with a project API
|
|
9
|
+
// key instead of a personal/org session.
|
|
10
|
+
//
|
|
11
|
+
// Reuses probe-scan.api.ts's `buildScanForm` (the global `FormData` + `Blob`,
|
|
12
|
+
// one code path for the browser and for Node — see that file's header for what
|
|
13
|
+
// a Node caller passes) and every request/response TYPE verbatim
|
|
14
|
+
// (`IScanOptions`, `IListScansQuery`, `IScanResponse`, `IScanSyncResponse`,
|
|
15
|
+
// `IScanAsyncResponse`, `IGetScanResponse`, `IPaginateScanResponse`) — never
|
|
16
|
+
// redefined here. `organizationId` is `Omit`'d from every option/query type
|
|
17
|
+
// below: unlike the personal/org route's `?organization_id=` override, an
|
|
18
|
+
// application caller's scope is entirely its `:applicationId` URL segment,
|
|
19
|
+
// resolved server-side by ProbeApplicationMiddleware (round-trips to
|
|
20
|
+
// abyss-main) — there is no scope query param to send.
|
|
21
|
+
//
|
|
22
|
+
// `authHeaderApplication` is kept LOCAL and unexported, same convention as
|
|
23
|
+
// the personal/org client's own `authHeader` (see probe-scan.api.ts's header
|
|
24
|
+
// comment) — it sends `API_KEY_APPLICATION_HEADER` (`abyss-api-key-
|
|
25
|
+
// application`, imported from this package's root) instead of the personal
|
|
26
|
+
// `abyss-api-key` header.
|
|
27
|
+
// ──────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
30
|
+
import { ProbeScanMode } from '../types';
|
|
31
|
+
import type {
|
|
32
|
+
IScanOptions,
|
|
33
|
+
IListScansQuery,
|
|
34
|
+
IScanResponse,
|
|
35
|
+
IScanSyncResponse,
|
|
36
|
+
IScanAsyncResponse,
|
|
37
|
+
IGetScanResponse,
|
|
38
|
+
IPaginateScanResponse,
|
|
39
|
+
} from '../types';
|
|
40
|
+
import { buildScanForm } from './probe-scan.api';
|
|
41
|
+
import type { ProbeScanFileInput } from './probe-scan.api';
|
|
42
|
+
|
|
43
|
+
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
44
|
+
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Turn a request/query options object into axios `params`: drops
|
|
49
|
+
* undefined/null and ISO-stringifies `Date`s. No key-renaming here (unlike
|
|
50
|
+
* probe-scan.api.ts#serializeProbeQuery's `organizationId` -> `organization_id`
|
|
51
|
+
* rename) — an application call never carries `organizationId` (`Omit`'d
|
|
52
|
+
* from every option/query type in this file), so there is nothing to rename.
|
|
53
|
+
*/
|
|
54
|
+
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
55
|
+
const out: Record<string, unknown> = {};
|
|
56
|
+
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
57
|
+
if (value === undefined || value === null) continue;
|
|
58
|
+
out[key] = value instanceof Date ? value.toISOString() : value;
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* `POST /application/:applicationId/scan` — SYNC by default, ASYNC when
|
|
65
|
+
* `options.mode = ProbeScanMode.ASYNC` (identical contract to {@link
|
|
66
|
+
* ../probe-scan.api.scan | the personal/org `scan`} — see that function's
|
|
67
|
+
* doc comment for the full sequence). `mode` travels as a query param;
|
|
68
|
+
* `context` (JSON-encoded) and `callbackUrl` travel as multipart text fields
|
|
69
|
+
* alongside the file.
|
|
70
|
+
*
|
|
71
|
+
* Returns the SYNC (200, verdict inline) or ASYNC (202, `{ scanId, status:
|
|
72
|
+
* 'queued' }`) shape depending on `options.mode` — see {@link IScanResponse}.
|
|
73
|
+
* Prefer {@link scanSyncApplication} / {@link scanAsyncApplication} for a
|
|
74
|
+
* precisely-typed return instead of the union.
|
|
75
|
+
*/
|
|
76
|
+
export const scanApplication = async (
|
|
77
|
+
applicationId: string,
|
|
78
|
+
file: ProbeScanFileInput,
|
|
79
|
+
options: Omit<IScanOptions, 'organizationId'> = {},
|
|
80
|
+
applicationApiKey?: string,
|
|
81
|
+
): Promise<IScanResponse> => {
|
|
82
|
+
const form = buildScanForm(file, options);
|
|
83
|
+
return (
|
|
84
|
+
await AbyssProbeCore.axios.post<IScanResponse>(`application/${applicationId}/scan`, form, {
|
|
85
|
+
params: serializeProbeQuery({ mode: options.mode }),
|
|
86
|
+
headers: authHeaderApplication(applicationApiKey),
|
|
87
|
+
maxBodyLength: Infinity,
|
|
88
|
+
maxContentLength: Infinity,
|
|
89
|
+
})
|
|
90
|
+
).data;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** {@link scanApplication}, forced to `mode: sync` — HTTP 200, verdict returned inline. */
|
|
94
|
+
export const scanSyncApplication = async (
|
|
95
|
+
applicationId: string,
|
|
96
|
+
file: ProbeScanFileInput,
|
|
97
|
+
options: Omit<IScanOptions, 'organizationId' | 'mode' | 'callbackUrl'> = {},
|
|
98
|
+
applicationApiKey?: string,
|
|
99
|
+
): Promise<IScanSyncResponse> =>
|
|
100
|
+
scanApplication(
|
|
101
|
+
applicationId,
|
|
102
|
+
file,
|
|
103
|
+
{ ...options, mode: ProbeScanMode.SYNC },
|
|
104
|
+
applicationApiKey,
|
|
105
|
+
) as Promise<IScanSyncResponse>;
|
|
106
|
+
|
|
107
|
+
/** {@link scanApplication}, forced to `mode: async` — HTTP 202, job queued. */
|
|
108
|
+
export const scanAsyncApplication = async (
|
|
109
|
+
applicationId: string,
|
|
110
|
+
file: ProbeScanFileInput,
|
|
111
|
+
options: Omit<IScanOptions, 'organizationId' | 'mode'> = {},
|
|
112
|
+
applicationApiKey?: string,
|
|
113
|
+
): Promise<IScanAsyncResponse> =>
|
|
114
|
+
scanApplication(
|
|
115
|
+
applicationId,
|
|
116
|
+
file,
|
|
117
|
+
{ ...options, mode: ProbeScanMode.ASYNC },
|
|
118
|
+
applicationApiKey,
|
|
119
|
+
) as Promise<IScanAsyncResponse>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* `GET /application/:applicationId/scan/:scanId` — poll the queued ->
|
|
123
|
+
* scanning -> done/error progression of an ASYNC scan (also answers for a
|
|
124
|
+
* SYNC scan's row). Cross-tenant guarded server-side by a direct
|
|
125
|
+
* `applicationId` column comparison (404, never 403) — needs no scope
|
|
126
|
+
* argument beyond `applicationId` itself, the scanId alone determines the
|
|
127
|
+
* rest.
|
|
128
|
+
*/
|
|
129
|
+
export const getScanApplication = async (
|
|
130
|
+
applicationId: string,
|
|
131
|
+
scanId: string,
|
|
132
|
+
applicationApiKey?: string,
|
|
133
|
+
): Promise<IGetScanResponse> =>
|
|
134
|
+
(
|
|
135
|
+
await AbyssProbeCore.axios.get<IGetScanResponse>(
|
|
136
|
+
`application/${applicationId}/scan/${scanId}`,
|
|
137
|
+
{ headers: authHeaderApplication(applicationApiKey) },
|
|
138
|
+
)
|
|
139
|
+
).data;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* `GET /application/:applicationId/scan` — paginated scan history/search for
|
|
143
|
+
* the calling application, newest first. Same filters as the personal/org
|
|
144
|
+
* `GET /scan` minus `organizationId` (see {@link IListScansQuery}) — the
|
|
145
|
+
* `:applicationId` URL segment is already the entire scope.
|
|
146
|
+
*/
|
|
147
|
+
export const listScansApplication = async (
|
|
148
|
+
applicationId: string,
|
|
149
|
+
query: Omit<IListScansQuery, 'organizationId'> = {},
|
|
150
|
+
applicationApiKey?: string,
|
|
151
|
+
): Promise<IPaginateScanResponse> =>
|
|
152
|
+
(
|
|
153
|
+
await AbyssProbeCore.axios.get<IPaginateScanResponse>(`application/${applicationId}/scan`, {
|
|
154
|
+
params: serializeProbeQuery(query),
|
|
155
|
+
headers: authHeaderApplication(applicationApiKey),
|
|
156
|
+
})
|
|
157
|
+
).data;
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
// ──────────────────────────────────────────────
|
|
2
|
-
// AbyssProbe usage API — WS5-3 (AbyssProbe UX rework). `GET /usage`: current
|
|
3
|
-
// ACCOUNT_AV_SCAN_UNITS ("tokens") used/limit/remaining for the caller's
|
|
4
|
-
// scope, via the same billing check the quota gate itself already uses (see
|
|
5
|
-
// apps/api/src/utils/probe-scan-billing.util.ts#getProbeScanUsage). Mirrors
|
|
6
|
-
// apps/api/src/api/controllers/probe-usage.controller.ts EXACTLY. No
|
|
7
|
-
// `probe/` path prefix — `@Controller({ prefixPath: '/usage' })` mounts
|
|
8
|
-
// directly at `usage`.
|
|
9
|
-
//
|
|
10
|
-
// See probe-usage.application.api.ts for the application/API-key-auth
|
|
11
|
-
// counterpart (`/application/:applicationId/usage`, Phase 3a).
|
|
12
|
-
// ──────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
import { AbyssProbeCore } from '..';
|
|
15
|
-
import type { IProbeUsageScopeQuery, IProbeUsageResponse } from '../types';
|
|
16
|
-
|
|
17
|
-
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
18
|
-
|
|
19
|
-
function authHeader(apiKey?: string): Record<string, string> {
|
|
20
|
-
return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Renames `organizationId` to the wire's `organization_id` (see probe-scan.api.ts). */
|
|
24
|
-
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
25
|
-
const out: Record<string, unknown> = {};
|
|
26
|
-
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
27
|
-
if (value === undefined || value === null) continue;
|
|
28
|
-
const wireKey = key === 'organizationId' ? 'organization_id' : key;
|
|
29
|
-
out[wireKey] = value;
|
|
30
|
-
}
|
|
31
|
-
return out;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* `GET /usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the caller's
|
|
36
|
-
* scope (personal by default, `organizationId` for an organization scope).
|
|
37
|
-
*/
|
|
38
|
-
export const getProbeUsage = async (
|
|
39
|
-
scope: IProbeUsageScopeQuery = {},
|
|
40
|
-
apiKey?: string,
|
|
41
|
-
): Promise<IProbeUsageResponse> =>
|
|
42
|
-
(
|
|
43
|
-
await AbyssProbeCore.axios.get<IProbeUsageResponse>('usage', {
|
|
44
|
-
params: serializeProbeQuery(scope),
|
|
45
|
-
headers: authHeader(apiKey),
|
|
46
|
-
})
|
|
47
|
-
).data;
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe usage API — WS5-3 (AbyssProbe UX rework). `GET /usage`: current
|
|
3
|
+
// ACCOUNT_AV_SCAN_UNITS ("tokens") used/limit/remaining for the caller's
|
|
4
|
+
// scope, via the same billing check the quota gate itself already uses (see
|
|
5
|
+
// apps/api/src/utils/probe-scan-billing.util.ts#getProbeScanUsage). Mirrors
|
|
6
|
+
// apps/api/src/api/controllers/probe-usage.controller.ts EXACTLY. No
|
|
7
|
+
// `probe/` path prefix — `@Controller({ prefixPath: '/usage' })` mounts
|
|
8
|
+
// directly at `usage`.
|
|
9
|
+
//
|
|
10
|
+
// See probe-usage.application.api.ts for the application/API-key-auth
|
|
11
|
+
// counterpart (`/application/:applicationId/usage`, Phase 3a).
|
|
12
|
+
// ──────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
import { AbyssProbeCore } from '..';
|
|
15
|
+
import type { IProbeUsageScopeQuery, IProbeUsageResponse } from '../types';
|
|
16
|
+
|
|
17
|
+
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
18
|
+
|
|
19
|
+
function authHeader(apiKey?: string): Record<string, string> {
|
|
20
|
+
return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Renames `organizationId` to the wire's `organization_id` (see probe-scan.api.ts). */
|
|
24
|
+
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
25
|
+
const out: Record<string, unknown> = {};
|
|
26
|
+
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
27
|
+
if (value === undefined || value === null) continue;
|
|
28
|
+
const wireKey = key === 'organizationId' ? 'organization_id' : key;
|
|
29
|
+
out[wireKey] = value;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `GET /usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the caller's
|
|
36
|
+
* scope (personal by default, `organizationId` for an organization scope).
|
|
37
|
+
*/
|
|
38
|
+
export const getProbeUsage = async (
|
|
39
|
+
scope: IProbeUsageScopeQuery = {},
|
|
40
|
+
apiKey?: string,
|
|
41
|
+
): Promise<IProbeUsageResponse> =>
|
|
42
|
+
(
|
|
43
|
+
await AbyssProbeCore.axios.get<IProbeUsageResponse>('usage', {
|
|
44
|
+
params: serializeProbeQuery(scope),
|
|
45
|
+
headers: authHeader(apiKey),
|
|
46
|
+
})
|
|
47
|
+
).data;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
// ──────────────────────────────────────────────
|
|
2
|
-
// AbyssProbe APPLICATION usage API — WS5-3 (AbyssProbe UX rework). `GET
|
|
3
|
-
// /application/:applicationId/usage`: current ACCOUNT_AV_SCAN_UNITS
|
|
4
|
-
// consumption for the calling application's resolved billing organization.
|
|
5
|
-
// Mirrors apps/api/src/api/controllers/probe-usage-application.controller.ts
|
|
6
|
-
// EXACTLY — the application counterpart of probe-usage.api.ts.
|
|
7
|
-
// ──────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
10
|
-
import type { IProbeUsageResponse } from '../types';
|
|
11
|
-
|
|
12
|
-
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
13
|
-
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** `GET /application/:applicationId/usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the calling application. */
|
|
17
|
-
export const getProbeUsageApplication = async (
|
|
18
|
-
applicationId: string,
|
|
19
|
-
applicationApiKey?: string,
|
|
20
|
-
): Promise<IProbeUsageResponse> =>
|
|
21
|
-
(
|
|
22
|
-
await AbyssProbeCore.axios.get<IProbeUsageResponse>(`application/${applicationId}/usage`, {
|
|
23
|
-
headers: authHeaderApplication(applicationApiKey),
|
|
24
|
-
})
|
|
25
|
-
).data;
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe APPLICATION usage API — WS5-3 (AbyssProbe UX rework). `GET
|
|
3
|
+
// /application/:applicationId/usage`: current ACCOUNT_AV_SCAN_UNITS
|
|
4
|
+
// consumption for the calling application's resolved billing organization.
|
|
5
|
+
// Mirrors apps/api/src/api/controllers/probe-usage-application.controller.ts
|
|
6
|
+
// EXACTLY — the application counterpart of probe-usage.api.ts.
|
|
7
|
+
// ──────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
10
|
+
import type { IProbeUsageResponse } from '../types';
|
|
11
|
+
|
|
12
|
+
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
13
|
+
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** `GET /application/:applicationId/usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the calling application. */
|
|
17
|
+
export const getProbeUsageApplication = async (
|
|
18
|
+
applicationId: string,
|
|
19
|
+
applicationApiKey?: string,
|
|
20
|
+
): Promise<IProbeUsageResponse> =>
|
|
21
|
+
(
|
|
22
|
+
await AbyssProbeCore.axios.get<IProbeUsageResponse>(`application/${applicationId}/usage`, {
|
|
23
|
+
headers: authHeaderApplication(applicationApiKey),
|
|
24
|
+
})
|
|
25
|
+
).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,27 +1,14 @@
|
|
|
1
1
|
// ──────────────────────────────────────────────
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// inter-service callers (abyss-storage, external integrations)
|
|
9
|
-
// authenticating with a project API key instead of a personal/org session.
|
|
2
|
+
// INTERNAL (P5 #792): AbyssProbe application webhooks, CRUD over the `probe_webhooks` rows owned
|
|
3
|
+
// by a calling application (create / list / delete / update, + paginated delivery history).
|
|
4
|
+
// They serve AbyssStorage's antivirus subscription until its client subscriptions move to Flow
|
|
5
|
+
// (L2). A client's own subscriptions to the verdict of its scans are the Flow delivery
|
|
6
|
+
// subscriptions (probe-delivery-subscription.application.api.ts). Mirrors
|
|
7
|
+
// apps/api/src/api/controllers/probe-webhook-application.controller.ts EXACTLY.
|
|
10
8
|
//
|
|
11
|
-
//
|
|
12
|
-
// `
|
|
13
|
-
// `
|
|
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.
|
|
9
|
+
// The scope is entirely the `:applicationId` URL segment, resolved server-side by
|
|
10
|
+
// ProbeApplicationMiddleware; there is nothing to select between. `authHeaderApplication` sends
|
|
11
|
+
// `API_KEY_APPLICATION_HEADER` (`abyss-api-key-application`, imported from this package's root).
|
|
25
12
|
// ──────────────────────────────────────────────
|
|
26
13
|
|
|
27
14
|
import { AbyssProbeCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
@@ -130,7 +117,7 @@ export const updateProbeWebhookApplication = async (
|
|
|
130
117
|
export const listProbeWebhookDeliveriesApplication = async (
|
|
131
118
|
applicationId: string,
|
|
132
119
|
webhookId: string,
|
|
133
|
-
query:
|
|
120
|
+
query: IListProbeWebhookDeliveriesQuery = {},
|
|
134
121
|
applicationApiKey?: string,
|
|
135
122
|
): Promise<IListProbeWebhookDeliveriesResponse> =>
|
|
136
123
|
(
|
package/src/constants/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|