@cosmoops/connect-sdk 0.1.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 +34 -0
- package/README.md +446 -0
- package/dist/cjs/cli/bin.js +16 -0
- package/dist/cjs/cli/init.js +179 -0
- package/dist/cjs/client/components/account-sessions.js +112 -0
- package/dist/cjs/client/components/apps-grid.js +46 -0
- package/dist/cjs/client/components/auth-buttons.js +42 -0
- package/dist/cjs/client/components/feature-gate.js +61 -0
- package/dist/cjs/client/components/link-button.js +24 -0
- package/dist/cjs/client/components/logo.js +27 -0
- package/dist/cjs/client/components/plan-pricing.js +166 -0
- package/dist/cjs/client/components/plans-page.js +39 -0
- package/dist/cjs/client/components/plans.js +212 -0
- package/dist/cjs/client/components/readiness.js +117 -0
- package/dist/cjs/client/components/subscribe-dialog.js +60 -0
- package/dist/cjs/client/components/subscription.js +189 -0
- package/dist/cjs/client/components/usage-meter.js +68 -0
- package/dist/cjs/client/components/user-menu.js +172 -0
- package/dist/cjs/client/index.js +99 -0
- package/dist/cjs/client/mark.js +16 -0
- package/dist/cjs/client/provider.js +259 -0
- package/dist/cjs/client/use-checkout.js +173 -0
- package/dist/cjs/errors.js +74 -0
- package/dist/cjs/format-relative-time.js +18 -0
- package/dist/cjs/helpers.js +30 -0
- package/dist/cjs/index.js +22 -0
- package/dist/cjs/next/index.js +311 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/server/client.js +114 -0
- package/dist/cjs/server/handler.js +333 -0
- package/dist/cjs/server/http.js +160 -0
- package/dist/cjs/server/index.js +18 -0
- package/dist/cjs/server/resources/access.js +28 -0
- package/dist/cjs/server/resources/ai.js +36 -0
- package/dist/cjs/server/resources/apps.js +30 -0
- package/dist/cjs/server/resources/billing.js +71 -0
- package/dist/cjs/server/resources/drive.js +39 -0
- package/dist/cjs/server/resources/entitlements.js +49 -0
- package/dist/cjs/server/resources/identity.js +194 -0
- package/dist/cjs/server/resources/logs.js +41 -0
- package/dist/cjs/server/resources/otp.js +29 -0
- package/dist/cjs/server/resources/sessions.js +82 -0
- package/dist/cjs/types.js +15 -0
- package/dist/esm/cli/bin.js +13 -0
- package/dist/esm/cli/init.js +174 -0
- package/dist/esm/client/components/account-sessions.js +109 -0
- package/dist/esm/client/components/apps-grid.js +43 -0
- package/dist/esm/client/components/auth-buttons.js +38 -0
- package/dist/esm/client/components/feature-gate.js +57 -0
- package/dist/esm/client/components/link-button.js +21 -0
- package/dist/esm/client/components/logo.js +24 -0
- package/dist/esm/client/components/plan-pricing.js +156 -0
- package/dist/esm/client/components/plans-page.js +36 -0
- package/dist/esm/client/components/plans.js +209 -0
- package/dist/esm/client/components/readiness.js +113 -0
- package/dist/esm/client/components/subscribe-dialog.js +57 -0
- package/dist/esm/client/components/subscription.js +181 -0
- package/dist/esm/client/components/usage-meter.js +65 -0
- package/dist/esm/client/components/user-menu.js +164 -0
- package/dist/esm/client/index.js +47 -0
- package/dist/esm/client/mark.js +13 -0
- package/dist/esm/client/provider.js +247 -0
- package/dist/esm/client/use-checkout.js +168 -0
- package/dist/esm/errors.js +69 -0
- package/dist/esm/format-relative-time.js +15 -0
- package/dist/esm/helpers.js +26 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/next/index.js +279 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/server/client.js +110 -0
- package/dist/esm/server/handler.js +330 -0
- package/dist/esm/server/http.js +156 -0
- package/dist/esm/server/index.js +10 -0
- package/dist/esm/server/resources/access.js +24 -0
- package/dist/esm/server/resources/ai.js +32 -0
- package/dist/esm/server/resources/apps.js +26 -0
- package/dist/esm/server/resources/billing.js +67 -0
- package/dist/esm/server/resources/drive.js +35 -0
- package/dist/esm/server/resources/entitlements.js +45 -0
- package/dist/esm/server/resources/identity.js +189 -0
- package/dist/esm/server/resources/logs.js +37 -0
- package/dist/esm/server/resources/otp.js +25 -0
- package/dist/esm/server/resources/sessions.js +78 -0
- package/dist/esm/types.js +14 -0
- package/dist/theme.css +84 -0
- package/dist/types/cli/bin.d.ts +1 -0
- package/dist/types/cli/init.d.ts +34 -0
- package/dist/types/client/components/account-sessions.d.ts +25 -0
- package/dist/types/client/components/apps-grid.d.ts +20 -0
- package/dist/types/client/components/auth-buttons.d.ts +31 -0
- package/dist/types/client/components/feature-gate.d.ts +57 -0
- package/dist/types/client/components/link-button.d.ts +20 -0
- package/dist/types/client/components/logo.d.ts +35 -0
- package/dist/types/client/components/plan-pricing.d.ts +96 -0
- package/dist/types/client/components/plans-page.d.ts +36 -0
- package/dist/types/client/components/plans.d.ts +34 -0
- package/dist/types/client/components/readiness.d.ts +52 -0
- package/dist/types/client/components/subscribe-dialog.d.ts +34 -0
- package/dist/types/client/components/subscription.d.ts +123 -0
- package/dist/types/client/components/usage-meter.d.ts +24 -0
- package/dist/types/client/components/user-menu.d.ts +86 -0
- package/dist/types/client/index.d.ts +47 -0
- package/dist/types/client/mark.d.ts +11 -0
- package/dist/types/client/provider.d.ts +209 -0
- package/dist/types/client/use-checkout.d.ts +93 -0
- package/dist/types/errors.d.ts +62 -0
- package/dist/types/format-relative-time.d.ts +2 -0
- package/dist/types/helpers.d.ts +33 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/next/index.d.ts +136 -0
- package/dist/types/server/client.d.ts +83 -0
- package/dist/types/server/handler.d.ts +67 -0
- package/dist/types/server/http.d.ts +52 -0
- package/dist/types/server/index.d.ts +15 -0
- package/dist/types/server/resources/access.d.ts +17 -0
- package/dist/types/server/resources/ai.d.ts +24 -0
- package/dist/types/server/resources/apps.d.ts +12 -0
- package/dist/types/server/resources/billing.d.ts +41 -0
- package/dist/types/server/resources/drive.d.ts +26 -0
- package/dist/types/server/resources/entitlements.d.ts +31 -0
- package/dist/types/server/resources/identity.d.ts +76 -0
- package/dist/types/server/resources/logs.d.ts +20 -0
- package/dist/types/server/resources/otp.d.ts +17 -0
- package/dist/types/server/resources/sessions.d.ts +37 -0
- package/dist/types/types.d.ts +434 -0
- package/package.json +102 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { FetchLike } from "./http.js";
|
|
2
|
+
import { AccessResource } from "./resources/access.js";
|
|
3
|
+
import { AppsResource } from "./resources/apps.js";
|
|
4
|
+
import { AiResource } from "./resources/ai.js";
|
|
5
|
+
import { BillingResource } from "./resources/billing.js";
|
|
6
|
+
import { DriveResource } from "./resources/drive.js";
|
|
7
|
+
import { EntitlementsResource } from "./resources/entitlements.js";
|
|
8
|
+
import { IdentityResource } from "./resources/identity.js";
|
|
9
|
+
import { LogsResource } from "./resources/logs.js";
|
|
10
|
+
import { OtpResource } from "./resources/otp.js";
|
|
11
|
+
import { SessionsResource } from "./resources/sessions.js";
|
|
12
|
+
export declare const DEFAULT_BASE_URL = "https://connect.cosmoops.com";
|
|
13
|
+
export interface ConnectClientOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The API key plaintext from this service's Setup tab, shown once at
|
|
16
|
+
* creation.
|
|
17
|
+
*
|
|
18
|
+
* One credential does three jobs: it is the `Authorization: Bearer` value
|
|
19
|
+
* for every endpoint, the OAuth2 `client_secret` for the `/sso/*` exchange,
|
|
20
|
+
* and the HMAC key `identity.verifyIdToken()` checks against. Revoking the
|
|
21
|
+
* key revokes all three.
|
|
22
|
+
*/
|
|
23
|
+
apiKey: string;
|
|
24
|
+
/** Required only for `identity.*`. Public - it goes in the authorize URL. */
|
|
25
|
+
clientId?: string;
|
|
26
|
+
/** Defaults to `https://connect.cosmoops.com`. Point at your own instance if you run one. */
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
/** Per attempt, not per call. Defaults to 20s. */
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Extra attempts after the first, for requests that are safe to repeat.
|
|
32
|
+
* Defaults to 2. See `request()` in `http.ts` for what qualifies - a bare
|
|
33
|
+
* POST never does.
|
|
34
|
+
*/
|
|
35
|
+
maxRetries?: number;
|
|
36
|
+
/** Swap in your own instrumented `fetch`. Defaults to the runtime's. */
|
|
37
|
+
fetch?: FetchLike;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The CosmoOps Connect service-partner API.
|
|
41
|
+
*
|
|
42
|
+
* Covers `/api/v1/service/*` and nothing else - the surface a service platform
|
|
43
|
+
* integrates against. Connect's internal API is not part of this package and
|
|
44
|
+
* never will be.
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* const connect = new ConnectClient({
|
|
48
|
+
* apiKey: process.env.CONNECT_API_KEY!,
|
|
49
|
+
* clientId: process.env.CONNECT_CLIENT_ID,
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* const session = await connect.identity.exchangeCode({ code, redirectUri });
|
|
53
|
+
* const { ready } = await connect.entitlements.getReadiness(session.user.organizationId);
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* Every failure throws a `ConnectError` carrying a stable `code`. Nothing here
|
|
57
|
+
* holds state between calls, so one client can be built once and shared.
|
|
58
|
+
*/
|
|
59
|
+
export declare class ConnectClient {
|
|
60
|
+
/** "Login with Connect" - the OAuth2 handshake and the session after it. */
|
|
61
|
+
readonly identity: IdentityResource;
|
|
62
|
+
/** What a signed-in member may do on your service. */
|
|
63
|
+
readonly access: AccessResource;
|
|
64
|
+
/** The services an organization can open - for a launcher grid. */
|
|
65
|
+
readonly apps: AppsResource;
|
|
66
|
+
/** Whether a workspace may use your service, and on what plan. */
|
|
67
|
+
readonly entitlements: EntitlementsResource;
|
|
68
|
+
/** Your plan catalog, and metering usage against add-on balances. */
|
|
69
|
+
readonly billing: BillingResource;
|
|
70
|
+
/** Files in an organization's Drive. */
|
|
71
|
+
readonly drive: DriveResource;
|
|
72
|
+
/** RAG chat and structured extraction. */
|
|
73
|
+
readonly ai: AiResource;
|
|
74
|
+
/** WhatsApp/SMS phone verification. */
|
|
75
|
+
readonly otp: OtpResource;
|
|
76
|
+
/** Feature events into the Console's audit log, filterable to your service. */
|
|
77
|
+
readonly logs: LogsResource;
|
|
78
|
+
/** This Connect account's own login sessions - account-wide, not scoped to this service. Requires the `sessions:manage` scope. */
|
|
79
|
+
readonly sessions: SessionsResource;
|
|
80
|
+
constructor(options: ConnectClientOptions);
|
|
81
|
+
}
|
|
82
|
+
/** Kept in step with `package.json` by `sdk.test.ts`. */
|
|
83
|
+
export declare const SDK_VERSION = "0.1.0";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ConnectClient } from "./client.js";
|
|
2
|
+
/**
|
|
3
|
+
* What the bridge needs from the partner's own session, and what it may change
|
|
4
|
+
* about it.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately an interface rather than a cookie this SDK sets: the partner
|
|
7
|
+
* already has a session mechanism, and a second one owned by a dependency
|
|
8
|
+
* would be a second source of truth about who is signed in.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConnectSessionStore {
|
|
11
|
+
/** The Connect `sessionToken` for this caller, or `null` if signed out. */
|
|
12
|
+
read(request: Request): Promise<string | null> | string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Persist a freshly exchanged session. Supplying this turns on `/signin` and
|
|
15
|
+
* `/callback`, so the handler runs the whole OAuth round trip instead of
|
|
16
|
+
* leaving you to write the callback route - see `createConnectHandler`.
|
|
17
|
+
* Set cookies on `response`.
|
|
18
|
+
*/
|
|
19
|
+
write?(request: Request, response: Response, sessionToken: string): Promise<void> | void;
|
|
20
|
+
/** Called on sign-out, before Connect is told. Clear your own session here - set cookies on `response`. */
|
|
21
|
+
clear?(request: Request, response: Response): Promise<void> | void;
|
|
22
|
+
}
|
|
23
|
+
export interface ConnectHandlerOptions {
|
|
24
|
+
client: ConnectClient;
|
|
25
|
+
session: ConnectSessionStore;
|
|
26
|
+
/**
|
|
27
|
+
* Where this handler is mounted, so it can strip the prefix off incoming
|
|
28
|
+
* paths. Must match `basePath` on `<ConnectProvider>`. Defaults to
|
|
29
|
+
* `/api/connect`.
|
|
30
|
+
*/
|
|
31
|
+
basePath?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Where `/callback` sends the user when the request carried no `next`.
|
|
34
|
+
* Defaults to `/`.
|
|
35
|
+
*/
|
|
36
|
+
defaultRedirect?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Name of the short-lived cookie holding the OAuth `state`. Only change it
|
|
39
|
+
* if it collides with something you already set.
|
|
40
|
+
*/
|
|
41
|
+
stateCookieName?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The browser half of this SDK cannot hold an API key - so it does not.
|
|
45
|
+
*
|
|
46
|
+
* `@cosmoops/connect-sdk/client` talks only to your own origin, and this
|
|
47
|
+
* handler is what answers. It lives in your backend, holds the key, and
|
|
48
|
+
* exposes a fixed, named set of reads plus sign-out and session revocation.
|
|
49
|
+
* Nothing here proxies arbitrary paths: a generic passthrough would hand the
|
|
50
|
+
* browser your whole API surface under your credentials, which is the same
|
|
51
|
+
* leak with extra steps.
|
|
52
|
+
*
|
|
53
|
+
* Framework-agnostic - `Request` in, `Response` out, so it mounts anywhere
|
|
54
|
+
* that shape exists.
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* // app/api/connect/[...route]/route.ts
|
|
58
|
+
* const handler = createConnectHandler({ client, session });
|
|
59
|
+
* export { handler as GET, handler as POST };
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* Every route resolves the organization from the caller's *own* session, never
|
|
63
|
+
* from a query parameter. A browser must not be able to ask about an
|
|
64
|
+
* organization it is not signed into, and a client-supplied `organizationId`
|
|
65
|
+
* is exactly that hole.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createConnectHandler(options: ConnectHandlerOptions): (request: Request) => Promise<Response>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
2
|
+
export interface RequestSpec {
|
|
3
|
+
method: "GET" | "POST";
|
|
4
|
+
/** Relative to the API base, e.g. `/plans`. */
|
|
5
|
+
path: string;
|
|
6
|
+
query?: Record<string, string | number | undefined>;
|
|
7
|
+
/** Sent as JSON. Mutually exclusive with `form` and `multipart`. */
|
|
8
|
+
json?: unknown;
|
|
9
|
+
/** Sent as `application/x-www-form-urlencoded` - what the `/sso/*` endpoints take. */
|
|
10
|
+
form?: Record<string, string | undefined>;
|
|
11
|
+
multipart?: FormData;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
/** Bearer API key (default), or none - the `/sso/*` endpoints authenticate inside the form body instead. */
|
|
14
|
+
auth?: "bearer" | "none";
|
|
15
|
+
/** Skip JSON parsing and hand back the raw `Response` - for streaming endpoints. */
|
|
16
|
+
raw?: boolean;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
export interface TransportOptions {
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
apiKey: string;
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
maxRetries: number;
|
|
24
|
+
fetch: FetchLike;
|
|
25
|
+
userAgent: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One id, safe to interpolate into a request path.
|
|
29
|
+
*
|
|
30
|
+
* `encodeURIComponent` alone is not enough, and the gap is easy to miss: it
|
|
31
|
+
* leaves `.` untouched, so an id of `".."` survives into the URL and the URL
|
|
32
|
+
* parser then collapses the segment *before* it - `/drive/files/../url`
|
|
33
|
+
* resolves to `/drive/url`, a different endpoint reached under the same API
|
|
34
|
+
* key. Slashes are encoded, so the traversal cannot chain past one segment,
|
|
35
|
+
* but one is already an endpoint the caller did not ask for.
|
|
36
|
+
*
|
|
37
|
+
* Relevant whenever an id reaches the SDK from a partner's own end users,
|
|
38
|
+
* which is the normal case for a file id.
|
|
39
|
+
*/
|
|
40
|
+
export declare function pathSegment(value: string, name: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* The one place a request leaves this SDK: builds it, applies the per-attempt
|
|
43
|
+
* timeout, retries what is safe to retry, and turns every failure into a
|
|
44
|
+
* `ConnectError`.
|
|
45
|
+
*
|
|
46
|
+
* **On retries.** Only idempotent requests are retried without a caller
|
|
47
|
+
* opt-in: every `GET`, plus any `POST` carrying an `Idempotency-Key` (the
|
|
48
|
+
* resources that mutate - `billing.consumeAddon`, `otp.send` - always set
|
|
49
|
+
* one). A bare `POST` is attempted exactly once, because a 429 or a 504 says
|
|
50
|
+
* nothing about whether the server already did the work.
|
|
51
|
+
*/
|
|
52
|
+
export declare function request<T>(options: TransportOptions, spec: RequestSpec): Promise<T>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-only half of `@cosmoops/connect-sdk`.
|
|
3
|
+
*
|
|
4
|
+
* Everything here handles the API key, so none of it may run in a browser.
|
|
5
|
+
* The browser half is `@cosmoops/connect-sdk/client`, which talks to your own
|
|
6
|
+
* origin and reaches Connect through `createConnectHandler` below.
|
|
7
|
+
*/
|
|
8
|
+
export { ConnectClient, DEFAULT_BASE_URL, SDK_VERSION } from "./client.js";
|
|
9
|
+
export type { ConnectClientOptions } from "./client.js";
|
|
10
|
+
export { createConnectHandler } from "./handler.js";
|
|
11
|
+
export type { ConnectHandlerOptions, ConnectSessionStore } from "./handler.js";
|
|
12
|
+
export { createState } from "./resources/identity.js";
|
|
13
|
+
export type { AuthorizeUrlInput, ExchangeCodeInput } from "./resources/identity.js";
|
|
14
|
+
export type { UploadInput } from "./resources/drive.js";
|
|
15
|
+
export type { FetchLike } from "./http.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { RolesResponse, UserRolesResponse } from "../../types.js";
|
|
3
|
+
/** What a signed-in member may do on your service, and the role catalog behind it. */
|
|
4
|
+
export declare class AccessResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Re-check one member's role and granted permissions, live. The same block
|
|
9
|
+
* `identity.getUser()` returns - use this when you need only the role axis
|
|
10
|
+
* and already know who the user is.
|
|
11
|
+
*/
|
|
12
|
+
getUserRoles(userId: string, input: {
|
|
13
|
+
organizationId: string;
|
|
14
|
+
}): Promise<UserRolesResponse>;
|
|
15
|
+
/** Your service's own permission catalog and role definitions - the definitions `getUserRoles` resolves against. */
|
|
16
|
+
listRoles(): Promise<RolesResponse>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { ChatMessage } from "../../types.js";
|
|
3
|
+
/** RAG chat and structured extraction against an organization's data. */
|
|
4
|
+
export declare class AiResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* RAG-grounded chat. Returns the raw streaming `Response` rather than a
|
|
9
|
+
* parsed body - this endpoint answers with server-sent events, and buffering
|
|
10
|
+
* it here would throw away the only reason to stream. Pipe
|
|
11
|
+
* `response.body` onward, or hand it to the AI SDK's own reader.
|
|
12
|
+
*/
|
|
13
|
+
chat(input: {
|
|
14
|
+
organizationId: string;
|
|
15
|
+
messages: ChatMessage[];
|
|
16
|
+
}, options?: {
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}): Promise<Response>;
|
|
19
|
+
/** Extract structured JSON from a file or image URL, against a platform extraction schema referenced by id. */
|
|
20
|
+
extract<T = unknown>(input: {
|
|
21
|
+
schemaId: string;
|
|
22
|
+
fileUrl: string;
|
|
23
|
+
}): Promise<T>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { OrganizationApp } from "../../types.js";
|
|
3
|
+
/** The services an organization can open - the data behind a launcher grid. */
|
|
4
|
+
export declare class AppsResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Launchable apps only, so a grid tile is never a dead end. The calling
|
|
9
|
+
* service is included and flagged `isCurrent` rather than filtered out.
|
|
10
|
+
*/
|
|
11
|
+
list(organizationId: string): Promise<OrganizationApp[]>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { AddonUsageResponse, ConsumeAddonInput, ConsumeAddonResponse, PlansResponse } from "../../types.js";
|
|
3
|
+
/** The plan catalog you sell, and metering usage back against a subscriber's add-on balance. */
|
|
4
|
+
export declare class BillingResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Your service's active plans - render live pricing instead of hardcoding it.
|
|
9
|
+
*
|
|
10
|
+
* `features` is normalised on the way out: Connect used to send bare keys
|
|
11
|
+
* and now sends `{ key, name, description }`, and this SDK is versioned
|
|
12
|
+
* independently of the instance it talks to. Without the coercion a partner
|
|
13
|
+
* pointed at a Connect that has not upgraded yet renders a feature list of
|
|
14
|
+
* blanks - which is exactly what happened. See `normalizePlanFeatures`.
|
|
15
|
+
*/
|
|
16
|
+
listPlans(): Promise<PlansResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* What is left of every consumable add-on on an organization's
|
|
19
|
+
* subscription - the read half of `consumeAddon`.
|
|
20
|
+
*
|
|
21
|
+
* Needs a key scoped to `addons:read`, which is separate from
|
|
22
|
+
* `addons:consume` on purpose: a key that only renders a usage meter should
|
|
23
|
+
* not also be able to spend the balance down.
|
|
24
|
+
*
|
|
25
|
+
* Returns an empty `addons` array rather than throwing when there is
|
|
26
|
+
* nothing to meter, so a caller can render it unconditionally.
|
|
27
|
+
*/
|
|
28
|
+
getAddonUsage(organizationId: string): Promise<AddonUsageResponse>;
|
|
29
|
+
/**
|
|
30
|
+
* Debit a consumable add-on's per-cycle balance on behalf of an
|
|
31
|
+
* organization's users. Call it at whatever cadence your usage happens.
|
|
32
|
+
*
|
|
33
|
+
* An `Idempotency-Key` is always sent, generated per call when you do not
|
|
34
|
+
* supply one: a balance cannot be un-spent, so a retried consume without a
|
|
35
|
+
* key double-debits. Pass your own when the natural unit of work is
|
|
36
|
+
* something you can name (a job id, a message id) and might submit twice.
|
|
37
|
+
*/
|
|
38
|
+
consumeAddon(input: ConsumeAddonInput, options?: {
|
|
39
|
+
idempotencyKey?: string;
|
|
40
|
+
}): Promise<ConsumeAddonResponse>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { ThumbnailSize, UploadedFile } from "../../types.js";
|
|
3
|
+
export interface UploadInput {
|
|
4
|
+
organizationId: string;
|
|
5
|
+
/** Any `Blob`/`File`. In Node, `new Blob([buffer])` or `fs.openAsBlob(path)`. */
|
|
6
|
+
file: Blob;
|
|
7
|
+
/** Defaults to the `Blob`'s own name when it has one. */
|
|
8
|
+
fileName?: string;
|
|
9
|
+
/** Target folder. Omit for the Drive root. */
|
|
10
|
+
parentId?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Files in an organization's Drive - upload, and signed URLs to read back. */
|
|
13
|
+
export declare class DriveResource {
|
|
14
|
+
private readonly transport;
|
|
15
|
+
constructor(transport: TransportOptions);
|
|
16
|
+
upload(input: UploadInput): Promise<UploadedFile>;
|
|
17
|
+
/** A signed URL for the original bytes. Short-lived - fetch it when you need it, do not store it. */
|
|
18
|
+
getFileUrl(fileId: string, input: {
|
|
19
|
+
organizationId: string;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
/** A signed URL for the thumbnail. Same lifetime caveat as `getFileUrl`. */
|
|
22
|
+
getPreviewUrl(fileId: string, input: {
|
|
23
|
+
organizationId: string;
|
|
24
|
+
size?: ThumbnailSize;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { ReadinessResponse, SubscriptionResponse } from "../../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The two checks worth making on every request: may this workspace be here at
|
|
5
|
+
* all, and what is it paying for.
|
|
6
|
+
*/
|
|
7
|
+
export declare class EntitlementsResource {
|
|
8
|
+
private readonly transport;
|
|
9
|
+
constructor(transport: TransportOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Every gate Connect owns between an organization and your service -
|
|
12
|
+
* subscription, KYC/KYB, a chargeable payment method, seat headroom -
|
|
13
|
+
* resolved in one call.
|
|
14
|
+
*
|
|
15
|
+
* Blocked users are the point: each blocker carries a `resolveUrl` into the
|
|
16
|
+
* Connect screen that fixes it, so you can route them somewhere useful
|
|
17
|
+
* instead of refusing them with nowhere to go.
|
|
18
|
+
*/
|
|
19
|
+
getReadiness(organizationId: string): Promise<ReadinessResponse>;
|
|
20
|
+
/** The live plan and subscription, including `plan.features`. */
|
|
21
|
+
getSubscription(organizationId: string): Promise<SubscriptionResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Whether an active subscription unlocks a plan feature - the check that
|
|
24
|
+
* gates a plan-restricted module.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately `false` rather than a throw when there is no subscription at
|
|
27
|
+
* all: "not entitled" is the same answer either way, and a feature gate
|
|
28
|
+
* should not need a try/catch around it.
|
|
29
|
+
*/
|
|
30
|
+
hasFeature(organizationId: string, feature: string): Promise<boolean>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { IdTokenClaims, LogoutScope, TokenResponse, UserResponse } from "../../types.js";
|
|
3
|
+
export interface AuthorizeUrlInput {
|
|
4
|
+
redirectUri: string;
|
|
5
|
+
/** Fresh and random per request; check it matches on the way back. `createState()` makes one. */
|
|
6
|
+
state: string;
|
|
7
|
+
/** `"create"` opens registration instead of sign-in, so one entry point serves both buttons. */
|
|
8
|
+
prompt?: "create";
|
|
9
|
+
/** Required only if this service enforces PKCE. */
|
|
10
|
+
codeChallenge?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ExchangeCodeInput {
|
|
13
|
+
code: string;
|
|
14
|
+
/** Must be byte-identical to the one sent to `authorizeUrl()`. */
|
|
15
|
+
redirectUri: string;
|
|
16
|
+
codeVerifier?: string;
|
|
17
|
+
}
|
|
18
|
+
/** A URL-safe random string, suitable for `state` or a PKCE verifier. */
|
|
19
|
+
export declare function createState(byteLength?: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* "Login with Connect" - the OAuth2 handshake, and the session that outlives
|
|
22
|
+
* it.
|
|
23
|
+
*
|
|
24
|
+
* The whole flow is five calls: `authorizeUrl` to send them out,
|
|
25
|
+
* `exchangeCode` when they come back, `verifyIdToken` once, then `getUser` on
|
|
26
|
+
* each later request and `logout` at the end.
|
|
27
|
+
*/
|
|
28
|
+
export declare class IdentityResource {
|
|
29
|
+
private readonly transport;
|
|
30
|
+
private readonly clientId;
|
|
31
|
+
private readonly appBaseUrl;
|
|
32
|
+
constructor(transport: TransportOptions, clientId: string | null, appBaseUrl: string);
|
|
33
|
+
/** Step 1 - the URL to send the user's browser to. */
|
|
34
|
+
authorizeUrl(input: AuthorizeUrlInput): string;
|
|
35
|
+
/** Step 2 - trade the one-time `code` for a session. Server-side only. */
|
|
36
|
+
exchangeCode(input: ExchangeCodeInput): Promise<TokenResponse>;
|
|
37
|
+
/**
|
|
38
|
+
* Step 3 - verify the `id_token` once, then discard it.
|
|
39
|
+
*
|
|
40
|
+
* HS256 over `header.payload`, keyed with your API key, plus the `exp` and
|
|
41
|
+
* `aud` checks. There is no JWKS to fetch: Connect stores only your key's
|
|
42
|
+
* sha256 hash, so the token is signed with the shared secret rather than an
|
|
43
|
+
* asymmetric key. Signature comparison goes through WebCrypto's own
|
|
44
|
+
* `verify`, which is why this is async - hand-rolling the compare is the
|
|
45
|
+
* step integrations most often get wrong.
|
|
46
|
+
*/
|
|
47
|
+
verifyIdToken(idToken: string): Promise<IdTokenClaims>;
|
|
48
|
+
/**
|
|
49
|
+
* Step 4 - who is signed in, right now. Same blocks as `exchangeCode`,
|
|
50
|
+
* re-resolved live, so a role change or a lapsed subscription shows up here
|
|
51
|
+
* without another sign-in.
|
|
52
|
+
*
|
|
53
|
+
* Any `ConnectError` with `isSessionExpired` means send them back through
|
|
54
|
+
* `authorizeUrl()`.
|
|
55
|
+
*/
|
|
56
|
+
getUser(sessionToken: string): Promise<UserResponse>;
|
|
57
|
+
/**
|
|
58
|
+
* Step 5 - end the sign-in immediately rather than leaving it valid for the
|
|
59
|
+
* rest of its ~15-day life. Discard your own copy of `sessionToken` too;
|
|
60
|
+
* this does not do that for you.
|
|
61
|
+
*
|
|
62
|
+
* `scope` defaults to `"device"`: this sign-in, every other service signed
|
|
63
|
+
* into from the same browser, and Connect's own session on that one device.
|
|
64
|
+
* `"all"` ends every session on every device - an explicit "sign out
|
|
65
|
+
* everywhere" action only.
|
|
66
|
+
*
|
|
67
|
+
* Always succeeds. An unknown or already-revoked token is an
|
|
68
|
+
* indistinguishable no-op, so there is nothing to branch on.
|
|
69
|
+
*/
|
|
70
|
+
logout(sessionToken: string, options?: {
|
|
71
|
+
scope?: LogoutScope;
|
|
72
|
+
}): Promise<void>;
|
|
73
|
+
private post;
|
|
74
|
+
private requireClientId;
|
|
75
|
+
private tokenError;
|
|
76
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { WriteLogInput, WriteLogResponse } from "../../types.js";
|
|
3
|
+
/** Push feature events into the Console's audit log, filterable to your service. */
|
|
4
|
+
export declare class LogsResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Never throws. A logging call that takes down the code path it was
|
|
9
|
+
* observing is worse than a lost line, so a failure here is swallowed and
|
|
10
|
+
* reported through the return value.
|
|
11
|
+
*
|
|
12
|
+
* Pass `sessionToken` to attribute the event to the end user it belongs to.
|
|
13
|
+
* Both scopes on the stored entry come from something verified - the service
|
|
14
|
+
* from your API key, the user from that token, which Connect checks was
|
|
15
|
+
* minted for your service before attributing anything. `attributed` in the
|
|
16
|
+
* result says whether it resolved; a `false` there still means the line was
|
|
17
|
+
* stored, just without a user on it.
|
|
18
|
+
*/
|
|
19
|
+
write(input: WriteLogInput): Promise<WriteLogResponse>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { SendOtpInput, SendOtpResponse, VerifyOtpInput, VerifyOtpResponse } from "../../types.js";
|
|
3
|
+
/** WhatsApp/SMS phone verification. */
|
|
4
|
+
export declare class OtpResource {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: TransportOptions);
|
|
7
|
+
/**
|
|
8
|
+
* Send a code. As with `billing.consumeAddon`, an `Idempotency-Key` always
|
|
9
|
+
* goes along - a retried send would otherwise deliver a second message and
|
|
10
|
+
* invalidate the first code the user is looking at.
|
|
11
|
+
*/
|
|
12
|
+
send(input: SendOtpInput, options?: {
|
|
13
|
+
idempotencyKey?: string;
|
|
14
|
+
}): Promise<SendOtpResponse>;
|
|
15
|
+
/** Check a 6-digit code against a `verificationId`. */
|
|
16
|
+
verify(input: VerifyOtpInput): Promise<VerifyOtpResponse>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { ConnectUserSession, RevokeOtherSessionsResponse } from "../../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* This Connect account's own login sessions - device, approximate location,
|
|
5
|
+
* timestamps - the same list Connect's own account settings page shows the
|
|
6
|
+
* user themselves.
|
|
7
|
+
*
|
|
8
|
+
* **Account-wide, not scoped to this service.** A Connect session is one
|
|
9
|
+
* browser's login to Connect, and it fans out to every partner service's own
|
|
10
|
+
* `sessionToken` - Connect has no per-service session concept to filter by.
|
|
11
|
+
* `list()` returns every session on the account, including ones that
|
|
12
|
+
* originated from a completely different, unrelated service. Requires the
|
|
13
|
+
* `sessions:manage` scope on your API key - unlike `identity`'s base `sso`
|
|
14
|
+
* capability, this is never granted to a zero-scope legacy key by default.
|
|
15
|
+
*
|
|
16
|
+
* Authenticated like `identity.*` - `client_id`+`client_secret`, never a
|
|
17
|
+
* Bearer key - because every call here is really "resolve identity from a
|
|
18
|
+
* `sessionToken`", the same shape `identity.getUser`/`identity.logout` are.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SessionsResource {
|
|
21
|
+
private readonly transport;
|
|
22
|
+
private readonly clientId;
|
|
23
|
+
constructor(transport: TransportOptions, clientId: string | null);
|
|
24
|
+
/** Every active session on the account behind `sessionToken`. `isCurrent` marks the one it was minted from. */
|
|
25
|
+
list(sessionToken: string): Promise<ConnectUserSession[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Ends one specific session by id - not necessarily the one `sessionToken`
|
|
28
|
+
* itself was minted from. Cascades to every partner-service sign-in that
|
|
29
|
+
* originated from that same browser, same as Connect's own "sign out this
|
|
30
|
+
* device".
|
|
31
|
+
*/
|
|
32
|
+
revoke(sessionToken: string, sessionId: string): Promise<void>;
|
|
33
|
+
/** "Sign out everywhere else" - keeps the session `sessionToken` was minted from, ends every other one. */
|
|
34
|
+
revokeOthers(sessionToken: string): Promise<RevokeOtherSessionsResponse>;
|
|
35
|
+
private post;
|
|
36
|
+
private requireClientId;
|
|
37
|
+
}
|