@cosmoops/connect-sdk 0.38.0 → 0.40.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 (35) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/cjs/client/components/availability-form.js +52 -24
  3. package/dist/cjs/client/components/create-workspace-form.js +66 -0
  4. package/dist/cjs/client/components/event-type-form.js +99 -25
  5. package/dist/cjs/client/components/workspace-switcher.js +42 -9
  6. package/dist/cjs/client/index.js +11 -1
  7. package/dist/cjs/client/use-scheduling.js +37 -0
  8. package/dist/cjs/client/use-workspaces.js +41 -0
  9. package/dist/cjs/server/client.js +1 -1
  10. package/dist/cjs/server/handler.js +103 -2
  11. package/dist/cjs/server/resources/scheduling.js +67 -0
  12. package/dist/cjs/server/resources/workspaces.js +30 -11
  13. package/dist/esm/client/components/availability-form.js +53 -25
  14. package/dist/esm/client/components/create-workspace-form.js +63 -0
  15. package/dist/esm/client/components/event-type-form.js +100 -26
  16. package/dist/esm/client/components/workspace-switcher.js +42 -9
  17. package/dist/esm/client/index.js +6 -1
  18. package/dist/esm/client/use-scheduling.js +34 -0
  19. package/dist/esm/client/use-workspaces.js +38 -0
  20. package/dist/esm/server/client.js +1 -1
  21. package/dist/esm/server/handler.js +103 -2
  22. package/dist/esm/server/resources/scheduling.js +67 -0
  23. package/dist/esm/server/resources/workspaces.js +30 -11
  24. package/dist/types/client/components/availability-form.d.ts +23 -12
  25. package/dist/types/client/components/create-workspace-form.d.ts +32 -0
  26. package/dist/types/client/components/event-type-form.d.ts +30 -8
  27. package/dist/types/client/components/workspace-switcher.d.ts +9 -9
  28. package/dist/types/client/index.d.ts +5 -1
  29. package/dist/types/client/use-scheduling.d.ts +46 -2
  30. package/dist/types/client/use-workspaces.d.ts +27 -0
  31. package/dist/types/server/client.d.ts +1 -1
  32. package/dist/types/server/resources/scheduling.d.ts +66 -2
  33. package/dist/types/server/resources/workspaces.d.ts +28 -0
  34. package/dist/types/types.d.ts +33 -0
  35. package/package.json +1 -1
@@ -1,16 +1,5 @@
1
1
  import { actingAs } from "./acting-as.js";
2
2
  import { request } from "../http.js";
3
- /**
4
- * Which workspaces the signed-in user belongs to, moving between them, who
5
- * else is on the team, and inviting or granting access to your application.
6
- *
7
- * **Every call here needs `asUser`** - the signed-in user's opaque
8
- * `sessionToken`. There is no application-wide form of any of these: they take
9
- * no `userId` and no `workspaceId`, and resolve both from the token. That is
10
- * what makes the whole module safe to reach from a browser through
11
- * `createConnectHandler`, and it is why a partner cannot enumerate another
12
- * tenant's team with their own API key.
13
- */
14
3
  export class WorkspacesResource {
15
4
  transport;
16
5
  constructor(transport) {
@@ -31,6 +20,36 @@ export class WorkspacesResource {
31
20
  });
32
21
  return result.workspaces;
33
22
  }
