@cosmoops/connect-sdk 0.2.0 → 0.6.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/CHANGELOG.md +125 -0
- package/README.md +284 -7
- package/dist/cjs/cli/doctor.js +209 -0
- package/dist/cjs/cli/init.js +20 -8
- package/dist/cjs/client/components/access-gate.js +162 -0
- package/dist/cjs/client/components/account-sessions.js +21 -19
- package/dist/cjs/client/components/app-shell.js +157 -0
- package/dist/cjs/client/components/apps-grid.js +2 -1
- package/dist/cjs/client/components/integrations-modal.js +95 -0
- package/dist/cjs/client/components/motion.js +27 -0
- package/dist/cjs/client/components/nav.js +97 -0
- package/dist/cjs/client/components/plans.js +39 -37
- package/dist/cjs/client/components/readiness.js +3 -1
- package/dist/cjs/client/components/side-nav.js +58 -0
- package/dist/cjs/client/components/subscription.js +2 -1
- package/dist/cjs/client/components/surfaces.js +54 -0
- package/dist/cjs/client/components/usage-meter.js +3 -2
- package/dist/cjs/client/components/user-menu.js +30 -3
- package/dist/cjs/client/index.js +29 -1
- package/dist/cjs/client/provider.js +54 -2
- package/dist/cjs/client/use-active-path.js +77 -0
- package/dist/cjs/errors.js +1 -1
- package/dist/cjs/next/index.js +96 -15
- package/dist/cjs/server/client.js +10 -2
- package/dist/cjs/server/handler.js +89 -6
- package/dist/cjs/server/index.js +8 -1
- package/dist/cjs/server/resources/analytics.js +66 -0
- package/dist/cjs/server/resources/identity.js +1 -1
- package/dist/cjs/server/resources/integrations.js +66 -0
- package/dist/cjs/server/resources/sessions.js +1 -1
- package/dist/cjs/server/webhooks.js +127 -0
- package/dist/cjs/this-entry-is-server-only.js +31 -0
- package/dist/esm/cli/doctor.js +206 -0
- package/dist/esm/cli/init.js +20 -8
- package/dist/esm/client/components/access-gate.js +158 -0
- package/dist/esm/client/components/account-sessions.js +21 -19
- package/dist/esm/client/components/app-shell.js +154 -0
- package/dist/esm/client/components/apps-grid.js +2 -1
- package/dist/esm/client/components/integrations-modal.js +92 -0
- package/dist/esm/client/components/motion.js +21 -0
- package/dist/esm/client/components/nav.js +89 -0
- package/dist/esm/client/components/plans.js +39 -37
- package/dist/esm/client/components/readiness.js +3 -1
- package/dist/esm/client/components/side-nav.js +53 -0
- package/dist/esm/client/components/subscription.js +2 -1
- package/dist/esm/client/components/surfaces.js +51 -0
- package/dist/esm/client/components/usage-meter.js +3 -2
- package/dist/esm/client/components/user-menu.js +31 -4
- package/dist/esm/client/index.js +15 -1
- package/dist/esm/client/provider.js +53 -2
- package/dist/esm/client/use-active-path.js +74 -0
- package/dist/esm/errors.js +1 -1
- package/dist/esm/next/index.js +95 -15
- package/dist/esm/server/client.js +10 -2
- package/dist/esm/server/handler.js +89 -6
- package/dist/esm/server/index.js +5 -0
- package/dist/esm/server/resources/analytics.js +62 -0
- package/dist/esm/server/resources/identity.js +1 -1
- package/dist/esm/server/resources/integrations.js +62 -0
- package/dist/esm/server/resources/sessions.js +1 -1
- package/dist/esm/server/webhooks.js +123 -0
- package/dist/esm/this-entry-is-server-only.js +30 -0
- package/dist/theme.css +28 -0
- package/dist/types/cli/doctor.d.ts +23 -0
- package/dist/types/cli/init.d.ts +2 -3
- package/dist/types/client/components/access-gate.d.ts +79 -0
- package/dist/types/client/components/app-shell.d.ts +115 -0
- package/dist/types/client/components/integrations-modal.d.ts +21 -0
- package/dist/types/client/components/motion.d.ts +22 -0
- package/dist/types/client/components/nav.d.ts +110 -0
- package/dist/types/client/components/side-nav.d.ts +31 -0
- package/dist/types/client/components/surfaces.d.ts +51 -0
- package/dist/types/client/index.d.ts +12 -1
- package/dist/types/client/provider.d.ts +38 -3
- package/dist/types/client/use-active-path.d.ts +8 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/next/index.d.ts +40 -0
- package/dist/types/server/client.d.ts +8 -2
- package/dist/types/server/index.d.ts +17 -2
- package/dist/types/server/resources/analytics.d.ts +31 -0
- package/dist/types/server/resources/identity.d.ts +12 -2
- package/dist/types/server/resources/integrations.d.ts +40 -0
- package/dist/types/server/webhooks.d.ts +67 -0
- package/dist/types/this-entry-is-server-only.d.ts +1 -0
- package/dist/types/types.d.ts +182 -1
- package/package.json +22 -4
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type TransportOptions } from "../http.js";
|
|
2
|
+
import type { DisconnectIntegrationResponse, ExecuteIntegrationActionResponse, InitiateIntegrationConnectionResponse, IntegrationsListResponse } from "../../types.js";
|
|
3
|
+
export interface ExecuteIntegrationActionInput {
|
|
4
|
+
toolkitSlug: string;
|
|
5
|
+
actionSlug: string;
|
|
6
|
+
/** Passed through to Composio verbatim - its shape is defined by the toolkit's own action schema, which Connect does not model. */
|
|
7
|
+
params?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Composio-hosted third-party connections (Google Calendar, Slack,
|
|
11
|
+
* Twitter/X, ...) an organization has connected. Connect proxies every call
|
|
12
|
+
* here - your service never sees or holds the underlying OAuth token, which
|
|
13
|
+
* stays with Composio.
|
|
14
|
+
*/
|
|
15
|
+
export declare class IntegrationsResource {
|
|
16
|
+
private readonly transport;
|
|
17
|
+
constructor(transport: TransportOptions);
|
|
18
|
+
/** Enabled toolkits and this organization's connection status for each. */
|
|
19
|
+
list(organizationId: string): Promise<IntegrationsListResponse["toolkits"]>;
|
|
20
|
+
/**
|
|
21
|
+
* Starts a Composio-hosted connection for one toolkit. The returned
|
|
22
|
+
* `redirectUrl` is where the browser completes the provider's OAuth
|
|
23
|
+
* screen, then Composio bounces it back to `returnUrl`.
|
|
24
|
+
*
|
|
25
|
+
* **The connection is not active when this returns.** Treat the toolkit
|
|
26
|
+
* as `pending` until a later `list()` call reports `active` - only
|
|
27
|
+
* Connect's own webhook from Composio confirms that, never the redirect
|
|
28
|
+
* itself. Reconnecting a disconnected/failed toolkit calls this same
|
|
29
|
+
* method - there is no separate reconnect.
|
|
30
|
+
*
|
|
31
|
+
* Meant to be called on behalf of a signed-in org admin (this is what the
|
|
32
|
+
* bridge's fixed `POST /integrations/connect` route does), not as a bare
|
|
33
|
+
* background action with no admin present to complete the OAuth screen.
|
|
34
|
+
*/
|
|
35
|
+
initiateConnect(organizationId: string, toolkitSlug: string, returnUrl: string): Promise<InitiateIntegrationConnectionResponse>;
|
|
36
|
+
/** Idempotent - disconnecting a toolkit that was never connected, or is already disconnected, is a success. */
|
|
37
|
+
disconnect(organizationId: string, toolkitSlug: string): Promise<DisconnectIntegrationResponse>;
|
|
38
|
+
/** Calls a Composio action against this organization's connected account for the named toolkit. */
|
|
39
|
+
execute(organizationId: string, input: ExecuteIntegrationActionInput): Promise<ExecuteIntegrationActionResponse>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ConnectWebhookEnvelope, ConnectWebhookEventMap, ConnectWebhookEventType } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Verifies a `Connect-Signature` header against the raw request body.
|
|
4
|
+
*
|
|
5
|
+
* Exported on its own for anyone wiring this into a framework
|
|
6
|
+
* `createConnectWebhookHandler` does not cover. The **raw** body matters:
|
|
7
|
+
* verify before parsing, and never re-serialise - `JSON.stringify(await
|
|
8
|
+
* req.json())` produces a different string whenever key order or number
|
|
9
|
+
* formatting differs, and the signature will not match.
|
|
10
|
+
*
|
|
11
|
+
* Returns a boolean and never explains which check failed. Reporting "bad
|
|
12
|
+
* timestamp" separately from "bad signature" tells whoever is probing which
|
|
13
|
+
* half of a forgery to keep working on.
|
|
14
|
+
*/
|
|
15
|
+
export declare function verifyConnectWebhook(rawBody: string, signatureHeader: string | null | undefined, secret: string, now?: Date): boolean;
|
|
16
|
+
/** One handler per event type. Every one is optional; unhandled types are acknowledged and ignored. */
|
|
17
|
+
export type ConnectWebhookHandlers = {
|
|
18
|
+
[K in ConnectWebhookEventType]?: (data: ConnectWebhookEventMap[K], envelope: ConnectWebhookEnvelope<K>) => void | Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
export interface ConnectWebhookHandlerOptions {
|
|
21
|
+
/** The endpoint's signing secret, from Console. Keep it in an environment variable. */
|
|
22
|
+
secret: string;
|
|
23
|
+
on: ConnectWebhookHandlers;
|
|
24
|
+
/**
|
|
25
|
+
* Called when a handler throws. Return nothing to have the delivery
|
|
26
|
+
* retried (Connect responds to a 5xx by retrying for about 33 hours);
|
|
27
|
+
* the default logs and rethrows, which produces exactly that.
|
|
28
|
+
*/
|
|
29
|
+
onError?: (error: unknown, envelope: ConnectWebhookEnvelope) => void | Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A ready-made `POST` route for Connect's webhooks.
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* export const POST = createConnectWebhookHandler({
|
|
36
|
+
* secret: process.env.CONNECT_WEBHOOK_SECRET!,
|
|
37
|
+
* on: {
|
|
38
|
+
* "organization.deletion_scheduled": ({ organizationId, purgeAfter }) =>
|
|
39
|
+
* freeze(organizationId, purgeAfter),
|
|
40
|
+
* "organization.deletion_cancelled": ({ organizationId }) => unfreeze(organizationId),
|
|
41
|
+
* "organization.deleted": ({ organizationId }) => purge(organizationId),
|
|
42
|
+
* },
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Three behaviours worth knowing, because each of them is a decision rather
|
|
47
|
+
* than an accident:
|
|
48
|
+
*
|
|
49
|
+
* **An unverified request gets a 401 and nothing else happens.** No parsing,
|
|
50
|
+
* no logging of the body, no handler. The endpoint is a public URL, so
|
|
51
|
+
* anything reachable before the signature check is reachable by anyone.
|
|
52
|
+
*
|
|
53
|
+
* **An unhandled event type is a 200.** Connect adds event types over time,
|
|
54
|
+
* and answering 4xx to one you have not written code for would dead-letter
|
|
55
|
+
* it immediately and, after enough of them, disable your endpoint. Silence
|
|
56
|
+
* is the correct answer to "we do not care about this one".
|
|
57
|
+
*
|
|
58
|
+
* **A throwing handler produces a 500, on purpose.** That is what makes
|
|
59
|
+
* Connect retry. Swallowing the error would acknowledge an event you failed
|
|
60
|
+
* to process, and the retry ladder is the only thing standing between a
|
|
61
|
+
* transient failure and a permanently missed deletion.
|
|
62
|
+
*
|
|
63
|
+
* Delivery is at-least-once and unordered. Dedupe on `envelope.id`, and
|
|
64
|
+
* reconcile against the readiness endpoint rather than trusting arrival
|
|
65
|
+
* order - the pull channel is authoritative, this one is fast.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createConnectWebhookHandler(options: ConnectWebhookHandlerOptions): (request: Request) => Promise<Response>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -16,6 +16,15 @@ export interface ConnectUser {
|
|
|
16
16
|
email: string | null;
|
|
17
17
|
emailVerified: boolean;
|
|
18
18
|
displayName: string | null;
|
|
19
|
+
/**
|
|
20
|
+
* The member's profile picture, or `null` when they have not set one.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately nullable rather than a generated placeholder: only you know
|
|
23
|
+
* what your fallback should look like. `<ConnectUserMenu>` renders initials
|
|
24
|
+
* via `<Avatar.Fallback>`, which also covers the URL loading slowly or
|
|
25
|
+
* failing outright - so pair the two rather than branching on `null`.
|
|
26
|
+
*/
|
|
27
|
+
photoUrl: string | null;
|
|
19
28
|
organizationId: string;
|
|
20
29
|
organizationName: string;
|
|
21
30
|
}
|
|
@@ -95,7 +104,7 @@ export interface RolesResponse {
|
|
|
95
104
|
permissionCatalog: ServicePermission[];
|
|
96
105
|
roles: ServiceRoleDefinition[];
|
|
97
106
|
}
|
|
98
|
-
export type ReadinessBlockerCode = "subscription_missing" | "subscription_inactive" | "audience_mismatch" | "verification_required" | "verification_pending" | "verification_rejected" | "verification_expired" | "payment_method_missing" | "seat_limit_reached" | "organization_not_found" | "onboarding_approval_pending" | "onboarding_approval_rejected";
|
|
107
|
+
export type ReadinessBlockerCode = "subscription_missing" | "subscription_inactive" | "audience_mismatch" | "verification_required" | "verification_pending" | "verification_rejected" | "verification_expired" | "payment_method_missing" | "seat_limit_reached" | "organization_not_found" | "onboarding_approval_pending" | "onboarding_approval_rejected" | "organization_suspended" | "payment_retry_pending";
|
|
99
108
|
export interface ReadinessBlocker {
|
|
100
109
|
/**
|
|
101
110
|
* Branch on this. Typed as a union for the codes that exist today, widened
|
|
@@ -108,6 +117,8 @@ export interface ReadinessBlocker {
|
|
|
108
117
|
message: string;
|
|
109
118
|
/** Where in Connect the customer resolves this. `null` when nothing they do helps (e.g. a review in progress). */
|
|
110
119
|
resolveUrl: string | null;
|
|
120
|
+
/** When this blocker resolves itself automatically - currently only set on `payment_retry_pending`, the deadline dunning suspends the subscription. `undefined`/`null` for every other code. */
|
|
121
|
+
graceEndsAt?: string | null;
|
|
111
122
|
}
|
|
112
123
|
export interface ReadinessResponse {
|
|
113
124
|
organizationId: string;
|
|
@@ -432,3 +443,173 @@ export interface RevokeOtherSessionsResponse {
|
|
|
432
443
|
}
|
|
433
444
|
/** Host-controlled - the SDK has no theme provider of its own. See `ConnectUserMenuProps.theme`. */
|
|
434
445
|
export type ThemeMode = "light" | "dark" | "system";
|
|
446
|
+
/**
|
|
447
|
+
* `not_connected` never travels over the wire as a persisted state - it's
|
|
448
|
+
* what `ListOrganizationIntegrationsUseCase` reports for a toolkit this
|
|
449
|
+
* organization has no `IntegrationConnection` record for at all.
|
|
450
|
+
*/
|
|
451
|
+
export type IntegrationConnectionStatus = "not_connected" | "pending" | "active" | "failed" | "disconnected" | "expired";
|
|
452
|
+
/**
|
|
453
|
+
* A Composio-hosted third-party toolkit (Google Calendar, Slack, Twitter/X,
|
|
454
|
+
* ...) this organization can see - only ever one a platform admin enabled in
|
|
455
|
+
* Connect's own Console, joined with this org's own connection status.
|
|
456
|
+
* Connections are org-shared: one covers every member, the way a Slack app
|
|
457
|
+
* install is shared rather than per-user.
|
|
458
|
+
*/
|
|
459
|
+
export interface IntegrationToolkit {
|
|
460
|
+
slug: string;
|
|
461
|
+
name: string;
|
|
462
|
+
description: string;
|
|
463
|
+
category: string | null;
|
|
464
|
+
logoUrl: string | null;
|
|
465
|
+
status: IntegrationConnectionStatus;
|
|
466
|
+
}
|
|
467
|
+
export interface IntegrationsListResponse {
|
|
468
|
+
toolkits: IntegrationToolkit[];
|
|
469
|
+
}
|
|
470
|
+
/** The connection isn't active yet when this returns - see `IntegrationsResource.initiateConnect`'s doc comment. */
|
|
471
|
+
export interface InitiateIntegrationConnectionResponse {
|
|
472
|
+
/** Send the browser here to complete the provider's OAuth screen. */
|
|
473
|
+
redirectUrl: string;
|
|
474
|
+
connectionId: string;
|
|
475
|
+
}
|
|
476
|
+
export interface DisconnectIntegrationResponse {
|
|
477
|
+
success: true;
|
|
478
|
+
}
|
|
479
|
+
export interface ExecuteIntegrationActionResponse {
|
|
480
|
+
data: unknown;
|
|
481
|
+
successful: boolean;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* The metrics Connect can report for your service.
|
|
485
|
+
*
|
|
486
|
+
* Hand-written here rather than imported from Connect's own registry, like
|
|
487
|
+
* every other wire type in this file, so the published package carries none of
|
|
488
|
+
* Connect's internals. `conformance.test.ts` type-checks these against the
|
|
489
|
+
* server DTOs, so drift fails the build in Connect's repo rather than in a
|
|
490
|
+
* partner's integration.
|
|
491
|
+
*/
|
|
492
|
+
export type ConnectMetric = "usage.events" | "usage.active_users" | "api.requests" | "api.errors" | "billing.mrr_paise" | "billing.active_subscriptions" | "metering.addon_consumed";
|
|
493
|
+
export interface AnalyticsPoint {
|
|
494
|
+
/** `YYYY-MM-DD`, UTC. */
|
|
495
|
+
day: string;
|
|
496
|
+
/**
|
|
497
|
+
* **`null` is not zero.** It means the metric was not measurable that day -
|
|
498
|
+
* `usage.active_users` is a distinct count that only exists after Connect's
|
|
499
|
+
* nightly rollup, so today's is always `null`, as is any future day. Render
|
|
500
|
+
* it as a gap or a dash, never as a zero.
|
|
501
|
+
*/
|
|
502
|
+
value: number | null;
|
|
503
|
+
}
|
|
504
|
+
export interface AnalyticsSeries {
|
|
505
|
+
metric: ConnectMetric;
|
|
506
|
+
points: AnalyticsPoint[];
|
|
507
|
+
/** Sum across measurable days only, or `null` if no day in the range was measurable. */
|
|
508
|
+
total: number | null;
|
|
509
|
+
/** True when at least one day was not measurable - caveat the total when this is set. */
|
|
510
|
+
partial: boolean;
|
|
511
|
+
}
|
|
512
|
+
export interface AnalyticsResponse {
|
|
513
|
+
from: string;
|
|
514
|
+
to: string;
|
|
515
|
+
series: AnalyticsSeries[];
|
|
516
|
+
}
|
|
517
|
+
export interface AnalyticsQuery {
|
|
518
|
+
metrics: ConnectMetric[];
|
|
519
|
+
/** Inclusive `YYYY-MM-DD`, UTC. The range must be shorter than 90 days. */
|
|
520
|
+
from: string;
|
|
521
|
+
to: string;
|
|
522
|
+
}
|
|
523
|
+
/** One event you push into Connect's analytics pipeline. */
|
|
524
|
+
export interface EmitEventInput {
|
|
525
|
+
/**
|
|
526
|
+
* Dot-namespaced and lowercase, e.g. `checkout.completed`. Prefixes Connect
|
|
527
|
+
* emits itself - `api.`, `billing.`, `addon.`, `subscription.`, `connect.` -
|
|
528
|
+
* are rejected, so your events can never inflate a metered number.
|
|
529
|
+
*/
|
|
530
|
+
name: string;
|
|
531
|
+
/** Defaults to now. Clamped server-side to within 48 hours. */
|
|
532
|
+
occurredAt?: string | Date;
|
|
533
|
+
/** Attributes the event to the signed-in user and their organization. */
|
|
534
|
+
sessionToken?: string;
|
|
535
|
+
/** A whole number in the smallest unit of `unit` - paise, bytes, milliseconds. */
|
|
536
|
+
value?: number;
|
|
537
|
+
unit?: string;
|
|
538
|
+
props?: Record<string, unknown>;
|
|
539
|
+
}
|
|
540
|
+
export interface EmitEventsResponse {
|
|
541
|
+
/** False when the call failed outright - see `AnalyticsResource.emit`. */
|
|
542
|
+
delivered: boolean;
|
|
543
|
+
accepted: number;
|
|
544
|
+
attributed: number;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Every event Connect will POST to your webhook endpoint.
|
|
548
|
+
*
|
|
549
|
+
* Additive only - Connect adds event types, never renames one - so a
|
|
550
|
+
* `switch` that does not handle a future type is safe, and
|
|
551
|
+
* `createConnectWebhookHandler` simply ignores anything you have not
|
|
552
|
+
* registered a handler for.
|
|
553
|
+
*/
|
|
554
|
+
export type ConnectWebhookEventType = "organization.deletion_scheduled" | "organization.deletion_cancelled" | "organization.deleted" | "subscription.cancelled";
|
|
555
|
+
/**
|
|
556
|
+
* A workspace's deletion has been confirmed and the grace window is running.
|
|
557
|
+
*
|
|
558
|
+
* Access is *already* denied - readiness reports
|
|
559
|
+
* `organization_pending_deletion` from this moment - so treat this as "stop
|
|
560
|
+
* writing", not "start planning". `purgeAfter` is what makes this event worth
|
|
561
|
+
* having: the customer's data still exists until then, so an export or a
|
|
562
|
+
* wind-down can run on the same clock rather than after everything is gone.
|
|
563
|
+
*/
|
|
564
|
+
export interface OrganizationDeletionScheduledEvent {
|
|
565
|
+
organizationId: string;
|
|
566
|
+
/** ISO-8601. When Connect destroys the workspace. */
|
|
567
|
+
purgeAfter: string;
|
|
568
|
+
requestedBy: "owner" | "platform_admin";
|
|
569
|
+
graceDays: number;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* The deletion was withdrawn and the workspace is live again.
|
|
573
|
+
*
|
|
574
|
+
* **Handle this one.** It is the event integrations forget, and its absence
|
|
575
|
+
* is the worst failure of the set: a service that froze a workspace on
|
|
576
|
+
* `organization.deletion_scheduled` and never unfreezes leaves a paying
|
|
577
|
+
* customer locked out of something that has no idea anything changed.
|
|
578
|
+
*/
|
|
579
|
+
export interface OrganizationDeletionCancelledEvent {
|
|
580
|
+
organizationId: string;
|
|
581
|
+
}
|
|
582
|
+
/** The grace window closed and Connect purged the workspace. Purge your own copy. */
|
|
583
|
+
export interface OrganizationDeletedEvent {
|
|
584
|
+
organizationId: string;
|
|
585
|
+
/** ISO-8601. */
|
|
586
|
+
purgedAt: string;
|
|
587
|
+
}
|
|
588
|
+
/** A subscription ended. Fires on its own, not only as part of a deletion. */
|
|
589
|
+
export interface SubscriptionCancelledEvent {
|
|
590
|
+
organizationId: string;
|
|
591
|
+
subscriptionId: string;
|
|
592
|
+
serviceId: string;
|
|
593
|
+
}
|
|
594
|
+
/** Maps each event type to the shape of its `data`. */
|
|
595
|
+
export interface ConnectWebhookEventMap {
|
|
596
|
+
"organization.deletion_scheduled": OrganizationDeletionScheduledEvent;
|
|
597
|
+
"organization.deletion_cancelled": OrganizationDeletionCancelledEvent;
|
|
598
|
+
"organization.deleted": OrganizationDeletedEvent;
|
|
599
|
+
"subscription.cancelled": SubscriptionCancelledEvent;
|
|
600
|
+
}
|
|
601
|
+
/** The envelope, as it arrives on the wire. */
|
|
602
|
+
export interface ConnectWebhookEnvelope<T extends ConnectWebhookEventType = ConnectWebhookEventType> {
|
|
603
|
+
/**
|
|
604
|
+
* Unique per delivery. **Dedupe on this.** Delivery is at-least-once and
|
|
605
|
+
* unordered: a partner that assumes exactly-once, or assumes order, will
|
|
606
|
+
* eventually be wrong.
|
|
607
|
+
*/
|
|
608
|
+
id: string;
|
|
609
|
+
type: T;
|
|
610
|
+
/** ISO-8601. */
|
|
611
|
+
createdAt: string;
|
|
612
|
+
/** Bumped only for a breaking payload change - never for a new event type. */
|
|
613
|
+
apiVersion: string;
|
|
614
|
+
data: ConnectWebhookEventMap[T];
|
|
615
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmoops/connect-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Official server-side SDK for the CosmoOps Connect platform API - Login with Connect, entitlements, billing and metering.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -15,11 +15,19 @@
|
|
|
15
15
|
},
|
|
16
16
|
"./server": {
|
|
17
17
|
"types": "./dist/types/server/index.d.ts",
|
|
18
|
+
"browser": {
|
|
19
|
+
"import": "./dist/esm/this-entry-is-server-only.js",
|
|
20
|
+
"require": "./dist/cjs/this-entry-is-server-only.js"
|
|
21
|
+
},
|
|
18
22
|
"import": "./dist/esm/server/index.js",
|
|
19
23
|
"require": "./dist/cjs/server/index.js"
|
|
20
24
|
},
|
|
21
25
|
"./next": {
|
|
22
26
|
"types": "./dist/types/next/index.d.ts",
|
|
27
|
+
"browser": {
|
|
28
|
+
"import": "./dist/esm/this-entry-is-server-only.js",
|
|
29
|
+
"require": "./dist/cjs/this-entry-is-server-only.js"
|
|
30
|
+
},
|
|
23
31
|
"import": "./dist/esm/next/index.js",
|
|
24
32
|
"require": "./dist/cjs/next/index.js"
|
|
25
33
|
},
|
|
@@ -39,7 +47,8 @@
|
|
|
39
47
|
"node": ">=18"
|
|
40
48
|
},
|
|
41
49
|
"files": [
|
|
42
|
-
"dist"
|
|
50
|
+
"dist",
|
|
51
|
+
"CHANGELOG.md"
|
|
43
52
|
],
|
|
44
53
|
"keywords": [
|
|
45
54
|
"cosmoops",
|
|
@@ -58,6 +67,8 @@
|
|
|
58
67
|
"verify:pack": "bun run scripts/verify-pack.ts",
|
|
59
68
|
"prepublishOnly": "bun run build && bun run verify:pack",
|
|
60
69
|
"test": "bun test",
|
|
70
|
+
"docs": "typedoc",
|
|
71
|
+
"docs:md": "typedoc --options typedoc.markdown.json",
|
|
61
72
|
"storybook": "storybook dev -p 6106",
|
|
62
73
|
"build:storybook": "storybook build -o storybook-static"
|
|
63
74
|
},
|
|
@@ -72,18 +83,22 @@
|
|
|
72
83
|
"@types/react": "^19",
|
|
73
84
|
"@types/react-dom": "^19",
|
|
74
85
|
"lucide-react": "^0.545.0",
|
|
86
|
+
"motion": "^13.1.1",
|
|
75
87
|
"react": "19.2.8",
|
|
76
88
|
"react-dom": "19.2.8",
|
|
77
89
|
"storybook": "^10.5.10",
|
|
78
90
|
"tailwindcss": "^4.3.3",
|
|
91
|
+
"typedoc": "^0.28.20",
|
|
92
|
+
"typedoc-plugin-markdown": "^4.12.0",
|
|
79
93
|
"typescript": "^5",
|
|
80
94
|
"vite": "^8.2.2"
|
|
81
95
|
},
|
|
82
96
|
"peerDependencies": {
|
|
83
97
|
"@heroui/react": ">=3.2.0",
|
|
84
98
|
"lucide-react": ">=0.400.0",
|
|
85
|
-
"
|
|
86
|
-
"react
|
|
99
|
+
"motion": ">=12",
|
|
100
|
+
"react": ">=19",
|
|
101
|
+
"react-dom": ">=19"
|
|
87
102
|
},
|
|
88
103
|
"peerDependenciesMeta": {
|
|
89
104
|
"@heroui/react": {
|
|
@@ -92,6 +107,9 @@
|
|
|
92
107
|
"lucide-react": {
|
|
93
108
|
"optional": true
|
|
94
109
|
},
|
|
110
|
+
"motion": {
|
|
111
|
+
"optional": true
|
|
112
|
+
},
|
|
95
113
|
"react": {
|
|
96
114
|
"optional": true
|
|
97
115
|
},
|