@neta-art/cohub 2.4.0 → 2.5.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/dist/chunks/http.d.ts +14 -6
- package/dist/chunks/http.js +7 -0
- package/dist/index.d.ts +111 -1
- package/dist/index.js +412 -4
- package/package.json +1 -1
package/dist/chunks/http.d.ts
CHANGED
|
@@ -3,7 +3,14 @@ import { C as ContentBlock, S as Usage, _ as SessionForkRecord, a as WebsocketCl
|
|
|
3
3
|
import { a as VoiceInputCreateOptions } from "./voice-input.js";
|
|
4
4
|
|
|
5
5
|
//#region ../protocol/src/gateway/types.d.ts
|
|
6
|
-
type
|
|
6
|
+
type ChannelModelConfig = {
|
|
7
|
+
provider: string;
|
|
8
|
+
id: string;
|
|
9
|
+
};
|
|
10
|
+
type BaseChannelConfig = {
|
|
11
|
+
model?: ChannelModelConfig | null;
|
|
12
|
+
};
|
|
13
|
+
type DiscordChannelConfig = BaseChannelConfig & {
|
|
7
14
|
inbound?: {
|
|
8
15
|
requireMentionInGuild?: boolean;
|
|
9
16
|
};
|
|
@@ -12,7 +19,7 @@ type DiscordChannelConfig = {
|
|
|
12
19
|
showToolCalls?: boolean;
|
|
13
20
|
};
|
|
14
21
|
};
|
|
15
|
-
type FeishuChannelConfig = {
|
|
22
|
+
type FeishuChannelConfig = BaseChannelConfig & {
|
|
16
23
|
brand?: "feishu" | "lark";
|
|
17
24
|
inbound?: {
|
|
18
25
|
requireMentionInGroup?: boolean;
|
|
@@ -23,12 +30,12 @@ type FeishuChannelConfig = {
|
|
|
23
30
|
showToolCalls?: boolean;
|
|
24
31
|
};
|
|
25
32
|
};
|
|
26
|
-
type WeChatChannelConfig = {
|
|
33
|
+
type WeChatChannelConfig = BaseChannelConfig & {
|
|
27
34
|
outbound?: {
|
|
28
35
|
showIntermediateStatus?: boolean;
|
|
29
36
|
};
|
|
30
37
|
};
|
|
31
|
-
type ChannelConfig = DiscordChannelConfig | FeishuChannelConfig | WeChatChannelConfig | Record<string, unknown
|
|
38
|
+
type ChannelConfig = DiscordChannelConfig | FeishuChannelConfig | WeChatChannelConfig | (BaseChannelConfig & Record<string, unknown>);
|
|
32
39
|
//#endregion
|
|
33
40
|
//#region ../../node_modules/.pnpm/@neta-art+generation@0.1.10/node_modules/@neta-art/generation/dist/builtins-CWEB_GK4.d.ts
|
|
34
41
|
//#region src/types.d.ts
|
|
@@ -2190,7 +2197,7 @@ type SpaceChannelBindingRecord = {
|
|
|
2190
2197
|
id: string;
|
|
2191
2198
|
spaceId: string;
|
|
2192
2199
|
channelId: string;
|
|
2193
|
-
config:
|
|
2200
|
+
config: ChannelConfig | null;
|
|
2194
2201
|
createdAt: string;
|
|
2195
2202
|
channel: {
|
|
2196
2203
|
id: string;
|
|
@@ -2207,7 +2214,8 @@ declare class SpaceChannelsApi {
|
|
|
2207
2214
|
private readonly spaceId;
|
|
2208
2215
|
constructor(transport: HttpTransport, spaceId: string);
|
|
2209
2216
|
list(): Promise<SpaceChannelBindingRecord[]>;
|
|
2210
|
-
bind(channelId: string, config?:
|
|
2217
|
+
bind(channelId: string, config?: ChannelConfig | null): Promise<SpaceChannelBindingRecord>;
|
|
2218
|
+
updateConfig(channelId: string, config?: ChannelConfig | null): Promise<SpaceChannelBindingRecord>;
|
|
2211
2219
|
unbind(channelId: string): Promise<{
|
|
2212
2220
|
ok: true;
|
|
2213
2221
|
}>;
|
package/dist/chunks/http.js
CHANGED
|
@@ -1923,6 +1923,13 @@ var SpaceChannelsApi = class {
|
|
|
1923
1923
|
body: JSON.stringify({ config: config ?? null })
|
|
1924
1924
|
});
|
|
1925
1925
|
}
|
|
1926
|
+
updateConfig(channelId, config) {
|
|
1927
|
+
return this.transport.request(`/api/spaces/${this.spaceId}/channels/${channelId}`, {
|
|
1928
|
+
method: "PATCH",
|
|
1929
|
+
headers: { "Content-Type": "application/json" },
|
|
1930
|
+
body: JSON.stringify({ config: config ?? null })
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1926
1933
|
unbind(channelId) {
|
|
1927
1934
|
return this.transport.request(`/api/spaces/${this.spaceId}/channels/${channelId}`, { method: "DELETE" });
|
|
1928
1935
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -136,9 +136,119 @@ declare class CohubClient {
|
|
|
136
136
|
}
|
|
137
137
|
declare const createCohubClient: (options?: CohubClientOptions) => CohubClient;
|
|
138
138
|
//#endregion
|
|
139
|
+
//#region src/work-bridge-core.d.ts
|
|
140
|
+
/**
|
|
141
|
+
* The subset of a work record the bridge host needs to answer bridge messages.
|
|
142
|
+
* Matches what the iframe host (WorkSurface) and the broker page both have on
|
|
143
|
+
* hand after loading the work.
|
|
144
|
+
*/
|
|
145
|
+
type WorkBridgeCoreWork = Pick<WorkRecord, "id" | "spaceId" | "slug" | "userUuid" | "workScopes" | "allowedViewerScopes">;
|
|
146
|
+
/**
|
|
147
|
+
* A pending authorize request surfaced to the UI as a consent dialog.
|
|
148
|
+
*/
|
|
149
|
+
type WorkAuthorizeRequest = {
|
|
150
|
+
requestId: string;
|
|
151
|
+
scopes: Permission[];
|
|
152
|
+
reason?: string;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* A pending purchase request surfaced to the UI as a checkout confirmation.
|
|
156
|
+
*/
|
|
157
|
+
type WorkPurchaseRequest = {
|
|
158
|
+
requestId: string;
|
|
159
|
+
productKey: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Reactive dialog state managed by the core. The host (Svelte or React)
|
|
163
|
+
* subscribes via {@link WorkBridgeCoreConfig.onStateChange} and mirrors these
|
|
164
|
+
* fields into its own reactive primitives.
|
|
165
|
+
*/
|
|
166
|
+
type WorkBridgeDialogState = {
|
|
167
|
+
authOpen: boolean;
|
|
168
|
+
pendingAuth: WorkAuthorizeRequest | null;
|
|
169
|
+
authError: string | null;
|
|
170
|
+
authSaving: boolean;
|
|
171
|
+
purchaseOpen: boolean;
|
|
172
|
+
pendingPurchase: WorkPurchaseRequest | null;
|
|
173
|
+
purchaseError: string | null;
|
|
174
|
+
purchaseSaving: boolean;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Resolves the current user's Cohub API access token. The core uses this to
|
|
178
|
+
* mint work session / authorization tokens via the Cohub API.
|
|
179
|
+
*/
|
|
180
|
+
type WorkBridgeGetAccessToken = (options?: {
|
|
181
|
+
forceRefresh?: boolean;
|
|
182
|
+
}) => Promise<string | null>;
|
|
183
|
+
/**
|
|
184
|
+
* Resolves the current viewer's user UUID (or null when unauthenticated).
|
|
185
|
+
* Used for ownership checks and silent re-authorization cache lookups.
|
|
186
|
+
*/
|
|
187
|
+
type WorkBridgeGetViewerUuid = () => Promise<string | null>;
|
|
188
|
+
/**
|
|
189
|
+
* Requests the host to start a sign-in flow, redirecting back to the given
|
|
190
|
+
* path afterward. The core calls this when an API request fails due to missing
|
|
191
|
+
* authentication.
|
|
192
|
+
*/
|
|
193
|
+
type WorkBridgeRequestSignIn = (redirectPath: string) => Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Configuration injected by the caller. The core is transport-agnostic: how a
|
|
196
|
+
* reply is delivered back to the work (iframe postMessage vs opener
|
|
197
|
+
* postMessage) and how the current checkout state is read (page URL) are the
|
|
198
|
+
* caller's responsibility, so the same core serves both bridge and broker
|
|
199
|
+
* hosts. Auth dependencies (token resolution, viewer identity, sign-in) are
|
|
200
|
+
* also injected so the core stays free of any framework's store/auth plumbing.
|
|
201
|
+
*/
|
|
202
|
+
type WorkBridgeCoreConfig = {
|
|
203
|
+
work: WorkBridgeCoreWork; /** True when running as a background chat surface (owner auto-authorizes). */
|
|
204
|
+
isBackground?: boolean; /** Base origin for Cohub API requests (e.g. "https://cohub.run"). */
|
|
205
|
+
apiOrigin: string; /** Sends a reply payload back to the work runtime. */
|
|
206
|
+
reply: (requestId: string, payload: Record<string, unknown>) => void; /** Reads the current checkout state (typically derived from the page URL). */
|
|
207
|
+
getCheckoutState: () => WorkRuntimeCheckoutState; /** Resolves the current user's Cohub access token. */
|
|
208
|
+
getAccessToken: WorkBridgeGetAccessToken; /** Resolves the current viewer's user UUID. */
|
|
209
|
+
getViewerUuid: WorkBridgeGetViewerUuid; /** Starts a sign-in flow with a post-login redirect path. */
|
|
210
|
+
requestSignIn: WorkBridgeRequestSignIn; /** Called whenever the dialog state changes, for reactive UI binding. */
|
|
211
|
+
onStateChange?: (state: WorkBridgeDialogState) => void;
|
|
212
|
+
};
|
|
213
|
+
type WorkBridgeCore = {
|
|
214
|
+
/** Returns a snapshot of the current dialog state. */getState: () => WorkBridgeDialogState; /** Processes an inbound bridge message (already source/origin-validated). */
|
|
215
|
+
handleMessage: (event: MessageEvent) => Promise<void>; /** Confirm/cancel handlers for the authorize dialog. */
|
|
216
|
+
confirmAuth: () => Promise<void>;
|
|
217
|
+
cancelAuth: () => void; /** Confirm/cancel handlers for the purchase dialog. */
|
|
218
|
+
confirmPurchase: () => Promise<void>;
|
|
219
|
+
cancelPurchase: () => void;
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Framework-agnostic work bridge host core — message handling, work session
|
|
223
|
+
* token minting, authorization (with silent re-grant cache), and
|
|
224
|
+
* purchase/checkout flow — without any rendering or reactive primitives.
|
|
225
|
+
*
|
|
226
|
+
* Both the Cohub iframe host (WorkSurface, Svelte) and the standalone broker
|
|
227
|
+
* page compose this with their own transport-specific reply and auth
|
|
228
|
+
* dependencies. External hosts (e.g. Neta-Studio in React) can do the same.
|
|
229
|
+
*/
|
|
230
|
+
declare function createWorkBridgeCore(config: WorkBridgeCoreConfig): WorkBridgeCore;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/work-grant-cache.d.ts
|
|
233
|
+
/**
|
|
234
|
+
* Returns true when the viewer has previously granted every requested scope
|
|
235
|
+
* for this work, allowing a silent re-authorization.
|
|
236
|
+
*/
|
|
237
|
+
declare function hasGrantedWorkScopes(userUuid: string | null | undefined, workId: string, scopes: readonly Permission[]): boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Records the granted scopes for a work, merged with any previously granted
|
|
240
|
+
* scopes so a growing permission set stays covered.
|
|
241
|
+
*/
|
|
242
|
+
declare function setGrantedWorkScopes(userUuid: string | null | undefined, workId: string, scopes: readonly Permission[]): void;
|
|
243
|
+
/**
|
|
244
|
+
* Clears cached grants. Pass a workId to clear a single work, or omit it to
|
|
245
|
+
* clear every cached grant for the user (used on sign-out).
|
|
246
|
+
*/
|
|
247
|
+
declare function clearGrantedWorkScopes(userUuid: string | null | undefined, workId?: string): void;
|
|
248
|
+
//#endregion
|
|
139
249
|
//#region src/http-error.d.ts
|
|
140
250
|
declare function isHttpErrorCode(error: unknown, code: string): error is HttpError & {
|
|
141
251
|
code: string;
|
|
142
252
|
};
|
|
143
253
|
//#endregion
|
|
144
|
-
export { AcceptInvitationResponse, ApiError, type AssistantMessageCommit, BatchUserProfilesResponse, BillingAccessWarning, BillingApi, BillingBalanceActivity, BillingBalanceActivityKind, BillingBalanceActivityList, BillingBalanceActivityStatus, BillingCatalog, BillingCatalogProduct, BillingCheckoutActionState, BillingCheckoutResult, BillingConversionIntent, BillingCreditExpiryGroup, BillingCreditGrantStatus, BillingCreditStatus, BillingCreditUnit, BillingHistoryPagination, BillingPaymentStatus, BillingPluginStatus, BillingProductBillingInterval, BillingProductCreditBenefit, BillingProductDisplay, BillingProductKind, BillingProductPricing, BillingRedemptionResult, BillingSubscriptionHistoryList, BillingSubscriptionHistoryStatus, BillingSubscriptionSummary, COHUB_ENVIRONMENTS, CanvasBootstrapResponse, CanvasCreateInput, CanvasDocumentRecord, CanvasNodeInput, CanvasNodeRecord, CanvasSemanticOp, CanvasTransactionInput, Channel, type ChannelConfig, type ChannelEnvelope, CheckpointRecord, CohubClient, type CohubClientOptions, type CohubEnvironment, CohubHttpClient, type ContentBlock, type CreateGenerationTaskRequest, type CreateGenerationTaskResponse, CreateInvitationInput, CreateInvitationResponse, type CreatePublicAssetUploadInput, type CreatePublicAssetUploadResponse, CreateSpaceInput, CreateSpaceModInput, CreateSpacePromptInput, CreateSpacePromptResponse, CreateSpaceSessionInput, CronJobPayload, CronJobRecord, CronJobUpdatePatch, CursorPageInfo, type DiscordChannelConfig, ExploreSection, ExploreSpaceItem, ExploreSpacesResponse, type Fetch, type GenerationContentBlock, type GenerationModelPolicy, type GenerationParameterConstraint, type GenerationPolicy, GenerationPolicyError, type GenerationStreamCommitEvent, type GenerationStreamErrorEvent, type GenerationStreamEvent, type GenerationStreamFinalizedEvent, type GenerationStreamIntermediateMessage, type GenerationStreamLifecycleEvent, type GenerationStreamOutOfSyncEvent, type GenerationStreamStateEvent, type GenerationStreamSubscribeOptions, type GenerationStreamSubscriptionHandlers, type GenerationStreamTurnUpdatedEvent, type GenerationTaskResult, GlobalSearchResponse, GlobalSearchResult, GlobalSearchType, HttpError, InvitationDetail, JsonObject, JsonPrimitive, JsonValue, LabelAssignmentListItem, LabelAssignmentPageInfo, LabelAssignmentRecord, type LabelAssignmentsUpdatedEvent, LabelListItem, LabelRecord, LabelResourceType, LabelScopeType, LabelSource, type ListGenerationModelsResponse, MeResponse, type MessageRecord, ModelCatalogEntry, ParentBridgeTransport, PatchResourceLabelsInput, PatchResourceLabelsResponse, Permission, PopupBrokerTransport, PromptAccessMode, PromptTemplateCatalogEntry, PromptTemplateCatalogResponse, type PublicAssetMimeType, type PublicAssetPurpose, type PublicGenerationDeclaration, PublicUserProfile, type RawHttpResponse, type RealtimeServerEvent, ReferenceAggregateGroup, ReferenceAggregateGroupBy, ReferenceAggregateResponse, ReferenceDirection, ReferenceKind, ReferenceQueryResponse, ReferenceQueryableType, ReferenceRecord, type ReferenceResourceSelector, ReferenceResourceType, ReferencesApi, ResourceLabelsResponse, SendMessageCronJobPayload, SessionBindingRecord, type SessionEventName, type SessionForkRecord, SessionGenerationStreamClient, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, type SessionPatchApplyInput, type SessionPatchApplyResult, SessionPatchReducer, type SessionPatchState, type SessionPatchStatus, SessionRecord, type SessionSubscriptionHandlers, type SessionTurnIndexItem, SessionTurnIndexResponse, type SessionTurnRecord, SessionTurnResponse, type SessionTurnSegmentRecord, SessionTurnSignedUrlsResponse, SessionTurnStreamSnapshotResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SpaceAccess, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, type SpaceChannelBindingRecord, SpaceCheckpointDetailResponse, SpaceCommerceBenefit, SpaceCommerceBuyerProfile, SpaceCommerceCreditsBenefit, SpaceCommerceFeatureBenefit, SpaceCommerceOrder, SpaceCommerceProduct, SpaceCommerceProductBenefitBinding, SpaceCommerceProductCreditBenefit, SpaceConfig, SpaceConfigInput, SpaceConfigResponse, SpaceCreateResponse, SpaceDefaultResponse, SpaceEnvInput, type SpaceEventName, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsEncoding, SpaceFsEntry, SpaceFsFileKind, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsPreparingFile, SpaceFsReadFilesError, SpaceFsReadFilesInput, SpaceFsReadFilesResponse, SpaceFsTreeResponse, SpaceFsUploadDestination, SpaceFsUploadEntry, SpaceFsUploadError, SpaceFsUploadPlanEntry, SpaceFsUploadPlanEntryInput, SpaceFsUploadProgress, SpaceFsUploadResponse, SpaceFsWriteFileInput, SpaceInvitation, SpaceListItem, SpaceMember, SpaceMeta, SpaceModListItem, SpacePresenceSnapshot, SpacePresenceUser, SpacePublicProfile, SpaceRecord, SpaceRole, SpaceSandboxAutoDestroyPolicy, SpaceSandboxConfig, SpaceSandboxProvider, SpaceSessionsResponse, SpaceUsageHourlyStat, SpaceUsageResponse, SpaceUsageSummary, TaskRunDetailResponse, TaskRunRecord, type UploadChatImageAttachmentInput, type UploadPublicAssetInput, UserProfile, UserRulesResponse, UsersApi, VoiceApi, type VoiceInputCallbacks, VoiceInputClient, type VoiceInputClientOptions, type VoiceInputCreateOptions, type VoiceInputEvent, type WebSocketConnectionState, WebsocketClient, type WorkAuthorizeResponse, WorkCommerceApi, type WorkCommerceCheckoutStatus, type WorkCommerceCreditConsumeResponse, type WorkCommerceCreditConsumeStatus, type WorkCommerceEntitlement, type WorkCommerceEntitlementsResponse, type WorkCommerceOrder, type WorkCommerceProductResolveResponse, type WorkCommercePurchaseResponse, type WorkCreateInput, type WorkDetailResponse, type WorkGetResponse, type WorkMeta, type WorkPresentationMeta, type WorkPublicOwnerRecord, type WorkPublicSpaceRecord, type WorkRecord, type WorkResolveResponse, WorkRuntimeApi, type WorkRuntimeCheckoutState, type WorkRuntimeCheckoutStatus, type WorkRuntimeContext, type WorkRuntimeModeConfig, type WorkRuntimeRequestOptions, type WorkRuntimeTransport, type WorkSessionResponse, type WorkStatus, type WorkTargetType, type WorkUpdateInput, type WorkVersionRecord, type WorkVisibility, WorksApi, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, isHttpErrorCode, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport };
|
|
254
|
+
export { AcceptInvitationResponse, ApiError, type AssistantMessageCommit, BatchUserProfilesResponse, BillingAccessWarning, BillingApi, BillingBalanceActivity, BillingBalanceActivityKind, BillingBalanceActivityList, BillingBalanceActivityStatus, BillingCatalog, BillingCatalogProduct, BillingCheckoutActionState, BillingCheckoutResult, BillingConversionIntent, BillingCreditExpiryGroup, BillingCreditGrantStatus, BillingCreditStatus, BillingCreditUnit, BillingHistoryPagination, BillingPaymentStatus, BillingPluginStatus, BillingProductBillingInterval, BillingProductCreditBenefit, BillingProductDisplay, BillingProductKind, BillingProductPricing, BillingRedemptionResult, BillingSubscriptionHistoryList, BillingSubscriptionHistoryStatus, BillingSubscriptionSummary, COHUB_ENVIRONMENTS, CanvasBootstrapResponse, CanvasCreateInput, CanvasDocumentRecord, CanvasNodeInput, CanvasNodeRecord, CanvasSemanticOp, CanvasTransactionInput, Channel, type ChannelConfig, type ChannelEnvelope, CheckpointRecord, CohubClient, type CohubClientOptions, type CohubEnvironment, CohubHttpClient, type ContentBlock, type CreateGenerationTaskRequest, type CreateGenerationTaskResponse, CreateInvitationInput, CreateInvitationResponse, type CreatePublicAssetUploadInput, type CreatePublicAssetUploadResponse, CreateSpaceInput, CreateSpaceModInput, CreateSpacePromptInput, CreateSpacePromptResponse, CreateSpaceSessionInput, CronJobPayload, CronJobRecord, CronJobUpdatePatch, CursorPageInfo, type DiscordChannelConfig, ExploreSection, ExploreSpaceItem, ExploreSpacesResponse, type Fetch, type GenerationContentBlock, type GenerationModelPolicy, type GenerationParameterConstraint, type GenerationPolicy, GenerationPolicyError, type GenerationStreamCommitEvent, type GenerationStreamErrorEvent, type GenerationStreamEvent, type GenerationStreamFinalizedEvent, type GenerationStreamIntermediateMessage, type GenerationStreamLifecycleEvent, type GenerationStreamOutOfSyncEvent, type GenerationStreamStateEvent, type GenerationStreamSubscribeOptions, type GenerationStreamSubscriptionHandlers, type GenerationStreamTurnUpdatedEvent, type GenerationTaskResult, GlobalSearchResponse, GlobalSearchResult, GlobalSearchType, HttpError, InvitationDetail, JsonObject, JsonPrimitive, JsonValue, LabelAssignmentListItem, LabelAssignmentPageInfo, LabelAssignmentRecord, type LabelAssignmentsUpdatedEvent, LabelListItem, LabelRecord, LabelResourceType, LabelScopeType, LabelSource, type ListGenerationModelsResponse, MeResponse, type MessageRecord, ModelCatalogEntry, ParentBridgeTransport, PatchResourceLabelsInput, PatchResourceLabelsResponse, Permission, PopupBrokerTransport, PromptAccessMode, PromptTemplateCatalogEntry, PromptTemplateCatalogResponse, type PublicAssetMimeType, type PublicAssetPurpose, type PublicGenerationDeclaration, PublicUserProfile, type RawHttpResponse, type RealtimeServerEvent, ReferenceAggregateGroup, ReferenceAggregateGroupBy, ReferenceAggregateResponse, ReferenceDirection, ReferenceKind, ReferenceQueryResponse, ReferenceQueryableType, ReferenceRecord, type ReferenceResourceSelector, ReferenceResourceType, ReferencesApi, ResourceLabelsResponse, SendMessageCronJobPayload, SessionBindingRecord, type SessionEventName, type SessionForkRecord, SessionGenerationStreamClient, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, type SessionPatchApplyInput, type SessionPatchApplyResult, SessionPatchReducer, type SessionPatchState, type SessionPatchStatus, SessionRecord, type SessionSubscriptionHandlers, type SessionTurnIndexItem, SessionTurnIndexResponse, type SessionTurnRecord, SessionTurnResponse, type SessionTurnSegmentRecord, SessionTurnSignedUrlsResponse, SessionTurnStreamSnapshotResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SpaceAccess, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, type SpaceChannelBindingRecord, SpaceCheckpointDetailResponse, SpaceCommerceBenefit, SpaceCommerceBuyerProfile, SpaceCommerceCreditsBenefit, SpaceCommerceFeatureBenefit, SpaceCommerceOrder, SpaceCommerceProduct, SpaceCommerceProductBenefitBinding, SpaceCommerceProductCreditBenefit, SpaceConfig, SpaceConfigInput, SpaceConfigResponse, SpaceCreateResponse, SpaceDefaultResponse, SpaceEnvInput, type SpaceEventName, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsEncoding, SpaceFsEntry, SpaceFsFileKind, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsPreparingFile, SpaceFsReadFilesError, SpaceFsReadFilesInput, SpaceFsReadFilesResponse, SpaceFsTreeResponse, SpaceFsUploadDestination, SpaceFsUploadEntry, SpaceFsUploadError, SpaceFsUploadPlanEntry, SpaceFsUploadPlanEntryInput, SpaceFsUploadProgress, SpaceFsUploadResponse, SpaceFsWriteFileInput, SpaceInvitation, SpaceListItem, SpaceMember, SpaceMeta, SpaceModListItem, SpacePresenceSnapshot, SpacePresenceUser, SpacePublicProfile, SpaceRecord, SpaceRole, SpaceSandboxAutoDestroyPolicy, SpaceSandboxConfig, SpaceSandboxProvider, SpaceSessionsResponse, SpaceUsageHourlyStat, SpaceUsageResponse, SpaceUsageSummary, TaskRunDetailResponse, TaskRunRecord, type UploadChatImageAttachmentInput, type UploadPublicAssetInput, UserProfile, UserRulesResponse, UsersApi, VoiceApi, type VoiceInputCallbacks, VoiceInputClient, type VoiceInputClientOptions, type VoiceInputCreateOptions, type VoiceInputEvent, type WebSocketConnectionState, WebsocketClient, type WorkAuthorizeRequest, type WorkAuthorizeResponse, type WorkBridgeCore, type WorkBridgeCoreConfig, type WorkBridgeCoreWork, type WorkBridgeDialogState, type WorkBridgeGetAccessToken, type WorkBridgeGetViewerUuid, type WorkBridgeRequestSignIn, WorkCommerceApi, type WorkCommerceCheckoutStatus, type WorkCommerceCreditConsumeResponse, type WorkCommerceCreditConsumeStatus, type WorkCommerceEntitlement, type WorkCommerceEntitlementsResponse, type WorkCommerceOrder, type WorkCommerceProductResolveResponse, type WorkCommercePurchaseResponse, type WorkCreateInput, type WorkDetailResponse, type WorkGetResponse, type WorkMeta, type WorkPresentationMeta, type WorkPublicOwnerRecord, type WorkPublicSpaceRecord, type WorkPurchaseRequest, type WorkRecord, type WorkResolveResponse, WorkRuntimeApi, type WorkRuntimeCheckoutState, type WorkRuntimeCheckoutStatus, type WorkRuntimeContext, type WorkRuntimeModeConfig, type WorkRuntimeRequestOptions, type WorkRuntimeTransport, type WorkSessionResponse, type WorkStatus, type WorkTargetType, type WorkUpdateInput, type WorkVersionRecord, type WorkVisibility, WorksApi, assertGenerationRequestAllowedByPolicy, clearGrantedWorkScopes, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, createWorkBridgeCore, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, hasGrantedWorkScopes, isHttpErrorCode, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, setGrantedWorkScopes };
|
package/dist/index.js
CHANGED
|
@@ -97,10 +97,10 @@ var UsersApi = class {
|
|
|
97
97
|
};
|
|
98
98
|
//#endregion
|
|
99
99
|
//#region src/work-runtime.ts
|
|
100
|
-
const isBrowser = () => typeof window !== "undefined" && typeof window.parent !== "undefined";
|
|
101
|
-
const hasParent = () => isBrowser() && window.parent !== window;
|
|
100
|
+
const isBrowser$1 = () => typeof window !== "undefined" && typeof window.parent !== "undefined";
|
|
101
|
+
const hasParent = () => isBrowser$1() && window.parent !== window;
|
|
102
102
|
const getParentOrigin = () => {
|
|
103
|
-
if (!isBrowser()) return null;
|
|
103
|
+
if (!isBrowser$1()) return null;
|
|
104
104
|
const ancestorOrigin = window.location.ancestorOrigins?.[0];
|
|
105
105
|
if (typeof ancestorOrigin === "string" && ancestorOrigin) return ancestorOrigin;
|
|
106
106
|
try {
|
|
@@ -515,6 +515,414 @@ var CohubClient = class {
|
|
|
515
515
|
};
|
|
516
516
|
const createCohubClient = (options) => new CohubClient(options);
|
|
517
517
|
//#endregion
|
|
518
|
+
//#region src/work-grant-cache.ts
|
|
519
|
+
const STORAGE_PREFIX = "cohub:work-grants";
|
|
520
|
+
const CACHE_VERSION = 1;
|
|
521
|
+
const MAX_AGE_MS = 336 * 60 * 60 * 1e3;
|
|
522
|
+
function isBrowser() {
|
|
523
|
+
return typeof localStorage !== "undefined";
|
|
524
|
+
}
|
|
525
|
+
function storageKey(userUuid, workId) {
|
|
526
|
+
return `${STORAGE_PREFIX}:${encodeURIComponent(userUuid)}:${encodeURIComponent(workId)}:v${CACHE_VERSION}`;
|
|
527
|
+
}
|
|
528
|
+
function userPrefix(userUuid) {
|
|
529
|
+
return `${STORAGE_PREFIX}:${encodeURIComponent(userUuid)}:`;
|
|
530
|
+
}
|
|
531
|
+
function isPermissionArray(value) {
|
|
532
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
533
|
+
}
|
|
534
|
+
function isCachedWorkGrant(value) {
|
|
535
|
+
if (!value || typeof value !== "object") return false;
|
|
536
|
+
const record = value;
|
|
537
|
+
return record.version === CACHE_VERSION && typeof record.userUuid === "string" && typeof record.workId === "string" && isPermissionArray(record.scopes) && typeof record.updatedAt === "number";
|
|
538
|
+
}
|
|
539
|
+
function readEntry(userUuid, workId) {
|
|
540
|
+
if (!isBrowser()) return null;
|
|
541
|
+
const key = storageKey(userUuid, workId);
|
|
542
|
+
try {
|
|
543
|
+
const raw = localStorage.getItem(key);
|
|
544
|
+
if (!raw) return null;
|
|
545
|
+
const parsed = JSON.parse(raw);
|
|
546
|
+
if (!isCachedWorkGrant(parsed) || parsed.userUuid !== userUuid || parsed.workId !== workId) {
|
|
547
|
+
localStorage.removeItem(key);
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
if (Date.now() - parsed.updatedAt > MAX_AGE_MS) {
|
|
551
|
+
localStorage.removeItem(key);
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
return parsed;
|
|
555
|
+
} catch {
|
|
556
|
+
try {
|
|
557
|
+
localStorage.removeItem(key);
|
|
558
|
+
} catch {}
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Returns true when the viewer has previously granted every requested scope
|
|
564
|
+
* for this work, allowing a silent re-authorization.
|
|
565
|
+
*/
|
|
566
|
+
function hasGrantedWorkScopes(userUuid, workId, scopes) {
|
|
567
|
+
if (!userUuid || !workId || scopes.length === 0) return false;
|
|
568
|
+
const entry = readEntry(userUuid, workId);
|
|
569
|
+
if (!entry) return false;
|
|
570
|
+
const granted = new Set(entry.scopes);
|
|
571
|
+
return scopes.every((scope) => granted.has(scope));
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Records the granted scopes for a work, merged with any previously granted
|
|
575
|
+
* scopes so a growing permission set stays covered.
|
|
576
|
+
*/
|
|
577
|
+
function setGrantedWorkScopes(userUuid, workId, scopes) {
|
|
578
|
+
if (!userUuid || !workId || scopes.length === 0) return;
|
|
579
|
+
const existing = readEntry(userUuid, workId);
|
|
580
|
+
const entry = {
|
|
581
|
+
version: CACHE_VERSION,
|
|
582
|
+
userUuid,
|
|
583
|
+
workId,
|
|
584
|
+
scopes: Array.from(new Set([...existing?.scopes ?? [], ...scopes])),
|
|
585
|
+
updatedAt: Date.now()
|
|
586
|
+
};
|
|
587
|
+
if (!isBrowser()) return;
|
|
588
|
+
try {
|
|
589
|
+
localStorage.setItem(storageKey(userUuid, workId), JSON.stringify(entry));
|
|
590
|
+
} catch {}
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Clears cached grants. Pass a workId to clear a single work, or omit it to
|
|
594
|
+
* clear every cached grant for the user (used on sign-out).
|
|
595
|
+
*/
|
|
596
|
+
function clearGrantedWorkScopes(userUuid, workId) {
|
|
597
|
+
if (!isBrowser() || !userUuid) return;
|
|
598
|
+
try {
|
|
599
|
+
if (workId) {
|
|
600
|
+
localStorage.removeItem(storageKey(userUuid, workId));
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const prefix = userPrefix(userUuid);
|
|
604
|
+
for (let i = localStorage.length - 1; i >= 0; i -= 1) {
|
|
605
|
+
const key = localStorage.key(i);
|
|
606
|
+
if (key?.startsWith(prefix)) localStorage.removeItem(key);
|
|
607
|
+
}
|
|
608
|
+
} catch {}
|
|
609
|
+
}
|
|
610
|
+
//#endregion
|
|
611
|
+
//#region src/work-bridge-core.ts
|
|
612
|
+
function readTokenResponse(value) {
|
|
613
|
+
if (!value || typeof value !== "object") return null;
|
|
614
|
+
const token = value.token;
|
|
615
|
+
return typeof token === "string" && token ? token : null;
|
|
616
|
+
}
|
|
617
|
+
function clonePermissionScopes(scopes) {
|
|
618
|
+
return Array.from(scopes ?? []).filter((scope) => typeof scope === "string");
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Framework-agnostic work bridge host core — message handling, work session
|
|
622
|
+
* token minting, authorization (with silent re-grant cache), and
|
|
623
|
+
* purchase/checkout flow — without any rendering or reactive primitives.
|
|
624
|
+
*
|
|
625
|
+
* Both the Cohub iframe host (WorkSurface, Svelte) and the standalone broker
|
|
626
|
+
* page compose this with their own transport-specific reply and auth
|
|
627
|
+
* dependencies. External hosts (e.g. Neta-Studio in React) can do the same.
|
|
628
|
+
*/
|
|
629
|
+
function createWorkBridgeCore(config) {
|
|
630
|
+
const { work, reply, getCheckoutState, getAccessToken, getViewerUuid } = config;
|
|
631
|
+
const apiOrigin = config.apiOrigin;
|
|
632
|
+
const isBackground = config.isBackground ?? false;
|
|
633
|
+
const onStateChange = config.onStateChange;
|
|
634
|
+
let workToken = null;
|
|
635
|
+
const state = {
|
|
636
|
+
authOpen: false,
|
|
637
|
+
pendingAuth: null,
|
|
638
|
+
authError: null,
|
|
639
|
+
authSaving: false,
|
|
640
|
+
purchaseOpen: false,
|
|
641
|
+
pendingPurchase: null,
|
|
642
|
+
purchaseError: null,
|
|
643
|
+
purchaseSaving: false
|
|
644
|
+
};
|
|
645
|
+
function notify() {
|
|
646
|
+
onStateChange?.({ ...state });
|
|
647
|
+
}
|
|
648
|
+
const pendingPurchaseStorageKey = `cohub-work-purchase:${work.id}`;
|
|
649
|
+
async function isCurrentViewerWorkOwner() {
|
|
650
|
+
const viewerUuid = await getViewerUuid();
|
|
651
|
+
return Boolean(viewerUuid && viewerUuid === work.userUuid);
|
|
652
|
+
}
|
|
653
|
+
async function ensureBaseToken(forceRefresh = false) {
|
|
654
|
+
if (workToken && !forceRefresh) return workToken;
|
|
655
|
+
const userToken = await getAccessToken({ forceRefresh });
|
|
656
|
+
if (!userToken) {
|
|
657
|
+
await config.requestSignIn(typeof location !== "undefined" ? location.pathname : "/");
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
const response = await fetch(`${apiOrigin}/api/works/${work.id}/session`, {
|
|
661
|
+
method: "POST",
|
|
662
|
+
headers: { Authorization: `Bearer ${userToken}` }
|
|
663
|
+
});
|
|
664
|
+
if (!response.ok) throw new Error("Failed to create work session.");
|
|
665
|
+
const token = readTokenResponse(await response.json());
|
|
666
|
+
if (!token) throw new Error("Invalid work session response.");
|
|
667
|
+
workToken = token;
|
|
668
|
+
return workToken;
|
|
669
|
+
}
|
|
670
|
+
async function authorize(scopes) {
|
|
671
|
+
const userToken = await getAccessToken();
|
|
672
|
+
if (!userToken) {
|
|
673
|
+
await config.requestSignIn(typeof location !== "undefined" ? location.pathname : "/");
|
|
674
|
+
return null;
|
|
675
|
+
}
|
|
676
|
+
const response = await fetch(`${apiOrigin}/api/works/${work.id}/authorize`, {
|
|
677
|
+
method: "POST",
|
|
678
|
+
headers: {
|
|
679
|
+
Authorization: `Bearer ${userToken}`,
|
|
680
|
+
"Content-Type": "application/json"
|
|
681
|
+
},
|
|
682
|
+
body: JSON.stringify({ scopes })
|
|
683
|
+
});
|
|
684
|
+
if (!response.ok) throw new Error((await response.json().catch(() => null))?.message ?? "Authorization failed.");
|
|
685
|
+
const token = readTokenResponse(await response.json());
|
|
686
|
+
if (!token) throw new Error("Invalid work authorization response.");
|
|
687
|
+
workToken = token;
|
|
688
|
+
return workToken;
|
|
689
|
+
}
|
|
690
|
+
function writePendingPurchase(input) {
|
|
691
|
+
if (typeof sessionStorage === "undefined") return;
|
|
692
|
+
try {
|
|
693
|
+
sessionStorage.setItem(pendingPurchaseStorageKey, JSON.stringify({
|
|
694
|
+
...input,
|
|
695
|
+
at: Date.now()
|
|
696
|
+
}));
|
|
697
|
+
} catch {}
|
|
698
|
+
}
|
|
699
|
+
function readPendingPurchase() {
|
|
700
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
701
|
+
try {
|
|
702
|
+
const raw = sessionStorage.getItem(pendingPurchaseStorageKey);
|
|
703
|
+
if (!raw) return null;
|
|
704
|
+
const parsed = JSON.parse(raw);
|
|
705
|
+
return typeof parsed.orderId === "string" && typeof parsed.productKey === "string" && typeof parsed.at === "number" ? {
|
|
706
|
+
orderId: parsed.orderId,
|
|
707
|
+
productKey: parsed.productKey,
|
|
708
|
+
at: parsed.at
|
|
709
|
+
} : null;
|
|
710
|
+
} catch {
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
function clearPendingPurchase() {
|
|
715
|
+
if (typeof sessionStorage === "undefined") return;
|
|
716
|
+
try {
|
|
717
|
+
sessionStorage.removeItem(pendingPurchaseStorageKey);
|
|
718
|
+
} catch {}
|
|
719
|
+
}
|
|
720
|
+
async function createPurchase(productKey) {
|
|
721
|
+
const userToken = await getAccessToken();
|
|
722
|
+
if (!userToken) {
|
|
723
|
+
await config.requestSignIn(typeof location !== "undefined" ? location.pathname + location.search + location.hash : "/");
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
const response = await fetch(`${apiOrigin}/api/works/${work.id}/commerce/purchase`, {
|
|
727
|
+
method: "POST",
|
|
728
|
+
headers: {
|
|
729
|
+
Authorization: `Bearer ${userToken}`,
|
|
730
|
+
"Content-Type": "application/json"
|
|
731
|
+
},
|
|
732
|
+
body: JSON.stringify({ productKey })
|
|
733
|
+
});
|
|
734
|
+
if (!response.ok) throw new Error((await response.json().catch(() => null))?.message ?? "Purchase failed.");
|
|
735
|
+
return (await response.json()).checkout ?? null;
|
|
736
|
+
}
|
|
737
|
+
async function handleMessage(event) {
|
|
738
|
+
const data = event.data;
|
|
739
|
+
if (!data?.requestId) return;
|
|
740
|
+
try {
|
|
741
|
+
if (data.type === "cohub.work.context") {
|
|
742
|
+
const workScopes = clonePermissionScopes(work.workScopes);
|
|
743
|
+
reply(data.requestId, {
|
|
744
|
+
type: "cohub.work.context.result",
|
|
745
|
+
context: {
|
|
746
|
+
work: {
|
|
747
|
+
id: work.id,
|
|
748
|
+
slug: work.slug,
|
|
749
|
+
url: typeof location !== "undefined" ? location.href : ""
|
|
750
|
+
},
|
|
751
|
+
space: { id: work.spaceId },
|
|
752
|
+
permissions: {
|
|
753
|
+
scopes: workScopes,
|
|
754
|
+
workScopes,
|
|
755
|
+
viewerScopes: []
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
if (data.type === "cohub.work.token") {
|
|
761
|
+
const token = await ensureBaseToken(Boolean(data.forceRefresh));
|
|
762
|
+
reply(data.requestId, {
|
|
763
|
+
type: "cohub.work.token.result",
|
|
764
|
+
token
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
if (data.type === "cohub.work.checkout-state") {
|
|
768
|
+
const pending = readPendingPurchase();
|
|
769
|
+
const checkoutState = getCheckoutState();
|
|
770
|
+
const orderId = checkoutState.orderId ?? pending?.orderId ?? null;
|
|
771
|
+
if (checkoutState.status && checkoutState.orderId) clearPendingPurchase();
|
|
772
|
+
reply(data.requestId, {
|
|
773
|
+
type: "cohub.work.checkout-state.result",
|
|
774
|
+
status: checkoutState.status,
|
|
775
|
+
orderId
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
if (data.type === "cohub.work.purchase") {
|
|
779
|
+
const productKey = typeof data.productKey === "string" ? data.productKey.trim() : "";
|
|
780
|
+
if (!productKey) {
|
|
781
|
+
reply(data.requestId, {
|
|
782
|
+
type: "cohub.work.error",
|
|
783
|
+
message: "Product key is required."
|
|
784
|
+
});
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
state.pendingPurchase = {
|
|
788
|
+
requestId: data.requestId,
|
|
789
|
+
productKey
|
|
790
|
+
};
|
|
791
|
+
state.purchaseError = null;
|
|
792
|
+
state.purchaseOpen = true;
|
|
793
|
+
notify();
|
|
794
|
+
}
|
|
795
|
+
if (data.type === "cohub.work.authorize") {
|
|
796
|
+
const allowedViewerScopes = clonePermissionScopes(work.allowedViewerScopes);
|
|
797
|
+
const scopes = clonePermissionScopes(data.scopes).filter((scope) => allowedViewerScopes.includes(scope));
|
|
798
|
+
if (scopes.length === 0) {
|
|
799
|
+
reply(data.requestId, {
|
|
800
|
+
type: "cohub.work.error",
|
|
801
|
+
message: "No allowed scopes requested."
|
|
802
|
+
});
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (isBackground && await isCurrentViewerWorkOwner()) {
|
|
806
|
+
const token = await authorize(scopes);
|
|
807
|
+
reply(data.requestId, {
|
|
808
|
+
type: "cohub.work.authorize.result",
|
|
809
|
+
token
|
|
810
|
+
});
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
const viewerUuid = await getViewerUuid();
|
|
814
|
+
if (viewerUuid && hasGrantedWorkScopes(viewerUuid, work.id, scopes)) try {
|
|
815
|
+
const token = await authorize(scopes);
|
|
816
|
+
reply(data.requestId, {
|
|
817
|
+
type: "cohub.work.authorize.result",
|
|
818
|
+
token
|
|
819
|
+
});
|
|
820
|
+
return;
|
|
821
|
+
} catch {
|
|
822
|
+
clearGrantedWorkScopes(viewerUuid, work.id);
|
|
823
|
+
}
|
|
824
|
+
state.pendingAuth = {
|
|
825
|
+
requestId: data.requestId,
|
|
826
|
+
scopes,
|
|
827
|
+
reason: data.reason
|
|
828
|
+
};
|
|
829
|
+
state.authError = null;
|
|
830
|
+
state.authOpen = true;
|
|
831
|
+
notify();
|
|
832
|
+
}
|
|
833
|
+
} catch (error) {
|
|
834
|
+
reply(data.requestId, {
|
|
835
|
+
type: "cohub.work.error",
|
|
836
|
+
message: error instanceof Error ? error.message : "Request failed."
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
function cancelAuth() {
|
|
841
|
+
if (state.authSaving) return;
|
|
842
|
+
if (!state.pendingAuth) return;
|
|
843
|
+
reply(state.pendingAuth.requestId, {
|
|
844
|
+
type: "cohub.work.authorize.result",
|
|
845
|
+
token: null
|
|
846
|
+
});
|
|
847
|
+
state.authOpen = false;
|
|
848
|
+
state.pendingAuth = null;
|
|
849
|
+
state.authError = null;
|
|
850
|
+
state.authSaving = false;
|
|
851
|
+
notify();
|
|
852
|
+
}
|
|
853
|
+
function cancelPurchase() {
|
|
854
|
+
if (state.purchaseSaving) return;
|
|
855
|
+
if (!state.pendingPurchase) return;
|
|
856
|
+
reply(state.pendingPurchase.requestId, {
|
|
857
|
+
type: "cohub.work.purchase.result",
|
|
858
|
+
checkout: null
|
|
859
|
+
});
|
|
860
|
+
state.purchaseOpen = false;
|
|
861
|
+
state.purchaseError = null;
|
|
862
|
+
state.pendingPurchase = null;
|
|
863
|
+
state.purchaseSaving = false;
|
|
864
|
+
notify();
|
|
865
|
+
}
|
|
866
|
+
async function confirmPurchase() {
|
|
867
|
+
if (!state.pendingPurchase || state.purchaseSaving) return;
|
|
868
|
+
state.purchaseSaving = true;
|
|
869
|
+
state.purchaseError = null;
|
|
870
|
+
notify();
|
|
871
|
+
try {
|
|
872
|
+
const checkout = await createPurchase(state.pendingPurchase.productKey);
|
|
873
|
+
reply(state.pendingPurchase.requestId, {
|
|
874
|
+
type: "cohub.work.purchase.result",
|
|
875
|
+
checkout
|
|
876
|
+
});
|
|
877
|
+
if (checkout && typeof checkout === "object") {
|
|
878
|
+
const next = checkout;
|
|
879
|
+
if (typeof next.orderId === "string" && typeof next.productKey === "string") writePendingPurchase({
|
|
880
|
+
orderId: next.orderId,
|
|
881
|
+
productKey: next.productKey
|
|
882
|
+
});
|
|
883
|
+
const url = next.checkoutUrl;
|
|
884
|
+
if (next.checkoutUsable === true && typeof url === "string" && url) window.location.href = url;
|
|
885
|
+
}
|
|
886
|
+
state.purchaseOpen = false;
|
|
887
|
+
state.pendingPurchase = null;
|
|
888
|
+
} catch (error) {
|
|
889
|
+
state.purchaseError = error instanceof Error ? error.message : "Purchase failed.";
|
|
890
|
+
} finally {
|
|
891
|
+
state.purchaseSaving = false;
|
|
892
|
+
notify();
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
async function confirmAuth() {
|
|
896
|
+
if (!state.pendingAuth || state.authSaving) return;
|
|
897
|
+
state.authError = null;
|
|
898
|
+
state.authSaving = true;
|
|
899
|
+
notify();
|
|
900
|
+
try {
|
|
901
|
+
const token = await authorize(state.pendingAuth.scopes);
|
|
902
|
+
setGrantedWorkScopes(await getViewerUuid(), work.id, state.pendingAuth.scopes);
|
|
903
|
+
reply(state.pendingAuth.requestId, {
|
|
904
|
+
type: "cohub.work.authorize.result",
|
|
905
|
+
token
|
|
906
|
+
});
|
|
907
|
+
state.authOpen = false;
|
|
908
|
+
state.pendingAuth = null;
|
|
909
|
+
} catch (error) {
|
|
910
|
+
state.authError = error instanceof Error ? error.message : "Authorization failed.";
|
|
911
|
+
} finally {
|
|
912
|
+
state.authSaving = false;
|
|
913
|
+
notify();
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
getState: () => ({ ...state }),
|
|
918
|
+
handleMessage,
|
|
919
|
+
confirmAuth,
|
|
920
|
+
cancelAuth,
|
|
921
|
+
confirmPurchase,
|
|
922
|
+
cancelPurchase
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
//#endregion
|
|
518
926
|
//#region src/http-error.ts
|
|
519
927
|
function isHttpErrorCode(error, code) {
|
|
520
928
|
return error instanceof HttpError && error.code === code;
|
|
@@ -751,4 +1159,4 @@ function filterGenerationDeclarationsByPolicy(declarations, policy) {
|
|
|
751
1159
|
});
|
|
752
1160
|
}
|
|
753
1161
|
//#endregion
|
|
754
|
-
export { BillingApi, COHUB_ENVIRONMENTS, CohubClient, CohubHttpClient, GenerationPolicyError, HttpError, ParentBridgeTransport, PopupBrokerTransport, ReferencesApi, SessionGenerationStreamClient, SessionPatchReducer, UsersApi, VoiceApi, VoiceInputClient, WebsocketClient, WorkCommerceApi, WorkRuntimeApi, WorksApi, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, isHttpErrorCode, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport };
|
|
1162
|
+
export { BillingApi, COHUB_ENVIRONMENTS, CohubClient, CohubHttpClient, GenerationPolicyError, HttpError, ParentBridgeTransport, PopupBrokerTransport, ReferencesApi, SessionGenerationStreamClient, SessionPatchReducer, UsersApi, VoiceApi, VoiceInputClient, WebsocketClient, WorkCommerceApi, WorkRuntimeApi, WorksApi, assertGenerationRequestAllowedByPolicy, clearGrantedWorkScopes, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, createWorkBridgeCore, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, hasGrantedWorkScopes, isHttpErrorCode, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, setGrantedWorkScopes };
|