23
+ /**
24
+ * Opens another workspace under the tenant the signed-in user already
25
+ * owns - a branch office, a second business unit.
26
+ *
27
+ * Every guard `CreateWorkspaceUseCase` enforces still applies: only the
28
+ * tenant's owner may call this, `type: "business"` still needs a non-free
29
+ * email domain, and the tenant's plan still decides whether it may hold
30
+ * another workspace at all - a `PreconditionError` surfaces as a thrown
31
+ * `ConnectError` with a message written to be shown ("Your current plan
32
+ * covers a single workspace...", "You've used all 3 of the workspaces
33
+ * your plans include..."). There is no `tenantId` parameter: the caller
34
+ * names no tenant, same as every other method on this resource names no
35
+ * workspace.
36
+ *
37
+ * `isActive`/`subscribed` on the result are always `false` - this does not
38
+ * switch the session, and the new workspace has no subscription yet. Chain
39
+ * `switch({workspaceId: result.workspaceId})` to move into it, but only
40
+ * when `result.inAudience` - a workspace outside this application's
41
+ * audience is refused by `switch` the same way `selectable()` in
42
+ * `<ConnectWorkspaceSwitcher>` already treats it.
43
+ */
44
+ async create(input, options) {
45
+ const result = await request(this.transport, {
46
+ method: "POST",
47
+ path: "/workspaces",
48
+ headers: actingAs(options.asUser),
49
+ json: input,
50
+ });
51
+ return result.workspace;
52
+ }
34
53
  /**
35
54
  * Moves this session to another workspace, returning a **new session
36
55
  * token**. The one you passed is revoked.
@@ -2,21 +2,32 @@ import type { AvailabilitySchedule } from "../../types.js";
2
2
  export interface ConnectAvailabilityFormModalProps {
3
3
  isOpen: boolean;
4
4
  onOpenChange: (isOpen: boolean) => void;
5
- /** Called once the schedule is created, before the modal closes. */
6
- onCreated?: (schedule: AvailabilitySchedule) => void;
5
+ /**
6
+ * `null` (or omitted) creates a new schedule. A row id from
7
+ * `useAvailabilitySchedules` edits that one instead - name and hours
8
+ * prefill from it.
9
+ */
10
+ scheduleId?: string | null;
11
+ /** Called once the schedule is created or saved, before the modal closes. */
12
+ onSaved?: (schedule: AvailabilitySchedule) => void;
7
13
  }
8
14
  /**
9
- * Gives a workspace its first working hours, from inside a host application
10
- * rather than a link-out to Connect.
15
+ * Creates or edits a workspace's working hours, from inside a host
16
+ * application rather than a link-out to Connect.
11
17
  *
12
18
  * Deliberately narrower than Connect's own Calendar settings form: one
13
- * interval per day (no split shifts), no date overrides, and the timezone
14
- * defaults to the browser's own rather than asking. This is a first-run
15
- * setup step, not a second copy of the Console editor - "Manage in Connect"
16
- * is still where the rest of what a schedule can do lives.
19
+ * interval per day (no split shifts), no date overrides, and the timezone is
20
+ * set once at creation (from the browser's own) and shown but not editable
21
+ * here afterwards. This is a first-party setup-and-edit surface, not a
22
+ * second copy of the Console editor - "Manage in Connect" is still where the
23
+ * rest of what a schedule can do lives.
17
24
  *
18
- * **Not optimistic.** `useCreateAvailabilitySchedule` settles the write
19
- * against the server before this closes, the same posture every write in
20
- * this package takes - see `ConnectBookingDialog`.
25
+ * **Not optimistic.** The write settles against the server before this
26
+ * closes, the same posture every write in this package takes - see
27
+ * `ConnectBookingDialog`.
28
+ *
29
+ * This outer component only decides whether the row to edit has loaded yet;
30
+ * the form itself is `ScheduleFields` below, mounted with
31
+ * `key={editing?.id}` - see that component's own doc comment for why.
21
32
  */
