@sentry/api 0.445.0 → 0.446.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/README.md +28 -0
- package/dist/api-client/api-path.d.ts +34 -0
- package/dist/api-client/auth-token.d.ts +6 -0
- package/dist/api-client/core.d.ts +84 -0
- package/dist/api-client/endpoints/client-keys.d.ts +38 -0
- package/dist/api-client/endpoints/dashboards.d.ts +23 -0
- package/dist/api-client/endpoints/index.d.ts +18 -0
- package/dist/api-client/endpoints/index.js +762 -0
- package/dist/api-client/endpoints/monitors.d.ts +49 -0
- package/dist/api-client/endpoints/organizations.d.ts +35 -0
- package/dist/api-client/endpoints/profiling.d.ts +32 -0
- package/dist/api-client/endpoints/projects.d.ts +63 -0
- package/dist/api-client/endpoints/releases.d.ts +45 -0
- package/dist/api-client/endpoints/replays.d.ts +53 -0
- package/dist/api-client/endpoints/repositories.d.ts +31 -0
- package/dist/api-client/endpoints/snapshots.d.ts +29 -0
- package/dist/api-client/endpoints/teams.d.ts +23 -0
- package/dist/api-client/endpoints/traces.d.ts +25 -0
- package/dist/api-client/endpoints/uptime-monitors.d.ts +61 -0
- package/dist/api-client/errors.d.ts +151 -0
- package/dist/api-client/idempotent-operations.d.ts +33 -0
- package/dist/api-client/index.d.ts +20 -0
- package/dist/api-client/index.js +1647 -0
- package/dist/api-client/pagination.d.ts +119 -0
- package/dist/api-client/response-cache/body.d.ts +31 -0
- package/dist/api-client/response-cache/index.d.ts +14 -0
- package/dist/api-client/response-cache/invalidation.d.ts +42 -0
- package/dist/api-client/response-cache/keys.d.ts +25 -0
- package/dist/api-client/response-cache/memory-store.d.ts +37 -0
- package/dist/api-client/response-cache/policy.d.ts +81 -0
- package/dist/api-client/response-cache/store.d.ts +52 -0
- package/dist/api-client/response-cache/tiers.d.ts +28 -0
- package/dist/api-client/response.d.ts +27 -0
- package/dist/api-client/retry.d.ts +57 -0
- package/dist/api-client/standard-schema.d.ts +65 -0
- package/dist/api-client/time-params.d.ts +46 -0
- package/dist/api-client/transport.d.ts +156 -0
- package/dist/api-client/validate.d.ts +22 -0
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -547,6 +547,34 @@ A generic `paginateUpTo` fetcher receives `(cursor, remaining)`. Existing cursor
|
|
|
547
547
|
|
|
548
548
|
Generic helpers delegate cancellation to your fetcher. Pass its signal through to the operation or transport it invokes; the helper cannot cancel an arbitrary callback.
|
|
549
549
|
|
|
550
|
+
## Shared client
|
|
551
|
+
|
|
552
|
+
`@sentry/api/client` is the request layer the Sentry CLI and MCP servers share, built on the generated operations. It uses only web-standard APIs (`fetch`, `Request`, `Headers`, `URL`, `AbortSignal`, `crypto.subtle`), so it runs in Node, Cloudflare Workers, and browsers. Hosts inject what differs between them:
|
|
553
|
+
|
|
554
|
+
- **Transport.** `createApiTransport` sets `Authorization` from a `CredentialProvider`, refreshes the credential once after a 401, times out each attempt, retries through the shared retry policy (429 for any method; 500, 502, 503, 504, timeouts, and network errors only for GET, HEAD, OPTIONS, or writes marked idempotent), follows redirects only to trusted origins, and serves and invalidates cached GETs. The host passes credentials, a `TransportCache`, the request-scoped `fresh` hook, a logger, a span hook, and its error classes.
|
|
555
|
+
- **Request core.** `createApiClientCore` sends `<origin>/api/0<path>` through the transport and throws the status's `ApiError` subclass for an error response. `sdkClient` gives a generated operation a client that sends through the same path.
|
|
556
|
+
- **Response cache.** The cache policy (`lookupResponse`, `storeResponse`, tiers, identity-scoped keys, invalidation) works on any `CacheStore` and `BodyCodec`. `createMemoryStore` is a byte-budgeted in-memory store. Compressing codecs need host APIs such as `node:zlib`, so hosts supply them.
|
|
557
|
+
- **Validation.** Endpoint wrappers validate responses with any [Standard Schema](https://standardschema.dev) validator the host passes in, such as the `@sentry/api/zod` or `@sentry/api/valibot` schemas. The client depends on neither.
|
|
558
|
+
- **Pagination.** `paginate` and `fetchAllPages` walk list endpoints on top of `paginateUpTo` and `consumePage`. Their cursors are Sentry cursors that also record rows already returned from a page, so a resumed walk neither repeats nor skips rows.
|
|
559
|
+
|
|
560
|
+
`@sentry/api/client/endpoints` holds endpoint wrappers by domain. Each takes an `ApiTarget` (a core and an origin) and a response schema.
|
|
561
|
+
|
|
562
|
+
Every API error the core throws (`ApiError`, `ApiNotFoundError`, `ApiRateLimitError`, and the rest) extends `SentryApiError`, so `instanceof SentryApiError` matches failures from both the generated operations and the core.
|
|
563
|
+
|
|
564
|
+
In a browser, put the session fetch under the transport to keep cookie auth and CSRF injection:
|
|
565
|
+
|
|
566
|
+
```ts
|
|
567
|
+
import { createBrowserFetch } from "@sentry/api/browser";
|
|
568
|
+
import { createApiClientCore, createApiTransport } from "@sentry/api/client";
|
|
569
|
+
|
|
570
|
+
const transport = createApiTransport({
|
|
571
|
+
fetch: createBrowserFetch(),
|
|
572
|
+
retry: { maxRetries: 2, baseDelayMs: 500, maxDelayMs: 5000, maxTotalDelayMs: 10000 },
|
|
573
|
+
});
|
|
574
|
+
const core = createApiClientCore({ transport, headers: () => ({}), logger: console });
|
|
575
|
+
const projects = await core.requestJson("https://sentry.example.com", "/organizations/acme/projects/");
|
|
576
|
+
```
|
|
577
|
+
|
|
550
578
|
## Schema source
|
|
551
579
|
|
|
552
580
|
The OpenAPI schema is synced from [`getsentry/sentry`](https://github.com/getsentry/sentry/tree/master/api-docs). Schema fixes belong there; build/tooling changes belong here.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode one Sentry API path identifier without letting it become a URL path.
|
|
3
|
+
*
|
|
4
|
+
* URL parsing collapses bare `.` and `..` segments even after
|
|
5
|
+
* `encodeURIComponent`, so callers must reject those identifiers before
|
|
6
|
+
* constructing a request. The caller owns its product-specific error type.
|
|
7
|
+
* A pre-encoded spelling such as `%2e%2e` is safe: encoding its percent signs
|
|
8
|
+
* prevents the URL parser from treating it as a dot segment.
|
|
9
|
+
*/
|
|
10
|
+
export declare function encodeApiPathSegment(value: string | number): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Assemble an API URL from a product-validated base and a relative endpoint.
|
|
13
|
+
* This does not decide which host is trusted or which region an org uses.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildSentryApiUrl(baseUrl: string, endpoint: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Builds an API request path, confining each interpolated value to one path segment.
|
|
18
|
+
*
|
|
19
|
+
* `fetch` resolves dot segments during URL parsing, so a raw value in a path can
|
|
20
|
+
* rewrite it above the org and project the server injected. Encoding stops separators
|
|
21
|
+
* but not `.` or `..`, which survive encoding and still collapse (the URL spec treats
|
|
22
|
+
* `%2e%2e` as a dot segment too), so those are rejected instead.
|
|
23
|
+
*
|
|
24
|
+
* Query strings go outside the template, since `URLSearchParams` has already encoded
|
|
25
|
+
* them and their separators must stay literal:
|
|
26
|
+
*
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const path = apiPath`/organizations/${organizationSlug}/issues/`;
|
|
29
|
+
* await this.requestJSON(`${path}?${query}`);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function apiPath(strings: TemplateStringsArray, ...values: (string | number)[]): string;
|
|
33
|
+
/** `path` with `query` appended, or `path` alone when `query` is empty. */
|
|
34
|
+
export declare function withQuery(path: string, query: URLSearchParams): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Strip padding at the edges without changing bytes within the token. */
|
|
2
|
+
export declare function trimAuthToken(token: string): string;
|
|
3
|
+
/** Return null for invalid input so each caller can preserve its own error type. */
|
|
4
|
+
export declare function normalizeAuthToken(token: string): string | null;
|
|
5
|
+
/** Format a validated upstream credential; callers own their auth errors. */
|
|
6
|
+
export declare function sentryBearerHeader(token: string): string | null;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The request core that endpoint wrappers build on. It sends a request
|
|
3
|
+
* through the host's transport, turns network failures and error responses
|
|
4
|
+
* into the shared errors, and reads JSON bodies. `@sentry/api` operations
|
|
5
|
+
* get a client that sends through the same path, and {@link listPage} walks
|
|
6
|
+
* their pages.
|
|
7
|
+
*
|
|
8
|
+
* The host supplies the transport (retries, caching), the per-request
|
|
9
|
+
* headers (credentials, user agent, attribution), and logging.
|
|
10
|
+
*/
|
|
11
|
+
import { type SentryClient } from "@sentry/api";
|
|
12
|
+
import { type ResponseSchema } from "./validate.js";
|
|
13
|
+
/** What the core needs from the host's transport. */
|
|
14
|
+
export type ApiRequestTransport = {
|
|
15
|
+
request(url: string, init: RequestInit): Promise<Response>;
|
|
16
|
+
};
|
|
17
|
+
export type ApiClientLogger = {
|
|
18
|
+
warn(message: string, extra: Record<string, unknown>): void;
|
|
19
|
+
};
|
|
20
|
+
export type ApiClientCoreOptions = {
|
|
21
|
+
transport: ApiRequestTransport;
|
|
22
|
+
/**
|
|
23
|
+
* Headers for every request after `Content-Type`, such as Authorization
|
|
24
|
+
* and User-Agent. Called once per request; may throw for a bad credential.
|
|
25
|
+
* They replace any headers the caller passes.
|
|
26
|
+
*/
|
|
27
|
+
headers: () => Record<string, string>;
|
|
28
|
+
logger: ApiClientLogger;
|
|
29
|
+
};
|
|
30
|
+
export type ApiRequestOptions = {
|
|
31
|
+
/** Error statuses returned as the response instead of thrown. */
|
|
32
|
+
allowStatuses?: number[];
|
|
33
|
+
};
|
|
34
|
+
export type ApiClientCore = {
|
|
35
|
+
/**
|
|
36
|
+
* Send a request to `origin` + `/api/0` + `path`.
|
|
37
|
+
*
|
|
38
|
+
* @throws {ApiError} For an error status not in `allowStatuses`
|
|
39
|
+
* @throws {ConfigurationError} When the host is unreachable or misconfigured
|
|
40
|
+
* @throws {Error} For other network failures, with a readable message
|
|
41
|
+
*/
|
|
42
|
+
request(origin: string, path: string, init?: RequestInit, options?: ApiRequestOptions): Promise<Response>;
|
|
43
|
+
/** {@link ApiClientCore.request}, then the parsed JSON body. */
|
|
44
|
+
requestJson(origin: string, path: string, init?: RequestInit): Promise<unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* A `@sentry/api` client for one GET to `expectedPath` on `origin`. The
|
|
47
|
+
* operation builds the path and query; the request goes through
|
|
48
|
+
* {@link ApiClientCore.request}. Any other target or method throws.
|
|
49
|
+
*/
|
|
50
|
+
sdkClient(origin: string, expectedPath: string): SentryClient["client"];
|
|
51
|
+
};
|
|
52
|
+
/** Where an endpoint wrapper sends: the core, and the region or host origin. */
|
|
53
|
+
export type ApiTarget = {
|
|
54
|
+
core: ApiClientCore;
|
|
55
|
+
origin: string;
|
|
56
|
+
};
|
|
57
|
+
/** Most pages {@link listPage} fetches for one call. */
|
|
58
|
+
export declare const MAX_LIST_PAGES = 50;
|
|
59
|
+
/** Rows from {@link listPage}, and the cursor for the next call. */
|
|
60
|
+
export type ListPage<T> = {
|
|
61
|
+
items: T[];
|
|
62
|
+
nextCursor: string | null;
|
|
63
|
+
};
|
|
64
|
+
/** The cursor of the next page in a list response's `Link` header, if any. */
|
|
65
|
+
export declare function nextPageCursor(response: Response): string | null;
|
|
66
|
+
export declare function createApiClientCore({ transport, headers, logger, }: ApiClientCoreOptions): ApiClientCore;
|
|
67
|
+
/**
|
|
68
|
+
* Fetch up to `limit` rows from a list endpoint, starting at `cursor`.
|
|
69
|
+
*
|
|
70
|
+
* Each page asks for exactly the rows still missing, up to
|
|
71
|
+
* {@link API_MAX_PER_PAGE}, and is validated with `schema`. The walk stops
|
|
72
|
+
* once it has `limit` rows or the server has no next page, and returns the
|
|
73
|
+
* server's cursor for the page after the last one fetched.
|
|
74
|
+
*
|
|
75
|
+
* @throws {ApiValidationError} When `limit` is not between 1 and
|
|
76
|
+
* `API_MAX_PER_PAGE * MAX_LIST_PAGES`
|
|
77
|
+
* @throws {ApiResponseValidationError} When a page does not match `schema`
|
|
78
|
+
* @throws {Error} When a page has more rows than requested, a cursor
|
|
79
|
+
* repeats, or the walk passes {@link MAX_LIST_PAGES}
|
|
80
|
+
*/
|
|
81
|
+
export declare function listPage<T>(fetchPage: (perPage: number, cursor: string | undefined) => Promise<{
|
|
82
|
+
data: unknown;
|
|
83
|
+
response: Response;
|
|
84
|
+
}>, schema: ResponseSchema<T[]>, limit: number, initialCursor?: string | null): Promise<ListPage<T>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client key (DSN) endpoints for a project. Each wrapper validates the
|
|
3
|
+
* response with the schema the host passes, so the host's schema decides the
|
|
4
|
+
* result type.
|
|
5
|
+
*/
|
|
6
|
+
import { type ApiTarget, type ResponseSchema } from "@sentry/api/client";
|
|
7
|
+
export type ClientKeyProjectParams = {
|
|
8
|
+
organizationSlug: string;
|
|
9
|
+
projectSlug: string;
|
|
10
|
+
};
|
|
11
|
+
/** Every client key of a project. */
|
|
12
|
+
export declare function listClientKeys<T>({ core, origin }: ApiTarget, { organizationSlug, projectSlug }: ClientKeyProjectParams, schema: ResponseSchema<T>): Promise<T>;
|
|
13
|
+
/** Create a client key, optionally named. */
|
|
14
|
+
export declare function createClientKey<T>({ core, origin }: ApiTarget, { organizationSlug, projectSlug, name, }: ClientKeyProjectParams & {
|
|
15
|
+
name?: string;
|
|
16
|
+
}, schema: ResponseSchema<T>): Promise<T>;
|
|
17
|
+
export type ClientKeyUpdate = {
|
|
18
|
+
name?: string;
|
|
19
|
+
isActive?: boolean;
|
|
20
|
+
/** Caps accepted errors per window; `null` removes the limit. */
|
|
21
|
+
rateLimit?: {
|
|
22
|
+
window: number;
|
|
23
|
+
count: number;
|
|
24
|
+
} | null;
|
|
25
|
+
browserSdkVersion?: string;
|
|
26
|
+
dynamicSdkLoaderOptions?: {
|
|
27
|
+
hasReplay?: boolean;
|
|
28
|
+
hasPerformance?: boolean;
|
|
29
|
+
hasDebug?: boolean;
|
|
30
|
+
hasFeedback?: boolean;
|
|
31
|
+
hasLogsAndMetrics?: boolean;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export type UpdateClientKeyParams = ClientKeyProjectParams & {
|
|
35
|
+
keyId: string | number;
|
|
36
|
+
} & ClientKeyUpdate;
|
|
37
|
+
/** Update a client key. Only the fields that are set are sent. */
|
|
38
|
+
export declare function updateClientKey<T>({ core, origin }: ApiTarget, { organizationSlug, projectSlug, keyId, name, isActive, rateLimit, browserSdkVersion, dynamicSdkLoaderOptions, }: UpdateClientKeyParams, schema: ResponseSchema<T>): Promise<T>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard endpoints. Each wrapper validates the response with the schema
|
|
3
|
+
* the host passes, so the host's schema decides the result type.
|
|
4
|
+
*/
|
|
5
|
+
import { type ApiTarget, type ListPage, type ResponseSchema } from "@sentry/api/client";
|
|
6
|
+
export type ListDashboardsParams = {
|
|
7
|
+
organizationSlug: string;
|
|
8
|
+
/** Filters by title. */
|
|
9
|
+
query?: string | null;
|
|
10
|
+
sortBy?: "title" | "-title" | "dateCreated" | "-dateCreated";
|
|
11
|
+
/** Page size. Default: 10. */
|
|
12
|
+
limit?: number;
|
|
13
|
+
/** Resumes from a previous call's `nextCursor`. */
|
|
14
|
+
cursor?: string | null;
|
|
15
|
+
};
|
|
16
|
+
/** One page of the organization's dashboards. */
|
|
17
|
+
export declare function listDashboards<T>({ core, origin }: ApiTarget, { organizationSlug, query, sortBy, limit, cursor }: ListDashboardsParams, schema: ResponseSchema<T[]>): Promise<ListPage<T>>;
|
|
18
|
+
export type GetDashboardParams = {
|
|
19
|
+
organizationSlug: string;
|
|
20
|
+
dashboardId: string;
|
|
21
|
+
};
|
|
22
|
+
/** One dashboard with its widgets. */
|
|
23
|
+
export declare function getDashboard<T>({ core, origin }: ApiTarget, { organizationSlug, dashboardId }: GetDashboardParams, schema: ResponseSchema<T>): Promise<T>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sentry/api/client/endpoints`: endpoint wrappers by domain, on the
|
|
3
|
+
* generated operations where they exist and the request core otherwise. Each
|
|
4
|
+
* takes an `ApiTarget` and a host-supplied response schema.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./client-keys.js";
|
|
7
|
+
export * from "./dashboards.js";
|
|
8
|
+
export * from "./monitors.js";
|
|
9
|
+
export * from "./organizations.js";
|
|
10
|
+
export * from "./profiling.js";
|
|
11
|
+
export * from "./projects.js";
|
|
12
|
+
export * from "./releases.js";
|
|
13
|
+
export * from "./replays.js";
|
|
14
|
+
export * from "./repositories.js";
|
|
15
|
+
export * from "./snapshots.js";
|
|
16
|
+
export * from "./teams.js";
|
|
17
|
+
export * from "./traces.js";
|
|
18
|
+
export * from "./uptime-monitors.js";
|