@allisall/sdk 0.0.0-stage → 0.2.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 +202 -0
- package/NOTICE +2 -0
- package/README.md +227 -2
- package/dist/client.d.ts +121 -0
- package/dist/client.js +193 -0
- package/dist/decimal.d.ts +20 -0
- package/dist/decimal.js +23 -0
- package/dist/errors.d.ts +79 -0
- package/dist/errors.js +98 -0
- package/dist/generated/openapi.d.ts +7724 -0
- package/dist/generated/openapi.js +4 -0
- package/dist/generated/operations.d.ts +37 -0
- package/dist/generated/operations.js +976 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +5 -0
- package/dist/ingest.d.ts +28 -0
- package/dist/ingest.js +247 -0
- package/dist/money.d.ts +57 -0
- package/dist/money.js +284 -0
- package/dist/multipart.d.ts +27 -0
- package/dist/multipart.js +48 -0
- package/dist/options.d.ts +50 -0
- package/dist/options.js +73 -0
- package/dist/pagination.d.ts +55 -0
- package/dist/pagination.js +85 -0
- package/dist/request.d.ts +117 -0
- package/dist/request.js +363 -0
- package/dist/resources/agents.d.ts +51 -0
- package/dist/resources/agents.js +65 -0
- package/dist/resources/analytics.d.ts +42 -0
- package/dist/resources/analytics.js +68 -0
- package/dist/resources/api-keys.d.ts +54 -0
- package/dist/resources/api-keys.js +63 -0
- package/dist/resources/calculations.d.ts +78 -0
- package/dist/resources/calculations.js +111 -0
- package/dist/resources/clients.d.ts +65 -0
- package/dist/resources/clients.js +85 -0
- package/dist/resources/cost.d.ts +69 -0
- package/dist/resources/cost.js +89 -0
- package/dist/resources/dashboard.d.ts +24 -0
- package/dist/resources/dashboard.js +28 -0
- package/dist/resources/events.d.ts +47 -0
- package/dist/resources/events.js +69 -0
- package/dist/resources/health.d.ts +14 -0
- package/dist/resources/health.js +17 -0
- package/dist/resources/imports.d.ts +33 -0
- package/dist/resources/imports.js +37 -0
- package/dist/resources/outcome-types.d.ts +25 -0
- package/dist/resources/outcome-types.js +33 -0
- package/dist/resources/reports.d.ts +77 -0
- package/dist/resources/reports.js +103 -0
- package/dist/resources/value-models.d.ts +92 -0
- package/dist/resources/value-models.js +126 -0
- package/dist/retry.d.ts +18 -0
- package/dist/retry.js +105 -0
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.js +61 -0
- package/dist/share.d.ts +52 -0
- package/dist/share.js +60 -0
- package/dist/transport.d.ts +102 -0
- package/dist/transport.js +269 -0
- package/dist/types.d.ts +268 -0
- package/dist/types.js +89 -0
- package/dist/unicode.d.ts +2 -0
- package/dist/unicode.js +11 -0
- package/dist/uuid.d.ts +6 -0
- package/dist/uuid.js +20 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/package.json +40 -4
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// A CSV import's body: a form of two parts, the mapping and then the file.
|
|
2
|
+
import { encodeJson } from "./money.js";
|
|
3
|
+
import { hasLoneSurrogate } from "./unicode.js";
|
|
4
|
+
const DEFAULT_FILENAME = "upload.csv";
|
|
5
|
+
function nameOf(file) {
|
|
6
|
+
const name = Reflect.get(file, "name");
|
|
7
|
+
return typeof name === "string" && name !== "" ? name : undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Builds the form once, `mapping` before `file`, as the API reads them. The
|
|
11
|
+
* same form is the body of every attempt.
|
|
12
|
+
*
|
|
13
|
+
* @throws {TypeError} when the upload is not an object, the mapping has no
|
|
14
|
+
* JSON text, or the file is not a `Blob`, a `Uint8Array` or a string, or
|
|
15
|
+
* is a string holding a lone surrogate.
|
|
16
|
+
*/
|
|
17
|
+
export function formOf(upload) {
|
|
18
|
+
if (typeof upload !== "object" || upload === null) {
|
|
19
|
+
throw new TypeError("allisall: an import takes an object with mapping and file");
|
|
20
|
+
}
|
|
21
|
+
const { mapping, file, filename } = upload;
|
|
22
|
+
const mappingPart = new Blob([encodeJson(mapping, [])], {
|
|
23
|
+
type: "application/json",
|
|
24
|
+
});
|
|
25
|
+
let filePart;
|
|
26
|
+
let defaultName = DEFAULT_FILENAME;
|
|
27
|
+
if (file instanceof Blob) {
|
|
28
|
+
// A File keeps its own name; its type is set to the one the API reads.
|
|
29
|
+
defaultName = nameOf(file) ?? DEFAULT_FILENAME;
|
|
30
|
+
filePart = new Blob([file], { type: "text/csv" });
|
|
31
|
+
}
|
|
32
|
+
else if (file instanceof Uint8Array || typeof file === "string") {
|
|
33
|
+
// A Blob writes a lone surrogate as U+FFFD, changing the file in silence.
|
|
34
|
+
if (typeof file === "string" && hasLoneSurrogate(file)) {
|
|
35
|
+
throw new TypeError("allisall: the import's file is not valid Unicode (a lone surrogate)");
|
|
36
|
+
}
|
|
37
|
+
filePart = new Blob([file], { type: "text/csv" });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new TypeError("allisall: an import's file must be a Blob, a Uint8Array or a string; a stream cannot be sent again on a retry");
|
|
41
|
+
}
|
|
42
|
+
const form = new FormData();
|
|
43
|
+
form.append("mapping", mappingPart, "mapping.json");
|
|
44
|
+
// An empty name falls back, as a File with no name does.
|
|
45
|
+
const name = typeof filename === "string" && filename !== "" ? filename : defaultName;
|
|
46
|
+
form.append("file", filePart, name);
|
|
47
|
+
return form;
|
|
48
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** The options of one call. Each member left out takes the client's. */
|
|
2
|
+
export interface RequestOptions {
|
|
3
|
+
/** Cancels the call, including any wait between retries. */
|
|
4
|
+
signal?: AbortSignal | undefined;
|
|
5
|
+
/** The timeout of each attempt of this call, in milliseconds. */
|
|
6
|
+
timeout?: number | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* How many times this call is retried. It cannot make a request eligible
|
|
9
|
+
* that the SDK never retries, such as a `PATCH`.
|
|
10
|
+
*/
|
|
11
|
+
maxRetries?: number | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Extra headers for this call, sent over the client's `defaultHeaders`.
|
|
14
|
+
* They may not name `Authorization`, `Content-Type`, `Idempotency-Key` or
|
|
15
|
+
* `X-Request-Id`, which the SDK sets. In a browser, a header must be one
|
|
16
|
+
* the API's CORS policy allows.
|
|
17
|
+
*/
|
|
18
|
+
headers?: Readonly<Record<string, string>> | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** The options of a call that creates something and takes an `Idempotency-Key`. */
|
|
21
|
+
export interface IdempotentRequestOptions extends RequestOptions {
|
|
22
|
+
/**
|
|
23
|
+
* The `Idempotency-Key` to send, as given. By default the SDK generates
|
|
24
|
+
* one per call and sends it on every attempt of that call. Set your own
|
|
25
|
+
* to make a create safe to repeat across process restarts.
|
|
26
|
+
*
|
|
27
|
+
* A second call with the same key and the same request, within 24 hours,
|
|
28
|
+
* gets the first call's stored response. Only a `2xx` is stored, so a key
|
|
29
|
+
* whose first call failed can be sent again. The same key with a
|
|
30
|
+
* different body is refused with `422` `idempotency_key_reused`.
|
|
31
|
+
*
|
|
32
|
+
* The key must be a string the platform can send as a header value: a
|
|
33
|
+
* newline, or a character above U+00FF, is a `TypeError` before sending.
|
|
34
|
+
*/
|
|
35
|
+
idempotencyKey?: string | undefined;
|
|
36
|
+
}
|
|
37
|
+
export declare const DEFAULT_TIMEOUT_MS = 60000;
|
|
38
|
+
export declare const DEFAULT_MAX_RETRIES = 2;
|
|
39
|
+
export declare function resolveTimeout(option: number | undefined, fallback: number): number;
|
|
40
|
+
export declare function resolveMaxRetries(option: number | undefined, fallback: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* Checks caller headers and returns a copy. `option` names the option the
|
|
43
|
+
* headers came from, for the message.
|
|
44
|
+
*
|
|
45
|
+
* @throws {TypeError} when the headers are not a plain object, or a header
|
|
46
|
+
* is one the SDK sets or is not a valid header name and string value.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveHeaders(headers: Readonly<Record<string, string>> | undefined, option: string): Readonly<Record<string, string>>;
|
|
49
|
+
/** Sets each of `extra` in `target`, replacing a header of the same name in any case. */
|
|
50
|
+
export declare function mergeHeaders(target: Record<string, string>, extra: Readonly<Record<string, string>>): void;
|
package/dist/options.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// The options of one call, and how they are checked and combined with the
|
|
2
|
+
// client's.
|
|
3
|
+
import { AllisallError } from "./errors.js";
|
|
4
|
+
export const DEFAULT_TIMEOUT_MS = 60_000;
|
|
5
|
+
export const DEFAULT_MAX_RETRIES = 2;
|
|
6
|
+
/** The headers the SDK sets itself, in lower case. */
|
|
7
|
+
const OWNED_HEADERS = new Set([
|
|
8
|
+
"authorization",
|
|
9
|
+
"content-type",
|
|
10
|
+
"idempotency-key",
|
|
11
|
+
"x-request-id",
|
|
12
|
+
]);
|
|
13
|
+
export function resolveTimeout(option, fallback) {
|
|
14
|
+
const timeout = option ?? fallback;
|
|
15
|
+
if (typeof timeout !== "number" ||
|
|
16
|
+
!Number.isFinite(timeout) ||
|
|
17
|
+
timeout <= 0) {
|
|
18
|
+
throw new AllisallError(`allisall: timeout must be a positive number of milliseconds, not ${String(timeout)}`);
|
|
19
|
+
}
|
|
20
|
+
return timeout;
|
|
21
|
+
}
|
|
22
|
+
export function resolveMaxRetries(option, fallback) {
|
|
23
|
+
const maxRetries = option ?? fallback;
|
|
24
|
+
if (!Number.isInteger(maxRetries) || maxRetries < 0) {
|
|
25
|
+
throw new AllisallError(`allisall: maxRetries must be a whole number, 0 or more, not ${String(maxRetries)}`);
|
|
26
|
+
}
|
|
27
|
+
return maxRetries;
|
|
28
|
+
}
|
|
29
|
+
function isPlainObject(value) {
|
|
30
|
+
if (typeof value !== "object" || value === null)
|
|
31
|
+
return false;
|
|
32
|
+
const proto = Object.getPrototypeOf(value);
|
|
33
|
+
return proto === Object.prototype || proto === null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Checks caller headers and returns a copy. `option` names the option the
|
|
37
|
+
* headers came from, for the message.
|
|
38
|
+
*
|
|
39
|
+
* @throws {TypeError} when the headers are not a plain object, or a header
|
|
40
|
+
* is one the SDK sets or is not a valid header name and string value.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveHeaders(headers, option) {
|
|
43
|
+
if (headers === undefined)
|
|
44
|
+
return {};
|
|
45
|
+
if (!isPlainObject(headers)) {
|
|
46
|
+
throw new TypeError(`allisall: ${option} must be a plain object of header names and string values`);
|
|
47
|
+
}
|
|
48
|
+
const copy = {};
|
|
49
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
50
|
+
if (OWNED_HEADERS.has(name.toLowerCase())) {
|
|
51
|
+
throw new TypeError(`allisall: ${option} may not set ${name}; the SDK sets it`);
|
|
52
|
+
}
|
|
53
|
+
if (typeof value !== "string") {
|
|
54
|
+
throw new TypeError(`allisall: ${option} sets ${name} to ${typeof value}; a header value must be a string`);
|
|
55
|
+
}
|
|
56
|
+
copy[name] = value;
|
|
57
|
+
}
|
|
58
|
+
// The platform's own check of names and values, so a malformed header is
|
|
59
|
+
// refused here rather than failing every attempt as a connection error.
|
|
60
|
+
new Headers(copy);
|
|
61
|
+
return copy;
|
|
62
|
+
}
|
|
63
|
+
/** Sets each of `extra` in `target`, replacing a header of the same name in any case. */
|
|
64
|
+
export function mergeHeaders(target, extra) {
|
|
65
|
+
for (const [name, value] of Object.entries(extra)) {
|
|
66
|
+
const lower = name.toLowerCase();
|
|
67
|
+
for (const existing of Object.keys(target)) {
|
|
68
|
+
if (existing.toLowerCase() === lower)
|
|
69
|
+
delete target[existing];
|
|
70
|
+
}
|
|
71
|
+
target[name] = value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RequestOptions } from "./options.js";
|
|
2
|
+
/** The envelope every list response shares. */
|
|
3
|
+
export interface ListBody {
|
|
4
|
+
readonly data: readonly unknown[];
|
|
5
|
+
readonly has_more: boolean;
|
|
6
|
+
readonly next_cursor: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** Fetches the page after this one; the options apply to that request alone. */
|
|
9
|
+
type NextPage<Item, Body extends ListBody> = (options: RequestOptions | undefined) => Promise<Page<Item, Body>>;
|
|
10
|
+
/**
|
|
11
|
+
* One page of a list. `data` holds its items and `body` the whole response,
|
|
12
|
+
* such as the event drill-down's `total`. Iterate it with `for await` to
|
|
13
|
+
* walk its items and then every following page's.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Page<Item, Body extends ListBody> implements AsyncIterable<Item> {
|
|
16
|
+
#private;
|
|
17
|
+
/** The page's items. */
|
|
18
|
+
readonly data: Item[];
|
|
19
|
+
/** The whole decoded response. */
|
|
20
|
+
readonly body: Body;
|
|
21
|
+
/** Pages are made by list methods; you do not construct one. */
|
|
22
|
+
constructor(body: Body, next: NextPage<Item, Body> | undefined);
|
|
23
|
+
/** Whether another page follows this one: the response's `has_more`. */
|
|
24
|
+
hasNextPage(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Fetches the next page, with the same query and options as this one.
|
|
27
|
+
* `options` apply to this request alone, over the call's.
|
|
28
|
+
*
|
|
29
|
+
* @throws {AllisallError} when this is the last page.
|
|
30
|
+
*/
|
|
31
|
+
getNextPage(options?: RequestOptions): Promise<Page<Item, Body>>;
|
|
32
|
+
/** Yields this page's items, then each following page's, fetching each page as it is reached. */
|
|
33
|
+
[Symbol.asyncIterator](): AsyncIterator<Item>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The result of a list method. Await it for the first `Page`; iterate it
|
|
37
|
+
* with `for await` for every item of every page.
|
|
38
|
+
*
|
|
39
|
+
* Nothing is sent until it is awaited or iterated, so a list call whose
|
|
40
|
+
* result is never used sends no request.
|
|
41
|
+
*/
|
|
42
|
+
export declare class PagePromise<Item, Body extends ListBody> implements PromiseLike<Page<Item, Body>>, AsyncIterable<Item> {
|
|
43
|
+
#private;
|
|
44
|
+
/** Made by list methods; you do not construct one. */
|
|
45
|
+
constructor(load: () => Promise<Page<Item, Body>>);
|
|
46
|
+
/** Resolves with the first page, sending its request on first use. */
|
|
47
|
+
then<R1 = Page<Item, Body>, R2 = never>(onfulfilled?: ((page: Page<Item, Body>) => R1 | PromiseLike<R1>) | null | undefined, onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null | undefined): Promise<R1 | R2>;
|
|
48
|
+
/** As `Promise.prototype.catch`, on the first page. */
|
|
49
|
+
catch<R = never>(onrejected?: ((reason: unknown) => R | PromiseLike<R>) | null | undefined): Promise<Page<Item, Body> | R>;
|
|
50
|
+
/** As `Promise.prototype.finally`, on the first page. */
|
|
51
|
+
finally(onfinally?: (() => void) | null | undefined): Promise<Page<Item, Body>>;
|
|
52
|
+
/** Yields every item of every page, from the first. */
|
|
53
|
+
[Symbol.asyncIterator](): AsyncIterator<Item>;
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// A list call's result: a page, and the walk over every following page.
|
|
2
|
+
import { AllisallError } from "./errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* One page of a list. `data` holds its items and `body` the whole response,
|
|
5
|
+
* such as the event drill-down's `total`. Iterate it with `for await` to
|
|
6
|
+
* walk its items and then every following page's.
|
|
7
|
+
*/
|
|
8
|
+
export class Page {
|
|
9
|
+
/** The page's items. */
|
|
10
|
+
data;
|
|
11
|
+
/** The whole decoded response. */
|
|
12
|
+
body;
|
|
13
|
+
#next;
|
|
14
|
+
/** Pages are made by list methods; you do not construct one. */
|
|
15
|
+
constructor(body, next) {
|
|
16
|
+
this.body = body;
|
|
17
|
+
// The envelope was checked as an array of the list's items when the
|
|
18
|
+
// response was read.
|
|
19
|
+
this.data = body.data;
|
|
20
|
+
this.#next = next;
|
|
21
|
+
}
|
|
22
|
+
/** Whether another page follows this one: the response's `has_more`. */
|
|
23
|
+
hasNextPage() {
|
|
24
|
+
return this.#next !== undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetches the next page, with the same query and options as this one.
|
|
28
|
+
* `options` apply to this request alone, over the call's.
|
|
29
|
+
*
|
|
30
|
+
* @throws {AllisallError} when this is the last page.
|
|
31
|
+
*/
|
|
32
|
+
getNextPage(options) {
|
|
33
|
+
if (this.#next === undefined) {
|
|
34
|
+
return Promise.reject(new AllisallError("allisall: this is the last page; no page follows it"));
|
|
35
|
+
}
|
|
36
|
+
return this.#next(options);
|
|
37
|
+
}
|
|
38
|
+
/** Yields this page's items, then each following page's, fetching each page as it is reached. */
|
|
39
|
+
async *[Symbol.asyncIterator]() {
|
|
40
|
+
let page = this;
|
|
41
|
+
for (;;) {
|
|
42
|
+
yield* page.data;
|
|
43
|
+
if (!page.hasNextPage())
|
|
44
|
+
return;
|
|
45
|
+
page = await page.getNextPage();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The result of a list method. Await it for the first `Page`; iterate it
|
|
51
|
+
* with `for await` for every item of every page.
|
|
52
|
+
*
|
|
53
|
+
* Nothing is sent until it is awaited or iterated, so a list call whose
|
|
54
|
+
* result is never used sends no request.
|
|
55
|
+
*/
|
|
56
|
+
export class PagePromise {
|
|
57
|
+
#load;
|
|
58
|
+
#first;
|
|
59
|
+
/** Made by list methods; you do not construct one. */
|
|
60
|
+
constructor(load) {
|
|
61
|
+
this.#load = load;
|
|
62
|
+
}
|
|
63
|
+
/** The first page, requested once, on first use. */
|
|
64
|
+
#page() {
|
|
65
|
+
this.#first ??= this.#load();
|
|
66
|
+
return this.#first;
|
|
67
|
+
}
|
|
68
|
+
/** Resolves with the first page, sending its request on first use. */
|
|
69
|
+
// biome-ignore lint/suspicious/noThenProperty: a PagePromise is awaitable by design, so it must have then.
|
|
70
|
+
then(onfulfilled, onrejected) {
|
|
71
|
+
return this.#page().then(onfulfilled, onrejected);
|
|
72
|
+
}
|
|
73
|
+
/** As `Promise.prototype.catch`, on the first page. */
|
|
74
|
+
catch(onrejected) {
|
|
75
|
+
return this.#page().catch(onrejected);
|
|
76
|
+
}
|
|
77
|
+
/** As `Promise.prototype.finally`, on the first page. */
|
|
78
|
+
finally(onfinally) {
|
|
79
|
+
return this.#page().finally(onfinally);
|
|
80
|
+
}
|
|
81
|
+
/** Yields every item of every page, from the first. */
|
|
82
|
+
async *[Symbol.asyncIterator]() {
|
|
83
|
+
yield* await this.#page();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { operations } from "./generated/openapi.js";
|
|
2
|
+
import { type Operation, type OperationId } from "./generated/operations.js";
|
|
3
|
+
import { type MoneyInput } from "./money.js";
|
|
4
|
+
import { type ImportUpload } from "./multipart.js";
|
|
5
|
+
import { type IdempotentRequestOptions, type RequestOptions } from "./options.js";
|
|
6
|
+
import { type ListBody, PagePromise } from "./pagination.js";
|
|
7
|
+
import { type CallPolicy, type TransportConfig } from "./transport.js";
|
|
8
|
+
import type { QueryOf } from "./types.js";
|
|
9
|
+
type Responses<K extends OperationId> = operations[K]["responses"];
|
|
10
|
+
type SuccessStatus = 200 | 201 | 202 | 204;
|
|
11
|
+
/**
|
|
12
|
+
* The decoded body of an operation's success response, from the generated
|
|
13
|
+
* types: `undefined` for a response without a body.
|
|
14
|
+
*/
|
|
15
|
+
export type SuccessBody<K extends OperationId> = Responses<K>[Extract<keyof Responses<K>, SuccessStatus>] extends {
|
|
16
|
+
content: {
|
|
17
|
+
"application/json": infer B;
|
|
18
|
+
};
|
|
19
|
+
} ? B : undefined;
|
|
20
|
+
/** What one call sends, beyond what the operation table fixes. */
|
|
21
|
+
export interface CallArgs {
|
|
22
|
+
/** The path parameters, by the name the path template gives each. */
|
|
23
|
+
readonly path?: Readonly<Record<string, string>> | undefined;
|
|
24
|
+
/** The query, written member by member in the object's own order. */
|
|
25
|
+
readonly query?: object | undefined;
|
|
26
|
+
/** The body: JSON for a JSON or merge-patch operation, an upload for a multipart one. */
|
|
27
|
+
readonly body?: unknown;
|
|
28
|
+
readonly options?: IdempotentRequestOptions | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* The share token of a shared report, already checked. Only the shared
|
|
31
|
+
* report's operation takes one, and it takes nothing else.
|
|
32
|
+
*/
|
|
33
|
+
readonly shareToken?: string | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Whether a retry cannot apply the request twice: a method RFC 9110 defines
|
|
37
|
+
* as idempotent, an operation sent with an `Idempotency-Key`, or ingest,
|
|
38
|
+
* whose `event_id`s deduplicate. The version-guarded `PUT` is the exception.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isEligible(id: OperationId, operation: Operation): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* What one call may do: its operation's retry eligibility, and the call's
|
|
43
|
+
* options resolved over the client's.
|
|
44
|
+
*
|
|
45
|
+
* @throws {AllisallError} for a `timeout` or `maxRetries` the client would refuse.
|
|
46
|
+
* @throws {TypeError} for headers that are not a plain object of headers, or
|
|
47
|
+
* that name a header the SDK sets.
|
|
48
|
+
*/
|
|
49
|
+
export declare function policyOf(config: TransportConfig, id: OperationId, operation: Operation, options: RequestOptions): CallPolicy;
|
|
50
|
+
/**
|
|
51
|
+
* Calls one operation and resolves with its decoded success body.
|
|
52
|
+
*
|
|
53
|
+
* Everything the call sends is fixed before the first attempt: its URL, its
|
|
54
|
+
* body's bytes and its `Idempotency-Key`. Retries follow the operation's
|
|
55
|
+
* eligibility. A `204` resolves with `undefined`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function request<K extends OperationId>(config: TransportConfig, id: K, args?: CallArgs): Promise<SuccessBody<K>>;
|
|
58
|
+
/** The item type of a list operation's page. */
|
|
59
|
+
type ItemOf<B> = B extends {
|
|
60
|
+
readonly data: readonly (infer I)[];
|
|
61
|
+
} ? I : never;
|
|
62
|
+
/**
|
|
63
|
+
* Calls a list operation lazily: nothing is sent until the result is
|
|
64
|
+
* awaited or iterated. Each following page sends the same query with
|
|
65
|
+
* `cursor` set to the previous page's `next_cursor` and without `page`.
|
|
66
|
+
*
|
|
67
|
+
* The walk remembers every cursor it has sent since the list call, with
|
|
68
|
+
* the position of the page each requested; a cursor the caller's own query
|
|
69
|
+
* held requested the first. A page with `has_more` whose `next_cursor` was
|
|
70
|
+
* sent for a page at another position would walk in a cycle, so it is
|
|
71
|
+
* unreadable: an `ApiError` with the page's status and no problem. Walking
|
|
72
|
+
* again from an earlier page sends each cursor for its own position, and is
|
|
73
|
+
* not refused.
|
|
74
|
+
*/
|
|
75
|
+
export declare function requestPage<K extends OperationId>(config: TransportConfig, id: K, args?: CallArgs): PagePromise<ItemOf<SuccessBody<K>>, Extract<SuccessBody<K>, ListBody>>;
|
|
76
|
+
/**
|
|
77
|
+
* The arguments of one page's request: the call's own, with the query and
|
|
78
|
+
* options paging sets for that page. Every other member is carried forward.
|
|
79
|
+
*/
|
|
80
|
+
export declare function pageArgs(args: CallArgs, query: object | undefined, options: RequestOptions): CallArgs;
|
|
81
|
+
/** An operation's path parameters, from the generated types. */
|
|
82
|
+
type PathOf<K extends OperationId> = NonNullable<operations[K]["parameters"]["path"]>;
|
|
83
|
+
/**
|
|
84
|
+
* The query member of an operation's arguments: required when the
|
|
85
|
+
* generated types require the query, which they do when any one of its
|
|
86
|
+
* parameters is required, and optional otherwise.
|
|
87
|
+
*/
|
|
88
|
+
type QueryArgs<K extends OperationId> = undefined extends operations[K]["parameters"]["query"] ? {
|
|
89
|
+
readonly query?: QueryOf<K> | undefined;
|
|
90
|
+
} : {
|
|
91
|
+
readonly query: QueryOf<K>;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* The body an operation takes, from the generated types: an `ImportUpload`
|
|
95
|
+
* for a form, and otherwise the JSON body with its money widened.
|
|
96
|
+
*/
|
|
97
|
+
type BodyOf<K extends OperationId> = operations[K] extends {
|
|
98
|
+
requestBody: {
|
|
99
|
+
content: infer C;
|
|
100
|
+
};
|
|
101
|
+
} ? "multipart/form-data" extends keyof C ? ImportUpload : MoneyInput<C[keyof C]> : never;
|
|
102
|
+
/**
|
|
103
|
+
* What a resource method passes for one operation, typed from the generated
|
|
104
|
+
* types. A change to the API that retypes an operation's path, query or
|
|
105
|
+
* body, or that makes its query required, fails the compile of the method
|
|
106
|
+
* that calls it.
|
|
107
|
+
*/
|
|
108
|
+
export type OperationArgs<K extends OperationId> = {
|
|
109
|
+
readonly path?: PathOf<K>;
|
|
110
|
+
readonly body?: BodyOf<K>;
|
|
111
|
+
readonly options?: IdempotentRequestOptions | undefined;
|
|
112
|
+
} & QueryArgs<K>;
|
|
113
|
+
/** Calls one operation with arguments typed for it; see `request`. */
|
|
114
|
+
export declare function call<K extends OperationId>(config: TransportConfig, id: K, args: OperationArgs<K>): Promise<SuccessBody<K>>;
|
|
115
|
+
/** Calls one list operation with arguments typed for it; see `requestPage`. */
|
|
116
|
+
export declare function callPage<K extends OperationId>(config: TransportConfig, id: K, args: OperationArgs<K>): PagePromise<ItemOf<SuccessBody<K>>, Extract<SuccessBody<K>, ListBody>>;
|
|
117
|
+
export {};
|