22
- export declare function ConnectAvailabilityFormModal({ isOpen, onOpenChange, onCreated, }: Readonly<ConnectAvailabilityFormModalProps>): import("react").JSX.Element;
33
+ export declare function ConnectAvailabilityFormModal({ isOpen, onOpenChange, scheduleId, onSaved, }: Readonly<ConnectAvailabilityFormModalProps>): import("react").JSX.Element;
@@ -0,0 +1,32 @@
1
+ import type { UserWorkspace } from "../../types.js";
2
+ export interface ConnectCreateWorkspaceModalProps {
3
+ isOpen: boolean;
4
+ onOpenChange: (isOpen: boolean) => void;
5
+ /** Called once the workspace is created, before the modal closes. */
6
+ onCreated?: (workspace: UserWorkspace) => void;
7
+ }
8
+ /**
9
+ * Opens another workspace under the signed-in user's own tenant - a branch
10
+ * office, a second business unit - from inside a host application rather
11
+ * than a link-out to Connect.
12
+ *
13
+ * **Only the tenant's owner can use this successfully.** `CreateWorkspaceUseCase`
14
+ * refuses anyone who merely belongs to a colleague's tenant, with a message
15
+ * naming that - someone who wants a workspace of their own uses a personal
16
+ * account instead.
17
+ *
18
+ * **The tenant's plan decides how many workspaces it may hold, and this does
19
+ * not pre-check it.** There is no capacity read to show ahead of time - the
20
+ * same posture Connect's own "Create workspace" button takes - so a refusal
21
+ * surfaces here exactly as the server wrote it ("Your current plan covers a
22
+ * single workspace - subscribe to a plan that includes additional workspaces
23
+ * to open another.", or "You've used all 3 of the workspaces your plans
24
+ * include. Upgrade a plan or delete a workspace to open another.").
25
+ *
26
+ * **Does not switch the session to the new workspace.** Creating one never
27
+ * does, on Connect's own screen either - see `useCreateWorkspace`'s doc
28
+ * comment for how to chain a switch once you have the result, and guard that
29
+ * chain on `inAudience` the same way `<ConnectWorkspaceSwitcher>` already
30
+ * does for every other row.
31
+ */
32
+ export declare function ConnectCreateWorkspaceModal({ isOpen, onOpenChange, onCreated, }: Readonly<ConnectCreateWorkspaceModalProps>): import("react").JSX.Element;
@@ -1,22 +1,44 @@
1
- import type { BookableEventType } from "../../types.js";
1
+ import type { ManageableEventType } from "../../types.js";
2
2
  export interface ConnectEventTypeFormModalProps {
3
3
  isOpen: boolean;
4
4
  onOpenChange: (isOpen: boolean) => void;
5
- /** Called once the appointment type is created, before the modal closes. */
6
- onCreated?: (eventType: BookableEventType) => void;
5
+ /**
6
+ * `null` (or omitted) creates a new appointment type. A row id from
7
+ * `useManageableEventTypes` edits that one instead - name, duration,
8
+ * buffers, host, schedule, location and `publicBookingEnabled` all prefill
9
+ * from it.
10
+ */
11
+ eventTypeId?: string | null;
12
+ /** Called once the appointment type is created or saved, before the modal closes. */
13
+ onSaved?: (eventType: ManageableEventType) => void;
7
14
  }
8
15
  /**
9
- * Creates the first thing a workspace can be booked for, from inside a host
10
- * application rather than a link-out to Connect.
16
+ * Creates or edits an appointment type, from inside a host application
17
+ * rather than a link-out to Connect.
11
18
  *
12
19
  * **Needs a schedule to exist first** - the picker reads `useAvailabilitySchedules`
13
20
  * and renders "Set up availability first" with nothing to submit if none
14
21
  * exists yet. Pair this with `ConnectAvailabilityFormModal` in a setup flow
15
22
  * rather than assuming one.
16
23
  *
24
+ * **That gate waits for the read, and the order matters.** Both bridge reads
25
+ * answer `[]` while they are in flight, so testing `schedules.length === 0`
26
+ * first showed "Set up availability first" to everybody who opened this -
27
+ * including, for a second or two, somebody pressing Edit on an appointment
28
+ * type that provably *has* a schedule. A load state wearing an empty state's
29
+ * words is worse than a spinner: it reads as a verdict, and on a slow
30
+ * connection it is the only thing the modal ever says. A failed read is named
31
+ * as a failure for the same reason - it is not the same fact as "none exist".
32
+ *
17
33
  * **Host is a specific member, never a team.** There is no groups read in
18
34
  * this bridge, so a round-robin team host stays a Console-only capability -
19
- * defaults to whoever is signed in, with an optional picker from the
20
- * workspace's own roster.
35
+ * defaults to whoever is signed in on create, with an optional picker from
36
+ * the workspace's own roster. **Editing a group-hosted row is refused
37
+ * inline** - the modal shows a notice instead of a form, because this
38
+ * surface cannot represent (and so cannot safely resend) a team host.
39
+ *
40
+ * This outer component only decides *which* message or form to show; the
41
+ * form itself is `EventTypeFields` below, mounted with `key={editing?.id}` -
42
+ * see that component's own doc comment for why.
21
43
  */
