@xenide-io/suite-client 0.3.2 → 0.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/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ConfigDefaults } from 'posthog-js';
2
+
1
3
  declare const ERROR_CODES: {
2
4
  readonly AUTH_001: "E-AUTH-001";
3
5
  readonly AUTH_002: "E-AUTH-002";
@@ -45,9 +47,54 @@ declare function normalizeThrown(input: unknown, capability?: string): AppError;
45
47
  /** Display string for a failure surface: capability copy plus the code. */
46
48
  declare function formatAppError(error: AppError): string;
47
49
 
50
+ /**
51
+ * Global super-properties and event properties accepted by the analytics client.
52
+ * Values may be `null` to clear a previously registered super-property.
53
+ */
54
+ type AnalyticsProperties = Record<string, unknown>;
55
+ /** Headers forwarded on every API request so server events share the web identity. */
56
+ type AnalyticsContextHeaders = Record<string, string>;
57
+ interface AnalyticsClientConfig {
58
+ /** `NEXT_PUBLIC_POSTHOG_KEY`. A missing key makes the client a no-op. */
59
+ apiKey?: string;
60
+ /** `NEXT_PUBLIC_POSTHOG_HOST`, e.g. `https://us.i.posthog.com`. */
61
+ host?: string;
62
+ /** Global `app` super-property, e.g. `turtletime`. */
63
+ app: string;
64
+ /** Global `environment` super-property; defaults to `NODE_ENV`. */
65
+ environment?: string;
66
+ /** PostHog config defaults date. Defaults to `2026-05-30`. */
67
+ defaults?: ConfigDefaults;
68
+ }
69
+ type AnalyticsClient = ReturnType<typeof createAnalyticsClient>;
70
+ /** Domain half of an email — safe to send; the raw address is not. */
71
+ declare function emailDomain(email: string | null | undefined): string | undefined;
72
+ /**
73
+ * Browser analytics client shared across ShellStack apps.
74
+ *
75
+ * Wraps `posthog-js` so every app initialises the same way, registers the same
76
+ * global super-properties, and forwards the browser identity/session ids to the
77
+ * API. The SDK keeps PostHog's defaults (autocapture, pageviews, UTM, browser/OS,
78
+ * referrer) — nothing here disables them.
79
+ */
80
+ declare function createAnalyticsClient(config: AnalyticsClientConfig): {
81
+ init: () => void;
82
+ identify: (userId: string, props?: AnalyticsProperties, setOnceProps?: AnalyticsProperties) => void;
83
+ group: (groupType: string, groupKey: string, props?: AnalyticsProperties) => void;
84
+ capture: (event: string, props?: AnalyticsProperties) => void;
85
+ reset: () => void;
86
+ getDistinctId: () => string | undefined;
87
+ getSessionId: () => string | undefined;
88
+ pageview: () => void;
89
+ registerSuperProperties: (props: AnalyticsProperties) => void;
90
+ getContextHeaders: () => AnalyticsContextHeaders;
91
+ };
92
+
48
93
  type ApiFetchInit = RequestInit & {
49
94
  skipAuth?: boolean;
50
95
  };
96
+ /** Optional analytics sink forwarded client lifecycle events (e.g. `analytics.capture`). */
97
+ type ApiAnalyticsEventSink = (event: string, properties?: Record<string, unknown>) => void;
51
98
  interface ApiClientConfig {
52
99
  /** localStorage key namespace, e.g. `tt` or `tides`. */
53
100
  storagePrefix: string;
@@ -74,6 +121,18 @@ interface ApiClientConfig {
74
121
  sessionStorageClearPrefixes?: string[];
75
122
  /** Refuse to send the session to an unexpected absolute origin. */
76
123
  enforceSameOrigin?: boolean;
124
+ /**
125
+ * Extra headers to attach to every request. Used to forward the PostHog
126
+ * identity/session ids (`X-POSTHOG-DISTINCT-ID` / `X-POSTHOG-SESSION-ID`)
127
+ * so server-side events share the browser identity. Empty values are dropped.
128
+ */
129
+ getContextHeaders?: () => Record<string, string>;
130
+ /**
131
+ * Forward client lifecycle events (`Session Expired`, `Workspace Switched`,
132
+ * `User Logged Out`) to the app's analytics client. Kept as a plain callback
133
+ * so this package never imports an analytics implementation.
134
+ */
135
+ onAnalyticsEvent?: ApiAnalyticsEventSink;
77
136
  }
78
137
  /**
79
138
  * Build a browser API client scoped to one ShellStack app. Every app shares the
@@ -92,7 +151,9 @@ declare function createApiClient(config: ApiClientConfig): {
92
151
  }) => void;
93
152
  getActiveWorkspaceId: () => string | null;
94
153
  restoreWorkspace: () => void;
95
- clearAuth: () => void;
154
+ clearAuth: (options?: {
155
+ origin?: "user" | "session_expired";
156
+ }) => void;
96
157
  restoreTokens: () => void;
97
158
  refreshAccessToken: () => Promise<boolean>;
98
159
  parseApiError: (res: Response) => Promise<string>;
@@ -104,7 +165,9 @@ declare function createApiClient(config: ApiClientConfig): {
104
165
  delete: (path: string, init?: ApiFetchInit) => Promise<Response>;
105
166
  };
106
167
  restoreSession: () => void;
107
- clearSession: () => void;
168
+ clearSession: (options?: {
169
+ origin?: "user" | "session_expired";
170
+ }) => void;
108
171
  };
109
172
  type ApiClient = ReturnType<typeof createApiClient>;
110
173
  type Api = ApiClient['api'];
@@ -117,6 +180,8 @@ interface AuthReturnPathConfig {
117
180
  defaultNext?: string;
118
181
  portalCallbackPath?: string;
119
182
  redeemPath?: string;
183
+ /** Forward the completed cross-app switch to the app's analytics client. */
184
+ onAnalyticsEvent?: (event: string, properties?: Record<string, unknown>) => void;
120
185
  }
121
186
  interface PortalHandoffPayload {
122
187
  code?: string;
@@ -326,6 +391,36 @@ declare function createNotificationsClient(config: NotificationsClientConfig): {
326
391
  markAllSuiteNotificationsRead: () => Promise<void>;
327
392
  };
328
393
 
394
+ /** Browser push state surfaced to settings UI. */
395
+ type WebPushState = 'unsupported' | 'unconfigured' | 'default' | 'granted' | 'denied' | 'subscribed';
396
+ interface WebPushConfig {
397
+ enabled: boolean;
398
+ public_key: string;
399
+ }
400
+ interface WebPushClientConfig {
401
+ api: Api;
402
+ parseApiError: (res: Response) => Promise<string>;
403
+ publicKeyPath?: string;
404
+ subscribePath?: string;
405
+ unsubscribePath?: string;
406
+ serviceWorkerPath?: string;
407
+ serviceWorkerScope?: string;
408
+ }
409
+ type WebPushClient = ReturnType<typeof createWebPushClient>;
410
+ /**
411
+ * Browser Web Push client shared across ShellStack apps.
412
+ *
413
+ * Registration is per origin: each app ships its own `/sw.js` and manifest,
414
+ * but all talk to the same suite endpoints, so a subscription made in one app
415
+ * receives notifications for the whole suite.
416
+ */
417
+ declare function createWebPushClient(config: WebPushClientConfig): {
418
+ supported: () => boolean;
419
+ getState: () => Promise<WebPushState>;
420
+ enable: () => Promise<void>;
421
+ disable: () => Promise<void>;
422
+ };
423
+
329
424
  type SuiteAiJobEvent = {
330
425
  sequence: number;
331
426
  event_type: 'queued' | 'started' | 'progress' | 'tool' | 'completed' | 'failed' | 'cancelled';
@@ -386,4 +481,4 @@ declare function createJsonLd(config: JsonLdConfig): string;
386
481
 
387
482
  declare function useIsNight(): boolean;
388
483
 
389
- export { type Api, type ApiClient, type ApiClientConfig, type ApiFetchInit, type AppError, type AuthReturnPath, type AuthReturnPathConfig, type BrandSettings, type BrandSettingsConfig, type CrossAppSync, type CrossAppSyncConfig, type CrossAppSyncTopic, DEFAULT_ERROR_CODE, ERROR_CODES, ERROR_COPY, ERROR_RETRYABLE, type ErrorCode, FREE_PLAN_SEAT_HELP, type JsonLdConfig, type LiveRefresh, type LiveRefreshOptions, type NotificationsClient, type NotificationsClientConfig, ORGANISATION_SEAT_HELP, type PortalHandoffPayload, type PortalHandoffRead, type SeatType, type SubscriptionTier, type SuiteAiJob, type SuiteAiJobEvent, type SuiteNotification, type SuiteNotificationsResponse, TIDES_ACCESS_HELP, TURTLETIME_ACCESS_HELP, WEBHOOK_ACTIVITY_ACTIONS, WORKSPACE_SEAT_HELP, type WorkspaceAppearance, type WorkspaceAppearanceApiConfig, type WorkspaceAppearanceConfig, WorkspaceAppearanceError, type WorkspaceAppearanceHelpers, type WorkspaceAppearancePatch, type WorkspaceBrandPayload, type WorkspaceSubscription, type WorkspaceTheme, activeSuiteAiJobs, appErrorFromResponse, canDisableAppAccess, codeForStatus, copyFor, createApiClient, createAuthReturnPath, createBrandSettings, createCrossAppSync, createJsonLd, createLiveRefresh, createNotificationsClient, createWorkspaceAppearance, createWorkspaceAppearanceApi, defaultInviteSeatType, flagsFromSeatType, formatAppError, hasAppAccess, isErrorCode, normalizeError, normalizeThrown, planSeatSummary, resolveSubscriptionTier, seatTypeDescription, seatTypeFromFlags, seatTypeLabel, selectedToWebhookActions, sortedSuiteAiEvents, suiteAiEventSummary, tierAllowsTidesOnlySeats, tierAllowsTurtletime, tierLabel, useIsNight, webhookActionsToSelected };
484
+ export { type AnalyticsClient, type AnalyticsClientConfig, type AnalyticsContextHeaders, type AnalyticsProperties, type Api, type ApiAnalyticsEventSink, type ApiClient, type ApiClientConfig, type ApiFetchInit, type AppError, type AuthReturnPath, type AuthReturnPathConfig, type BrandSettings, type BrandSettingsConfig, type CrossAppSync, type CrossAppSyncConfig, type CrossAppSyncTopic, DEFAULT_ERROR_CODE, ERROR_CODES, ERROR_COPY, ERROR_RETRYABLE, type ErrorCode, FREE_PLAN_SEAT_HELP, type JsonLdConfig, type LiveRefresh, type LiveRefreshOptions, type NotificationsClient, type NotificationsClientConfig, ORGANISATION_SEAT_HELP, type PortalHandoffPayload, type PortalHandoffRead, type SeatType, type SubscriptionTier, type SuiteAiJob, type SuiteAiJobEvent, type SuiteNotification, type SuiteNotificationsResponse, TIDES_ACCESS_HELP, TURTLETIME_ACCESS_HELP, WEBHOOK_ACTIVITY_ACTIONS, WORKSPACE_SEAT_HELP, type WebPushClient, type WebPushClientConfig, type WebPushConfig, type WebPushState, type WorkspaceAppearance, type WorkspaceAppearanceApiConfig, type WorkspaceAppearanceConfig, WorkspaceAppearanceError, type WorkspaceAppearanceHelpers, type WorkspaceAppearancePatch, type WorkspaceBrandPayload, type WorkspaceSubscription, type WorkspaceTheme, activeSuiteAiJobs, appErrorFromResponse, canDisableAppAccess, codeForStatus, copyFor, createAnalyticsClient, createApiClient, createAuthReturnPath, createBrandSettings, createCrossAppSync, createJsonLd, createLiveRefresh, createNotificationsClient, createWebPushClient, createWorkspaceAppearance, createWorkspaceAppearanceApi, defaultInviteSeatType, emailDomain, flagsFromSeatType, formatAppError, hasAppAccess, isErrorCode, normalizeError, normalizeThrown, planSeatSummary, resolveSubscriptionTier, seatTypeDescription, seatTypeFromFlags, seatTypeLabel, selectedToWebhookActions, sortedSuiteAiEvents, suiteAiEventSummary, tierAllowsTidesOnlySeats, tierAllowsTurtletime, tierLabel, useIsNight, webhookActionsToSelected };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ConfigDefaults } from 'posthog-js';
2
+
1
3
  declare const ERROR_CODES: {
2
4
  readonly AUTH_001: "E-AUTH-001";
3
5
  readonly AUTH_002: "E-AUTH-002";
@@ -45,9 +47,54 @@ declare function normalizeThrown(input: unknown, capability?: string): AppError;
45
47
  /** Display string for a failure surface: capability copy plus the code. */
46
48
  declare function formatAppError(error: AppError): string;
47
49
 
50
+ /**
51
+ * Global super-properties and event properties accepted by the analytics client.
52
+ * Values may be `null` to clear a previously registered super-property.
53
+ */
54
+ type AnalyticsProperties = Record<string, unknown>;
55
+ /** Headers forwarded on every API request so server events share the web identity. */
56
+ type AnalyticsContextHeaders = Record<string, string>;
57
+ interface AnalyticsClientConfig {
58
+ /** `NEXT_PUBLIC_POSTHOG_KEY`. A missing key makes the client a no-op. */
59
+ apiKey?: string;
60
+ /** `NEXT_PUBLIC_POSTHOG_HOST`, e.g. `https://us.i.posthog.com`. */
61
+ host?: string;
62
+ /** Global `app` super-property, e.g. `turtletime`. */
63
+ app: string;
64
+ /** Global `environment` super-property; defaults to `NODE_ENV`. */
65
+ environment?: string;
66
+ /** PostHog config defaults date. Defaults to `2026-05-30`. */
67
+ defaults?: ConfigDefaults;
68
+ }
69
+ type AnalyticsClient = ReturnType<typeof createAnalyticsClient>;
70
+ /** Domain half of an email — safe to send; the raw address is not. */
71
+ declare function emailDomain(email: string | null | undefined): string | undefined;
72
+ /**
73
+ * Browser analytics client shared across ShellStack apps.
74
+ *
75
+ * Wraps `posthog-js` so every app initialises the same way, registers the same
76
+ * global super-properties, and forwards the browser identity/session ids to the
77
+ * API. The SDK keeps PostHog's defaults (autocapture, pageviews, UTM, browser/OS,
78
+ * referrer) — nothing here disables them.
79
+ */
80
+ declare function createAnalyticsClient(config: AnalyticsClientConfig): {
81
+ init: () => void;
82
+ identify: (userId: string, props?: AnalyticsProperties, setOnceProps?: AnalyticsProperties) => void;
83
+ group: (groupType: string, groupKey: string, props?: AnalyticsProperties) => void;
84
+ capture: (event: string, props?: AnalyticsProperties) => void;
85
+ reset: () => void;
86
+ getDistinctId: () => string | undefined;
87
+ getSessionId: () => string | undefined;
88
+ pageview: () => void;
89
+ registerSuperProperties: (props: AnalyticsProperties) => void;
90
+ getContextHeaders: () => AnalyticsContextHeaders;
91
+ };
92
+
48
93
  type ApiFetchInit = RequestInit & {
49
94
  skipAuth?: boolean;
50
95
  };
96
+ /** Optional analytics sink forwarded client lifecycle events (e.g. `analytics.capture`). */
97
+ type ApiAnalyticsEventSink = (event: string, properties?: Record<string, unknown>) => void;
51
98
  interface ApiClientConfig {
52
99
  /** localStorage key namespace, e.g. `tt` or `tides`. */
53
100
  storagePrefix: string;
@@ -74,6 +121,18 @@ interface ApiClientConfig {
74
121
  sessionStorageClearPrefixes?: string[];
75
122
  /** Refuse to send the session to an unexpected absolute origin. */
76
123
  enforceSameOrigin?: boolean;
124
+ /**
125
+ * Extra headers to attach to every request. Used to forward the PostHog
126
+ * identity/session ids (`X-POSTHOG-DISTINCT-ID` / `X-POSTHOG-SESSION-ID`)
127
+ * so server-side events share the browser identity. Empty values are dropped.
128
+ */
129
+ getContextHeaders?: () => Record<string, string>;
130
+ /**
131
+ * Forward client lifecycle events (`Session Expired`, `Workspace Switched`,
132
+ * `User Logged Out`) to the app's analytics client. Kept as a plain callback
133
+ * so this package never imports an analytics implementation.
134
+ */
135
+ onAnalyticsEvent?: ApiAnalyticsEventSink;
77
136
  }
78
137
  /**
79
138
  * Build a browser API client scoped to one ShellStack app. Every app shares the
@@ -92,7 +151,9 @@ declare function createApiClient(config: ApiClientConfig): {
92
151
  }) => void;
93
152
  getActiveWorkspaceId: () => string | null;
94
153
  restoreWorkspace: () => void;
95
- clearAuth: () => void;
154
+ clearAuth: (options?: {
155
+ origin?: "user" | "session_expired";
156
+ }) => void;
96
157
  restoreTokens: () => void;
97
158
  refreshAccessToken: () => Promise<boolean>;
98
159
  parseApiError: (res: Response) => Promise<string>;
@@ -104,7 +165,9 @@ declare function createApiClient(config: ApiClientConfig): {
104
165
  delete: (path: string, init?: ApiFetchInit) => Promise<Response>;
105
166
  };
106
167
  restoreSession: () => void;
107
- clearSession: () => void;
168
+ clearSession: (options?: {
169
+ origin?: "user" | "session_expired";
170
+ }) => void;
108
171
  };
109
172
  type ApiClient = ReturnType<typeof createApiClient>;
110
173
  type Api = ApiClient['api'];
@@ -117,6 +180,8 @@ interface AuthReturnPathConfig {
117
180
  defaultNext?: string;
118
181
  portalCallbackPath?: string;
119
182
  redeemPath?: string;
183
+ /** Forward the completed cross-app switch to the app's analytics client. */
184
+ onAnalyticsEvent?: (event: string, properties?: Record<string, unknown>) => void;
120
185
  }
121
186
  interface PortalHandoffPayload {
122
187
  code?: string;
@@ -326,6 +391,36 @@ declare function createNotificationsClient(config: NotificationsClientConfig): {
326
391
  markAllSuiteNotificationsRead: () => Promise<void>;
327
392
  };
328
393
 
394
+ /** Browser push state surfaced to settings UI. */
395
+ type WebPushState = 'unsupported' | 'unconfigured' | 'default' | 'granted' | 'denied' | 'subscribed';
396
+ interface WebPushConfig {
397
+ enabled: boolean;
398
+ public_key: string;
399
+ }
400
+ interface WebPushClientConfig {
401
+ api: Api;
402
+ parseApiError: (res: Response) => Promise<string>;
403
+ publicKeyPath?: string;
404
+ subscribePath?: string;
405
+ unsubscribePath?: string;
406
+ serviceWorkerPath?: string;
407
+ serviceWorkerScope?: string;
408
+ }
409
+ type WebPushClient = ReturnType<typeof createWebPushClient>;
410
+ /**
411
+ * Browser Web Push client shared across ShellStack apps.
412
+ *
413
+ * Registration is per origin: each app ships its own `/sw.js` and manifest,
414
+ * but all talk to the same suite endpoints, so a subscription made in one app
415
+ * receives notifications for the whole suite.
416
+ */
417
+ declare function createWebPushClient(config: WebPushClientConfig): {
418
+ supported: () => boolean;
419
+ getState: () => Promise<WebPushState>;
420
+ enable: () => Promise<void>;
421
+ disable: () => Promise<void>;
422
+ };
423
+
329
424
  type SuiteAiJobEvent = {
330
425
  sequence: number;
331
426
  event_type: 'queued' | 'started' | 'progress' | 'tool' | 'completed' | 'failed' | 'cancelled';
@@ -386,4 +481,4 @@ declare function createJsonLd(config: JsonLdConfig): string;
386
481
 
387
482
  declare function useIsNight(): boolean;
388
483
 
389
- export { type Api, type ApiClient, type ApiClientConfig, type ApiFetchInit, type AppError, type AuthReturnPath, type AuthReturnPathConfig, type BrandSettings, type BrandSettingsConfig, type CrossAppSync, type CrossAppSyncConfig, type CrossAppSyncTopic, DEFAULT_ERROR_CODE, ERROR_CODES, ERROR_COPY, ERROR_RETRYABLE, type ErrorCode, FREE_PLAN_SEAT_HELP, type JsonLdConfig, type LiveRefresh, type LiveRefreshOptions, type NotificationsClient, type NotificationsClientConfig, ORGANISATION_SEAT_HELP, type PortalHandoffPayload, type PortalHandoffRead, type SeatType, type SubscriptionTier, type SuiteAiJob, type SuiteAiJobEvent, type SuiteNotification, type SuiteNotificationsResponse, TIDES_ACCESS_HELP, TURTLETIME_ACCESS_HELP, WEBHOOK_ACTIVITY_ACTIONS, WORKSPACE_SEAT_HELP, type WorkspaceAppearance, type WorkspaceAppearanceApiConfig, type WorkspaceAppearanceConfig, WorkspaceAppearanceError, type WorkspaceAppearanceHelpers, type WorkspaceAppearancePatch, type WorkspaceBrandPayload, type WorkspaceSubscription, type WorkspaceTheme, activeSuiteAiJobs, appErrorFromResponse, canDisableAppAccess, codeForStatus, copyFor, createApiClient, createAuthReturnPath, createBrandSettings, createCrossAppSync, createJsonLd, createLiveRefresh, createNotificationsClient, createWorkspaceAppearance, createWorkspaceAppearanceApi, defaultInviteSeatType, flagsFromSeatType, formatAppError, hasAppAccess, isErrorCode, normalizeError, normalizeThrown, planSeatSummary, resolveSubscriptionTier, seatTypeDescription, seatTypeFromFlags, seatTypeLabel, selectedToWebhookActions, sortedSuiteAiEvents, suiteAiEventSummary, tierAllowsTidesOnlySeats, tierAllowsTurtletime, tierLabel, useIsNight, webhookActionsToSelected };
484
+ export { type AnalyticsClient, type AnalyticsClientConfig, type AnalyticsContextHeaders, type AnalyticsProperties, type Api, type ApiAnalyticsEventSink, type ApiClient, type ApiClientConfig, type ApiFetchInit, type AppError, type AuthReturnPath, type AuthReturnPathConfig, type BrandSettings, type BrandSettingsConfig, type CrossAppSync, type CrossAppSyncConfig, type CrossAppSyncTopic, DEFAULT_ERROR_CODE, ERROR_CODES, ERROR_COPY, ERROR_RETRYABLE, type ErrorCode, FREE_PLAN_SEAT_HELP, type JsonLdConfig, type LiveRefresh, type LiveRefreshOptions, type NotificationsClient, type NotificationsClientConfig, ORGANISATION_SEAT_HELP, type PortalHandoffPayload, type PortalHandoffRead, type SeatType, type SubscriptionTier, type SuiteAiJob, type SuiteAiJobEvent, type SuiteNotification, type SuiteNotificationsResponse, TIDES_ACCESS_HELP, TURTLETIME_ACCESS_HELP, WEBHOOK_ACTIVITY_ACTIONS, WORKSPACE_SEAT_HELP, type WebPushClient, type WebPushClientConfig, type WebPushConfig, type WebPushState, type WorkspaceAppearance, type WorkspaceAppearanceApiConfig, type WorkspaceAppearanceConfig, WorkspaceAppearanceError, type WorkspaceAppearanceHelpers, type WorkspaceAppearancePatch, type WorkspaceBrandPayload, type WorkspaceSubscription, type WorkspaceTheme, activeSuiteAiJobs, appErrorFromResponse, canDisableAppAccess, codeForStatus, copyFor, createAnalyticsClient, createApiClient, createAuthReturnPath, createBrandSettings, createCrossAppSync, createJsonLd, createLiveRefresh, createNotificationsClient, createWebPushClient, createWorkspaceAppearance, createWorkspaceAppearanceApi, defaultInviteSeatType, emailDomain, flagsFromSeatType, formatAppError, hasAppAccess, isErrorCode, normalizeError, normalizeThrown, planSeatSummary, resolveSubscriptionTier, seatTypeDescription, seatTypeFromFlags, seatTypeLabel, selectedToWebhookActions, sortedSuiteAiEvents, suiteAiEventSummary, tierAllowsTidesOnlySeats, tierAllowsTurtletime, tierLabel, useIsNight, webhookActionsToSelected };