@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.
Files changed (126) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +446 -0
  3. package/dist/cjs/cli/bin.js +16 -0
  4. package/dist/cjs/cli/init.js +179 -0
  5. package/dist/cjs/client/components/account-sessions.js +112 -0
  6. package/dist/cjs/client/components/apps-grid.js +46 -0
  7. package/dist/cjs/client/components/auth-buttons.js +42 -0
  8. package/dist/cjs/client/components/feature-gate.js +61 -0
  9. package/dist/cjs/client/components/link-button.js +24 -0
  10. package/dist/cjs/client/components/logo.js +27 -0
  11. package/dist/cjs/client/components/plan-pricing.js +166 -0
  12. package/dist/cjs/client/components/plans-page.js +39 -0
  13. package/dist/cjs/client/components/plans.js +212 -0
  14. package/dist/cjs/client/components/readiness.js +117 -0
  15. package/dist/cjs/client/components/subscribe-dialog.js +60 -0
  16. package/dist/cjs/client/components/subscription.js +189 -0
  17. package/dist/cjs/client/components/usage-meter.js +68 -0
  18. package/dist/cjs/client/components/user-menu.js +172 -0
  19. package/dist/cjs/client/index.js +99 -0
  20. package/dist/cjs/client/mark.js +16 -0
  21. package/dist/cjs/client/provider.js +259 -0
  22. package/dist/cjs/client/use-checkout.js +173 -0
  23. package/dist/cjs/errors.js +74 -0
  24. package/dist/cjs/format-relative-time.js +18 -0
  25. package/dist/cjs/helpers.js +30 -0
  26. package/dist/cjs/index.js +22 -0
  27. package/dist/cjs/next/index.js +311 -0
  28. package/dist/cjs/package.json +3 -0
  29. package/dist/cjs/server/client.js +114 -0
  30. package/dist/cjs/server/handler.js +333 -0
  31. package/dist/cjs/server/http.js +160 -0
  32. package/dist/cjs/server/index.js +18 -0
  33. package/dist/cjs/server/resources/access.js +28 -0
  34. package/dist/cjs/server/resources/ai.js +36 -0
  35. package/dist/cjs/server/resources/apps.js +30 -0
  36. package/dist/cjs/server/resources/billing.js +71 -0
  37. package/dist/cjs/server/resources/drive.js +39 -0
  38. package/dist/cjs/server/resources/entitlements.js +49 -0
  39. package/dist/cjs/server/resources/identity.js +194 -0
  40. package/dist/cjs/server/resources/logs.js +41 -0
  41. package/dist/cjs/server/resources/otp.js +29 -0
  42. package/dist/cjs/server/resources/sessions.js +82 -0
  43. package/dist/cjs/types.js +15 -0
  44. package/dist/esm/cli/bin.js +13 -0
  45. package/dist/esm/cli/init.js +174 -0
  46. package/dist/esm/client/components/account-sessions.js +109 -0
  47. package/dist/esm/client/components/apps-grid.js +43 -0
  48. package/dist/esm/client/components/auth-buttons.js +38 -0
  49. package/dist/esm/client/components/feature-gate.js +57 -0
  50. package/dist/esm/client/components/link-button.js +21 -0
  51. package/dist/esm/client/components/logo.js +24 -0
  52. package/dist/esm/client/components/plan-pricing.js +156 -0
  53. package/dist/esm/client/components/plans-page.js +36 -0
  54. package/dist/esm/client/components/plans.js +209 -0
  55. package/dist/esm/client/components/readiness.js +113 -0
  56. package/dist/esm/client/components/subscribe-dialog.js +57 -0
  57. package/dist/esm/client/components/subscription.js +181 -0
  58. package/dist/esm/client/components/usage-meter.js +65 -0
  59. package/dist/esm/client/components/user-menu.js +164 -0
  60. package/dist/esm/client/index.js +47 -0
  61. package/dist/esm/client/mark.js +13 -0
  62. package/dist/esm/client/provider.js +247 -0
  63. package/dist/esm/client/use-checkout.js +168 -0
  64. package/dist/esm/errors.js +69 -0
  65. package/dist/esm/format-relative-time.js +15 -0
  66. package/dist/esm/helpers.js +26 -0
  67. package/dist/esm/index.js +15 -0
  68. package/dist/esm/next/index.js +279 -0
  69. package/dist/esm/package.json +3 -0
  70. package/dist/esm/server/client.js +110 -0
  71. package/dist/esm/server/handler.js +330 -0
  72. package/dist/esm/server/http.js +156 -0
  73. package/dist/esm/server/index.js +10 -0
  74. package/dist/esm/server/resources/access.js +24 -0
  75. package/dist/esm/server/resources/ai.js +32 -0
  76. package/dist/esm/server/resources/apps.js +26 -0
  77. package/dist/esm/server/resources/billing.js +67 -0
  78. package/dist/esm/server/resources/drive.js +35 -0
  79. package/dist/esm/server/resources/entitlements.js +45 -0
  80. package/dist/esm/server/resources/identity.js +189 -0
  81. package/dist/esm/server/resources/logs.js +37 -0
  82. package/dist/esm/server/resources/otp.js +25 -0
  83. package/dist/esm/server/resources/sessions.js +78 -0
  84. package/dist/esm/types.js +14 -0
  85. package/dist/theme.css +84 -0
  86. package/dist/types/cli/bin.d.ts +1 -0
  87. package/dist/types/cli/init.d.ts +34 -0
  88. package/dist/types/client/components/account-sessions.d.ts +25 -0
  89. package/dist/types/client/components/apps-grid.d.ts +20 -0
  90. package/dist/types/client/components/auth-buttons.d.ts +31 -0
  91. package/dist/types/client/components/feature-gate.d.ts +57 -0
  92. package/dist/types/client/components/link-button.d.ts +20 -0
  93. package/dist/types/client/components/logo.d.ts +35 -0
  94. package/dist/types/client/components/plan-pricing.d.ts +96 -0
  95. package/dist/types/client/components/plans-page.d.ts +36 -0
  96. package/dist/types/client/components/plans.d.ts +34 -0
  97. package/dist/types/client/components/readiness.d.ts +52 -0
  98. package/dist/types/client/components/subscribe-dialog.d.ts +34 -0
  99. package/dist/types/client/components/subscription.d.ts +123 -0
  100. package/dist/types/client/components/usage-meter.d.ts +24 -0
  101. package/dist/types/client/components/user-menu.d.ts +86 -0
  102. package/dist/types/client/index.d.ts +47 -0
  103. package/dist/types/client/mark.d.ts +11 -0
  104. package/dist/types/client/provider.d.ts +209 -0
  105. package/dist/types/client/use-checkout.d.ts +93 -0
  106. package/dist/types/errors.d.ts +62 -0
  107. package/dist/types/format-relative-time.d.ts +2 -0
  108. package/dist/types/helpers.d.ts +33 -0
  109. package/dist/types/index.d.ts +17 -0
  110. package/dist/types/next/index.d.ts +136 -0
  111. package/dist/types/server/client.d.ts +83 -0
  112. package/dist/types/server/handler.d.ts +67 -0
  113. package/dist/types/server/http.d.ts +52 -0
  114. package/dist/types/server/index.d.ts +15 -0
  115. package/dist/types/server/resources/access.d.ts +17 -0
  116. package/dist/types/server/resources/ai.d.ts +24 -0
  117. package/dist/types/server/resources/apps.d.ts +12 -0
  118. package/dist/types/server/resources/billing.d.ts +41 -0
  119. package/dist/types/server/resources/drive.d.ts +26 -0
  120. package/dist/types/server/resources/entitlements.d.ts +31 -0
  121. package/dist/types/server/resources/identity.d.ts +76 -0
  122. package/dist/types/server/resources/logs.d.ts +20 -0
  123. package/dist/types/server/resources/otp.d.ts +17 -0
  124. package/dist/types/server/resources/sessions.d.ts +37 -0
  125. package/dist/types/types.d.ts +434 -0
  126. 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
+ }