22
- export declare function ConnectEventTypeFormModal({ isOpen, onOpenChange, onCreated, }: Readonly<ConnectEventTypeFormModalProps>): import("react").JSX.Element;
44
+ export declare function ConnectEventTypeFormModal({ isOpen, onOpenChange, eventTypeId, onSaved, }: Readonly<ConnectEventTypeFormModalProps>): import("react").JSX.Element;
@@ -21,12 +21,12 @@ export interface ConnectWorkspaceSwitcherProps {
21
21
  * every other host: an account with one workspace sees nothing, because a
22
22
  * switcher offering one option teaches it nothing. Pass `true` on an
23
23
  * application that wants a single-workspace account to be able to
24
- * discover - and start - creating a second one without leaving its own
25
- * chrome. There is deliberately no `workspaces.create()` on the SDK:
26
- * creating a workspace is Connect's job, tied to KYC/KYB and a billing
27
- * profile, not something an API key should be able to trigger - so turning
28
- * this on also adds a "Create workspace" row that opens Connect, rather
29
- * than pretending the switcher can do it itself.
24
+ * discover - and open - a second one without leaving its own chrome. Turning
25
+ * this on adds a "Create workspace" row that opens
26
+ * `<ConnectCreateWorkspaceModal>` inline: name, individual-or-business, and
27
+ * the tenant's own plan decides whether another workspace is allowed at
28
+ * all - the same guards Connect's own "Create workspace" button runs
29
+ * through, surfaced as the server wrote them rather than pre-checked here.
30
30
  */
31
31
  alwaysShow?: boolean;
32
32
  }
@@ -44,9 +44,9 @@ export interface ConnectWorkspaceSwitcherProps {
44
44
  * a workspace is *created*, so hiding it at one workspace would guarantee
45
45
  * nobody ever reached two. `alwaysShow` is the escape hatch for a partner
46
46
  * application that wants that same discoverability without becoming Connect:
47
- * it keeps the dropdown open below two workspaces and adds a row that sends
48
- * the member to Connect to actually create one, since there is nothing here
49
- * that can.
47
+ * it keeps the dropdown open below two workspaces and adds a row that opens
48
+ * `<ConnectCreateWorkspaceModal>` inline, auto-switching into the result when
49
+ * that is possible - see `handleCreated` below.
50
50
  *
51
51
  * **Authorization is the data, not a prop.** The list comes from the caller's
52
52
  * own session (`GET /workspaces` takes no user id), so a workspace the user
@@ -102,6 +102,10 @@ export type { PlanAction, PlanTier, ComparablePlan } from "./components/plan-pri
102
102
  export { ConnectWorkspaceSwitcher } from "./components/workspace-switcher.js";
103
103
  export type { ConnectWorkspaceSwitcherProps } from "./components/workspace-switcher.js";
104
104
  export { useConnectWorkspaces, useConnectWorkspaceMembers } from "./provider.js";
105
+ export { ConnectCreateWorkspaceModal } from "./components/create-workspace-form.js";
106
+ export type { ConnectCreateWorkspaceModalProps } from "./components/create-workspace-form.js";
107
+ export { useCreateWorkspace } from "./use-workspaces.js";
108
+ export type { WorkspaceActionsState } from "./use-workspaces.js";
105
109
  export { ConnectBookingCalendar } from "./components/booking-calendar.js";
106
110
  export type { ConnectBookingCalendarProps } from "./components/booking-calendar.js";
107
111
  export { ConnectBookingDialog, ConnectBookingDetail } from "./components/booking-dialogs.js";
@@ -109,5 +113,5 @@ export { ConnectAvailabilityFormModal } from "./components/availability-form.js"
109
113
  export type { ConnectAvailabilityFormModalProps } from "./components/availability-form.js";
110
114
  export { ConnectEventTypeFormModal } from "./components/event-type-form.js";
111
115
  export type { ConnectEventTypeFormModalProps } from "./components/event-type-form.js";
112
- export { useBookableEventTypes, useAvailabilitySchedules, useCreateAvailabilitySchedule, useCreateEventType, useAvailableSlots, useBookings, useBookingActions, type SlotQuery, type BookingsQuery, } from "./use-scheduling.js";
116
+ export { useBookableEventTypes, useAvailabilitySchedules, useCreateAvailabilitySchedule, useUpdateAvailabilitySchedule, useManageableEventTypes, useCreateEventType, useUpdateEventType, useAvailableSlots, useBookings, useBookingActions, type SlotQuery, type BookingsQuery, } from "./use-scheduling.js";
113
117
  export { layoutBookings, dayColumns, zonedInstant, type GridWindow, type PositionedBooking, } from "./components/booking-grid.js";
@@ -1,4 +1,4 @@
1
- import type { AvailabilitySchedule, BookableEventType, Booking, BookingAttendee, WeeklyHours } from "../types.js";
1
+ import type { AvailabilitySchedule, BookableEventType, Booking, BookingAttendee, ManageableEventType, WeeklyHours } from "../types.js";
2
2
  /**
3
3
  * The bridge's scheduling surface, as hooks.
4
4
  *
@@ -25,6 +25,18 @@ export declare function useAvailabilitySchedules(): {
25
25
  isLoading: boolean;
26
26
  error: string | null;
27
27
  };
28
+ /**
29
+ * The richer read `ConnectEventTypeFormModal`'s edit mode needs - everything
30
+ * `useBookableEventTypes`'s booking catalogue deliberately withholds. See
31
+ * the bridge route's own doc comment for why this is a separate read rather
32
+ * than a wider response on that one. Includes inactive rows.
33
+ */
34
+ export declare function useManageableEventTypes(): {
35
+ eventTypes: ManageableEventType[];
36
+ isLoading: boolean;
37
+ error: string | null;
38
+ refetch: () => void;
39
+ };
28
40
  /**
29
41
  * Gives a workspace its first working hours.
30
42
  *
@@ -39,6 +51,15 @@ export declare function useCreateAvailabilitySchedule(): BookingActionsState & {
39
51
  weeklyHours: WeeklyHours;
40
52
  }): Promise<AvailabilitySchedule | null>;
41
53
  };
54
+ /** Edits an existing availability schedule. Every field optional - send only what changed. */
55
+ export declare function useUpdateAvailabilitySchedule(): BookingActionsState & {
56
+ updateSchedule(input: {
57
+ scheduleId: string;
58
+ name?: string;
59
+ timezone?: string;
60
+ weeklyHours?: WeeklyHours;
61
+ }): Promise<AvailabilitySchedule | null>;
62
+ };
42
63
  /**
43
64
  * Creates the first thing a workspace can be booked for.
44
65
  *
@@ -60,7 +81,30 @@ export declare function useCreateEventType(): BookingActionsState & {
60
81
  value?: string | null;
61
82
  };
62
83
  publicBookingEnabled?: boolean;
63
- }): Promise<BookableEventType | null>;
84
+ }): Promise<ManageableEventType | null>;
85
+ };
86
+ /**
87
+ * Edits an existing appointment type. Every field optional - send only what
88
+ * changed. `hostMemberId` omitted leaves the host untouched, including a
89
+ * *group* host this surface cannot represent.
90
+ */
91
+ export declare function useUpdateEventType(): BookingActionsState & {
92
+ updateEventType(input: {
93
+ eventTypeId: string;
94
+ name?: string;
95
+ description?: string | null;
96
+ durationMinutes?: number;
97
+ bufferBeforeMinutes?: number;
98
+ bufferAfterMinutes?: number;
99
+ hostMemberId?: string;
100
+ scheduleId?: string;
101
+ location?: {
102
+ kind: "phone" | "address" | "link";
103
+ value?: string | null;
104
+ };
105
+ publicBookingEnabled?: boolean;
106
+ active?: boolean;
107
+ }): Promise<ManageableEventType | null>;
64
108
  };
65
109
  export interface SlotQuery {
66
110
  eventTypeId: string;
@@ -0,0 +1,27 @@
1
+ import type { UserWorkspace } from "../types.js";
2
+ export interface WorkspaceActionsState {
3
+ isPending: boolean;
4
+ /** The last refusal, written to be shown to the person who clicked - see `CreateWorkspaceUseCase`. */
5
+ error: string | null;
6
+ clearError(): void;
7
+ }
8
+ /**
9
+ * Opens another workspace under the tenant the signed-in user already owns.
10
+ *
11
+ * **Not optimistic**, same posture as every write in `use-scheduling.ts`:
12
+ * whether the tenant's plan still has room for another workspace is a
13
+ * question only the server can answer, and a modal that closes before that
14
+ * answer comes back is the lie a two-phase write exists to avoid.
15
+ *
16
+ * The result is a `UserWorkspace` row with `isActive`/`subscribed` both
17
+ * `false` - creating does not switch the session to it, and the workspace has
18
+ * no subscription yet. Pair with `<ConnectWorkspaceSwitcher>`'s own
19
+ * `mutateResource("/workspaces/switch", ...)` call to move into it, guarded
20
+ * on `inAudience` the same way that component's `selectable()` already is.
21
+ */
22
+ export declare function useCreateWorkspace(): WorkspaceActionsState & {
23
+ createWorkspace(input: {
24
+ name: string;
25
+ type: "individual" | "business";
26
+ }): Promise<UserWorkspace | null>;
27
+ };
@@ -138,4 +138,4 @@ export declare class ConnectClient {
138
138
  constructor(options: ConnectClientOptions);
139
139
  }
140
140
  /** Kept in step with `package.json` by `sdk.test.ts`. */
141
- export declare const SDK_VERSION = "0.38.0";
141
+ export declare const SDK_VERSION = "0.40.0";
@@ -1,5 +1,5 @@
1
1
  import { type TransportOptions } from "../http.js";
2
- import type { AvailabilitySchedule, BookableEventType, Booking, RescheduledBooking, BookingAttendee, BookingSlots, BookingStatus, ListBookingsPage, WeeklyHours } from "../../types.js";
2
+ import type { AvailabilitySchedule, BookableEventType, Booking, ManageableEventType, RescheduledBooking, BookingAttendee, BookingSlots, BookingStatus, ListBookingsPage, WeeklyHours } from "../../types.js";
3
3
  /**
4
4
  * Present on every method here.
5
5
  *
@@ -98,6 +98,42 @@ export interface CreateEventTypeInput extends ActingAsOption {
98
98
  /** Off by default - most appointment types are booked by your integration or a member, not the public. */
99
99
  publicBookingEnabled?: boolean;
100
100
  }
101
+ /**
102
+ * What `updateSchedule` takes. Every field optional - send only what changed.
103
+ * `ownerMemberId` and date overrides are not settable from this surface at
104
+ * all, so an edit can never touch them.
105
+ */
106
+ export interface UpdateScheduleInput extends ActingAsOption {
107
+ workspaceId: string;
108
+ scheduleId: string;
109
+ name?: string;
110
+ timezone?: string;
111
+ weeklyHours?: WeeklyHours;
112
+ }
113
+ /**
114
+ * What `updateEventType` takes. Every field optional - send only what
115
+ * changed. `hostMemberId` omitted leaves the host untouched, including a
116
+ * *group* host this surface cannot represent; sending one always rewrites to
117
+ * a member host, by design.
118
+ */
119
+ export interface UpdateEventTypeInput extends ActingAsOption {
120
+ workspaceId: string;
121
+ eventTypeId: string;
122
+ name?: string;
123
+ description?: string | null;
124
+ durationMinutes?: number;
125
+ bufferBeforeMinutes?: number;
126
+ bufferAfterMinutes?: number;
127
+ hostMemberId?: string;
128
+ scheduleId?: string;
129
+ location?: {
130
+ kind: "phone" | "address" | "link";
131
+ value?: string | null;
132
+ };
133
+ publicBookingEnabled?: boolean;
134
+ /** Take an appointment type out of (or back into) service. */
135
+ active?: boolean;
136
+ }
101
137
  export interface CreateBookingInput extends ActingAsOption {
102
138
  workspaceId: string;
103
139
  eventTypeId: string;
@@ -152,8 +188,36 @@ export declare class SchedulingResource {
152
188
  * Needs a schedule - create or pick one with `listSchedules`/`createSchedule`
153
189
  * first. The slug for a future public booking link is derived from `name`
154
190
  * server-side; you cannot choose one.
191
+ *
192
+ * Answers the richer *manageable* shape, not `BookableEventType` - you just
193
+ * created this row and are about to manage it, not book against it.
194
+ */
195
+ createEventType(input: CreateEventTypeInput): Promise<ManageableEventType>;
196
+ /**
197
+ * The richer read `createEventType`/`updateEventType`'s edit mode needs -
198
+ * everything `listEventTypes`'s booking catalogue deliberately withholds,
199
+ * because this is the opposite audience: a member managing their own
200
+ * calendar, not a widget rendering someone else's. Includes inactive rows,
201
+ * since an edit screen is exactly where one gets reactivated.
202
+ */
203
+ listManageableEventTypes(workspaceId: string, options?: ActingAsOption): Promise<ManageableEventType[]>;
204
+ /**
205
+ * Edits an existing availability schedule.
206
+ *
207
+ * Narrower than what the workspace's own Calendar settings can do, the
208
+ * same way `createSchedule` is: `ownerMemberId` and date overrides stay
209
+ * untouched, since this surface never sets either.
210
+ */
211
+ updateSchedule(input: UpdateScheduleInput): Promise<AvailabilitySchedule>;
212
+ /**
213
+ * Edits an existing appointment type.
214
+ *
215
+ * `hostMemberId` omitted leaves the host untouched, including a *group*
216
+ * host this surface cannot represent - so an edit that says nothing about
217
+ * the host can never accidentally overwrite a team assignment made in
218
+ * Connect.
155
219
  */
156
- createEventType(input: CreateEventTypeInput): Promise<BookableEventType>;
220
+ updateEventType(input: UpdateEventTypeInput): Promise<ManageableEventType>;
157
221
  /**
158
222
  * Free times for one appointment type over one window.
159
223
  *
@@ -11,6 +11,10 @@ import type { ConnectInvitation, ConnectMemberAccess, ConnectMemberAccessResult,
11
11
  * `createConnectHandler`, and it is why a partner cannot enumerate another
12
12
  * tenant's team with their own API key.
13
13
  */
14
+ export interface CreateUserWorkspaceInput {
15
+ name: string;
16
+ type: "individual" | "business";
17
+ }
14
18
  export declare class WorkspacesResource {
15
19
  private readonly transport;
16
20
  constructor(transport: TransportOptions);
@@ -24,6 +28,30 @@ export declare class WorkspacesResource {
24
28
  list(options: {
25
29
  asUser: string;
26
30
  }): Promise<UserWorkspace[]>;
31
+ /**
32
+ * Opens another workspace under the tenant the signed-in user already
33
+ * owns - a branch office, a second business unit.
34
+ *
35
+ * Every guard `CreateWorkspaceUseCase` enforces still applies: only the
36
+ * tenant's owner may call this, `type: "business"` still needs a non-free
37
+ * email domain, and the tenant's plan still decides whether it may hold
38
+ * another workspace at all - a `PreconditionError` surfaces as a thrown
39
+ * `ConnectError` with a message written to be shown ("Your current plan
40
+ * covers a single workspace...", "You've used all 3 of the workspaces
41
+ * your plans include..."). There is no `tenantId` parameter: the caller
42
+ * names no tenant, same as every other method on this resource names no
43
+ * workspace.
44
+ *
45
+ * `isActive`/`subscribed` on the result are always `false` - this does not
46
+ * switch the session, and the new workspace has no subscription yet. Chain
47
+ * `switch({workspaceId: result.workspaceId})` to move into it, but only
48
+ * when `result.inAudience` - a workspace outside this application's
49
+ * audience is refused by `switch` the same way `selectable()` in
50
+ * `<ConnectWorkspaceSwitcher>` already treats it.
51
+ */
52
+ create(input: CreateUserWorkspaceInput, options: {
53
+ asUser: string;
54
+ }): Promise<UserWorkspace>;
27
55
  /**
28
56
  * Moves this session to another workspace, returning a **new session
29
57
  * token**. The one you passed is revoked.
@@ -2029,6 +2029,39 @@ export interface AvailabilitySchedule {
2029
2029
  id: string;
2030
2030
  name: string;
2031
2031
  timezone: string;
2032
+ weeklyHours: WeeklyHours;
2033
+ }
2034
+ /**
2035
+ * One appointment type, as a management UI sees it - richer than
2036
+ * `BookableEventType`'s booking-catalogue shape, which deliberately
2037
+ * withholds `location.value` and everything else here. Fetched from
2038
+ * `listManageableEventTypes`, never the booking flow's `listEventTypes`.
2039
+ *
2040
+ * `host` collapses a group host to `{kind:"group"}` with nothing else -
2041
+ * there is no groups read in this API, so a team host is representable only
2042
+ * as "not this, edit it in Connect".
2043
+ */
2044
+ export interface ManageableEventType {
2045
+ id: string;
2046
+ slug: string;
2047
+ name: string;
2048
+ description: string | null;
2049
+ durationMinutes: number;
2050
+ bufferBeforeMinutes: number;
2051
+ bufferAfterMinutes: number;
2052
+ host: {
2053
+ kind: "member";
2054
+ memberId: string;
2055
+ } | {
2056
+ kind: "group";
2057
+ };
2058
+ scheduleId: string;
2059
+ location: {
2060
+ kind: "phone" | "address" | "link";
2061
+ value: string | null;
2062
+ };
2063
+ active: boolean;
2064
+ publicBookingEnabled: boolean;
2032
2065
  }
2033
2066
  /**
2034
2067
  * A phone or email on a contact.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmoops/connect-sdk",
3
- "version": "0.38.0",
3
+ "version": "0.40.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",