@graph8/sdk 0.11.0 → 0.12.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/README.md CHANGED
@@ -251,6 +251,57 @@ export const CTA = () => {
251
251
  | `g8.webhooks.constructEvent(body, sig, ts, secret, opts?)` | Verify a delivery's HMAC signature and return the parsed event (throws `WebhookSignatureError`) |
252
252
  | `g8.webhooks.knownEvents` | The known event-type catalog |
253
253
 
254
+ ## App Platform
255
+
256
+ Hosted apps do not carry a permanent org API key. Instead they **exchange** a
257
+ longer-lived credential for a short-lived graph8 app token, and the client
258
+ mints, refreshes, and attaches it for you. Both clients expose a token-bound
259
+ `request()` that reaches the existing Developer API resources with the app
260
+ token.
261
+
262
+ ### Browser (PropelAuth token exchange)
263
+
264
+ ```typescript
265
+ import { createGraph8AppClient } from '@graph8/sdk';
266
+
267
+ // Exchange the signed-in user's PropelAuth token for a short-lived graph8 app
268
+ // token. The client refreshes it on/near expiry and attaches
269
+ // `Authorization: Bearer <app-token>` to every call — no API key in the browser.
270
+ const appClient = createGraph8AppClient({
271
+ appId: 'dapp_your_app',
272
+ tenantOrgId: 'org_customer',
273
+ scopes: ['objects:read'],
274
+ getPropelAuthToken: () => localStorage.getItem('propelauth_token') ?? '',
275
+ });
276
+
277
+ // Reach the existing resources with the app token via request():
278
+ const { data: contacts } = await appClient.request<{ data: unknown[] }>(
279
+ '/api/v1/contacts',
280
+ { query: { limit: 10 } },
281
+ );
282
+ ```
283
+
284
+ ### Backend (service credentials)
285
+
286
+ ```typescript
287
+ import { createGraph8ServiceClient } from '@graph8/sdk';
288
+
289
+ // Exchange service client-credentials for a service token. Every call is pinned
290
+ // to the one consented tenant via the `X-Target-Org-Id` header the client adds.
291
+ const service = createGraph8ServiceClient({
292
+ clientId: process.env.G8_APP_CLIENT_ID,
293
+ clientSecret: process.env.G8_APP_CLIENT_SECRET,
294
+ tenantOrgId: 'org_customer',
295
+ scopes: ['objects:read', 'objects:write'],
296
+ });
297
+
298
+ const { data: rows } = await service.request<{ data: unknown[] }>('/api/v1/contacts');
299
+ ```
300
+
301
+ > The typed `apps` (control-plane) and `objects` (custom-object CRUD) resource
302
+ > modules are deferred until their backend routes ship (M6-3 / M6-5). Until then,
303
+ > reach the Developer API through the token-bound `request()` shown above.
304
+
254
305
  ## Auth Modes
255
306
 
256
307
  | Mode | Key | Use case |
package/dist/index.d.mts CHANGED
@@ -4016,4 +4016,229 @@ interface PaginatedResponse<T> {
4016
4016
  */
4017
4017
  declare function paginate<T>(fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>): AsyncGenerator<T, void, unknown>;
4018
4018
 
4019
- export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type CopilotConfig, type CreatedField, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, g8, isRetryableStatus, paginate, parseRetryAfter, request };
4019
+ /**
4020
+ * App-platform token exchange + refresh core (M6-9).
4021
+ *
4022
+ * The hosted-app clients never carry a permanent org API key. Instead they mint
4023
+ * SHORT-LIVED app tokens by EXCHANGING a longer-lived credential, and refresh
4024
+ * them on/near expiry:
4025
+ *
4026
+ * - browser apps exchange the caller's PropelAuth login at
4027
+ * `POST /api/v1/app-sessions/exchange` (identity is derived server-side from
4028
+ * the validated principal — the body only names the target app + scopes);
4029
+ * - hosted backends exchange service client-credentials at
4030
+ * `POST /api/v1/service-token`.
4031
+ *
4032
+ * Both endpoints answer with the reused `ApiResponse` envelope wrapping a
4033
+ * `TokenResponse` (see developer_api/app_platform/app_tokens/dtos.py). This
4034
+ * module owns:
4035
+ *
4036
+ * - `AppTokenResponse` — the minted-token payload shape (frozen wire contract);
4037
+ * - `createTokenManager` — caches a token, refreshes it on/near expiry, and
4038
+ * de-dupes concurrent refreshes into one in-flight exchange;
4039
+ * - `createAppRequester` — binds the managed token onto the hardened
4040
+ * `request()` core (typed `G8Error`, retries, idempotency, pagination),
4041
+ * attaching `Authorization: Bearer <app-token>` (plus any static header such
4042
+ * as a service client's `X-Target-Org-Id`) and refreshing once on a 401.
4043
+ *
4044
+ * The backend app-token API is INERT/unmounted today (behind a deny-by-default
4045
+ * flag), so these paths are exercised against mocked HTTP, never a live server.
4046
+ */
4047
+ declare const DEFAULT_APP_API = "https://be.graph8.com";
4048
+ /** The minted app token + the non-secret metadata a client reads back.
4049
+ * Mirrors `TokenResponse` in developer_api/app_platform/app_tokens/dtos.py. */
4050
+ interface AppTokenResponse {
4051
+ /** The signed app JWT (attach as `Authorization: Bearer <access_token>`). */
4052
+ access_token: string;
4053
+ /** Always "Bearer". */
4054
+ token_type: string;
4055
+ /** Lifetime in seconds from issuance. */
4056
+ expires_in: number;
4057
+ /** The distinct-per-app, per-environment audience. */
4058
+ audience: string;
4059
+ /** App the token is bound to (dapp_-prefixed). */
4060
+ app_id: string;
4061
+ /** Signing key id (matches a JWKS entry). */
4062
+ kid: string;
4063
+ }
4064
+ /** Per-request options accepted by an {@link AppRequest}. A subset of the
4065
+ * hardened core's `RequestOptions` — auth (the app token) and the injected
4066
+ * fetch/sleep seams are bound by the requester, not passed per call. */
4067
+ interface AppRequestOptions {
4068
+ method?: string;
4069
+ body?: unknown;
4070
+ headers?: Record<string, string>;
4071
+ query?: Record<string, unknown>;
4072
+ /** Sent as `Idempotency-Key` for safe POST/PATCH retries. */
4073
+ idempotencyKey?: string;
4074
+ /** Max retry attempts on 429/5xx/network (default 2). */
4075
+ maxRetries?: number;
4076
+ /** Base backoff in ms (default 200). */
4077
+ retryBaseMs?: number;
4078
+ signal?: AbortSignal;
4079
+ }
4080
+ /** A token-bound request function: same ergonomics as the raw `request()` core
4081
+ * minus the credential, which the token manager supplies. */
4082
+ type AppRequest = <T = unknown>(path: string, opts?: AppRequestOptions) => Promise<T>;
4083
+ /** Caches + refreshes one app token. */
4084
+ interface TokenManager {
4085
+ /** Return a valid token, refreshing on/near expiry. `force` refreshes now. */
4086
+ getToken(force?: boolean): Promise<string>;
4087
+ /** Current token expiry as an epoch-ms timestamp (0 before the first mint). */
4088
+ expiresAt(): number;
4089
+ }
4090
+ /**
4091
+ * Build a token manager over a `refresh` exchange.
4092
+ *
4093
+ * Freshness rule: a cached token is reused until it is within `refreshSkewMs`
4094
+ * of expiry, then a refresh is triggered. Concurrent callers during a refresh
4095
+ * share ONE in-flight exchange (no stampede). `now` is injectable for tests.
4096
+ */
4097
+ declare function createTokenManager(args: {
4098
+ refresh: () => Promise<AppTokenResponse>;
4099
+ now?: () => number;
4100
+ refreshSkewMs?: number;
4101
+ }): TokenManager;
4102
+ /**
4103
+ * Bind a {@link TokenManager} onto the hardened `request()` core.
4104
+ *
4105
+ * Every call fetches the current token, attaches `Authorization: Bearer …`
4106
+ * (plus any `extraHeaders`, e.g. a service client's `X-Target-Org-Id`), and
4107
+ * reuses all of the core's typed errors / retries / idempotency. On a 401 —
4108
+ * a token revoked or gone stale mid-window — it force-refreshes ONCE and retries.
4109
+ */
4110
+ declare function createAppRequester(args: {
4111
+ baseUrl: string;
4112
+ tokens: TokenManager;
4113
+ extraHeaders?: Record<string, string>;
4114
+ fetchImpl?: typeof fetch;
4115
+ sleepImpl?: (ms: number) => Promise<void>;
4116
+ }): AppRequest;
4117
+ /**
4118
+ * Exchange the caller's PropelAuth token for a short-lived BROWSER app token.
4119
+ * `POST /api/v1/app-sessions/exchange` (body = target app + scopes only;
4120
+ * identity/role/tenant are derived server-side from the validated principal).
4121
+ */
4122
+ declare function exchangeBrowserToken(args: {
4123
+ baseUrl: string;
4124
+ appId: string;
4125
+ scopes?: string[];
4126
+ getPropelAuthToken: () => string | Promise<string>;
4127
+ fetchImpl?: typeof fetch;
4128
+ sleepImpl?: (ms: number) => Promise<void>;
4129
+ }): Promise<AppTokenResponse>;
4130
+ /**
4131
+ * Exchange service client-credentials for a SERVICE app token.
4132
+ * `POST /api/v1/service-token` — credentials travel in the body; this endpoint
4133
+ * has no bearer auth, so no `Authorization` is sent on the exchange itself.
4134
+ */
4135
+ declare function exchangeServiceToken(args: {
4136
+ baseUrl: string;
4137
+ clientId: string;
4138
+ clientSecret: string;
4139
+ scopes?: string[];
4140
+ ttlSeconds?: number;
4141
+ fetchImpl?: typeof fetch;
4142
+ sleepImpl?: (ms: number) => Promise<void>;
4143
+ }): Promise<AppTokenResponse>;
4144
+
4145
+ /**
4146
+ * Hosted app-platform clients (M6-9).
4147
+ *
4148
+ * Two entry points, both additive to `@graph8/sdk` and independent of the
4149
+ * `g8` tracking/API-key singleton:
4150
+ *
4151
+ * - `createGraph8AppClient` — BROWSER client. Exchanges the caller's
4152
+ * PropelAuth token for a short-lived app token, refreshes it on/near expiry,
4153
+ * and attaches `Authorization: Bearer <app-token>` to every call. It NEVER
4154
+ * accepts a permanent org API key for browser init (the whole reason the
4155
+ * token-exchange exists).
4156
+ * - `createGraph8ServiceClient` — BACKEND client. Exchanges service
4157
+ * client-credentials for a service app token and sends `X-Target-Org-Id`
4158
+ * for the single configured tenant on every call.
4159
+ *
4160
+ * Both expose a token-bound `request()` — the hardened `request()` core with the
4161
+ * minted app token attached — so callers reach Developer API routes with the
4162
+ * app token and reuse the core's typed `G8Error`, retries, idempotency, and
4163
+ * cursor pagination. The typed `apps` (control-plane) and `objects`
4164
+ * (custom-object CRUD) resource modules are DEFERRED until their backend routes
4165
+ * ship and freeze (M6-3 / M6-5); only the auth clients ship here.
4166
+ */
4167
+
4168
+ /** Config for {@link createGraph8AppClient} (browser). No API key is accepted. */
4169
+ interface Graph8AppClientConfig {
4170
+ /** Target app id (dapp_-prefixed). */
4171
+ appId: string;
4172
+ /** The client org this browser session acts in (informational; the server
4173
+ * derives the authoritative tenant from the validated PropelAuth principal). */
4174
+ tenantOrgId: string;
4175
+ /** Returns the caller's current PropelAuth token (sync or async). */
4176
+ getPropelAuthToken: () => string | Promise<string>;
4177
+ /** Scopes to embed in the minted app token. */
4178
+ scopes?: string[];
4179
+ /** Backend API URL (default https://be.graph8.com). */
4180
+ apiUrl?: string;
4181
+ /** Refresh this many ms before expiry (default 60_000). */
4182
+ refreshSkewMs?: number;
4183
+ /** Injected for tests; defaults to global fetch. */
4184
+ fetchImpl?: typeof fetch;
4185
+ /** Injected for tests; defaults to a real setTimeout sleep. */
4186
+ sleepImpl?: (ms: number) => Promise<void>;
4187
+ /** Injected for tests; defaults to Date.now. */
4188
+ now?: () => number;
4189
+ }
4190
+ /** A browser app-platform client. */
4191
+ interface Graph8AppClient {
4192
+ readonly appId: string;
4193
+ readonly tenantOrgId: string;
4194
+ /** Token-bound requester: mints/refreshes the app token and attaches
4195
+ * `Authorization: Bearer <app-token>` to every Developer API call. */
4196
+ readonly request: AppRequest;
4197
+ /** Return the current app token, refreshing on/near expiry (`force` refreshes now). */
4198
+ getAppToken(force?: boolean): Promise<string>;
4199
+ }
4200
+ /**
4201
+ * Create a BROWSER app-platform client backed by PropelAuth->app-token exchange.
4202
+ * Refuses an org API key / write key — those must never reach a browser.
4203
+ */
4204
+ declare function createGraph8AppClient(config: Graph8AppClientConfig): Graph8AppClient;
4205
+ /** Config for {@link createGraph8ServiceClient} (backend / server-to-server). */
4206
+ interface Graph8ServiceClientConfig {
4207
+ /** Service credential client id. */
4208
+ clientId: string;
4209
+ /** Service credential client secret (checked against the stored hash). */
4210
+ clientSecret: string;
4211
+ /** The single consented client org this backend acts for (sent as X-Target-Org-Id). */
4212
+ tenantOrgId: string;
4213
+ /** Scopes to embed in the minted service token. */
4214
+ scopes?: string[];
4215
+ /** Requested token TTL; the server clamps it into its service band. */
4216
+ ttlSeconds?: number;
4217
+ /** Backend API URL (default https://be.graph8.com). */
4218
+ apiUrl?: string;
4219
+ /** Refresh this many ms before expiry (default 60_000). */
4220
+ refreshSkewMs?: number;
4221
+ /** Injected for tests; defaults to global fetch. */
4222
+ fetchImpl?: typeof fetch;
4223
+ /** Injected for tests; defaults to a real setTimeout sleep. */
4224
+ sleepImpl?: (ms: number) => Promise<void>;
4225
+ /** Injected for tests; defaults to Date.now. */
4226
+ now?: () => number;
4227
+ }
4228
+ /** A backend service app-platform client. */
4229
+ interface Graph8ServiceClient {
4230
+ readonly tenantOrgId: string;
4231
+ /** Token-bound requester: mints/refreshes the service token, attaches it, and
4232
+ * sends `X-Target-Org-Id` for the one consented tenant on every call. */
4233
+ readonly request: AppRequest;
4234
+ /** Return the current service token, refreshing on/near expiry (`force` refreshes now). */
4235
+ getServiceToken(force?: boolean): Promise<string>;
4236
+ }
4237
+ /**
4238
+ * Create a BACKEND service client backed by client-credentials->service-token
4239
+ * exchange. Every request carries `X-Target-Org-Id: <tenantOrgId>` for the one
4240
+ * configured consented tenant.
4241
+ */
4242
+ declare function createGraph8ServiceClient(config: Graph8ServiceClientConfig): Graph8ServiceClient;
4243
+
4244
+ export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type AppRequest, type AppRequestOptions, type AppTokenResponse, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type CopilotConfig, type CreatedField, DEFAULT_APP_API, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type Graph8AppClient, type Graph8AppClientConfig, type Graph8ServiceClient, type Graph8ServiceClientConfig, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TokenManager, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, createAppRequester, createGraph8AppClient, createGraph8ServiceClient, createTokenManager, exchangeBrowserToken, exchangeServiceToken, g8, isRetryableStatus, paginate, parseRetryAfter, request };
package/dist/index.d.ts CHANGED
@@ -4016,4 +4016,229 @@ interface PaginatedResponse<T> {
4016
4016
  */
4017
4017
  declare function paginate<T>(fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>): AsyncGenerator<T, void, unknown>;
4018
4018
 
4019
- export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type CopilotConfig, type CreatedField, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, g8, isRetryableStatus, paginate, parseRetryAfter, request };
4019
+ /**
4020
+ * App-platform token exchange + refresh core (M6-9).
4021
+ *
4022
+ * The hosted-app clients never carry a permanent org API key. Instead they mint
4023
+ * SHORT-LIVED app tokens by EXCHANGING a longer-lived credential, and refresh
4024
+ * them on/near expiry:
4025
+ *
4026
+ * - browser apps exchange the caller's PropelAuth login at
4027
+ * `POST /api/v1/app-sessions/exchange` (identity is derived server-side from
4028
+ * the validated principal — the body only names the target app + scopes);
4029
+ * - hosted backends exchange service client-credentials at
4030
+ * `POST /api/v1/service-token`.
4031
+ *
4032
+ * Both endpoints answer with the reused `ApiResponse` envelope wrapping a
4033
+ * `TokenResponse` (see developer_api/app_platform/app_tokens/dtos.py). This
4034
+ * module owns:
4035
+ *
4036
+ * - `AppTokenResponse` — the minted-token payload shape (frozen wire contract);
4037
+ * - `createTokenManager` — caches a token, refreshes it on/near expiry, and
4038
+ * de-dupes concurrent refreshes into one in-flight exchange;
4039
+ * - `createAppRequester` — binds the managed token onto the hardened
4040
+ * `request()` core (typed `G8Error`, retries, idempotency, pagination),
4041
+ * attaching `Authorization: Bearer <app-token>` (plus any static header such
4042
+ * as a service client's `X-Target-Org-Id`) and refreshing once on a 401.
4043
+ *
4044
+ * The backend app-token API is INERT/unmounted today (behind a deny-by-default
4045
+ * flag), so these paths are exercised against mocked HTTP, never a live server.
4046
+ */
4047
+ declare const DEFAULT_APP_API = "https://be.graph8.com";
4048
+ /** The minted app token + the non-secret metadata a client reads back.
4049
+ * Mirrors `TokenResponse` in developer_api/app_platform/app_tokens/dtos.py. */
4050
+ interface AppTokenResponse {
4051
+ /** The signed app JWT (attach as `Authorization: Bearer <access_token>`). */
4052
+ access_token: string;
4053
+ /** Always "Bearer". */
4054
+ token_type: string;
4055
+ /** Lifetime in seconds from issuance. */
4056
+ expires_in: number;
4057
+ /** The distinct-per-app, per-environment audience. */
4058
+ audience: string;
4059
+ /** App the token is bound to (dapp_-prefixed). */
4060
+ app_id: string;
4061
+ /** Signing key id (matches a JWKS entry). */
4062
+ kid: string;
4063
+ }
4064
+ /** Per-request options accepted by an {@link AppRequest}. A subset of the
4065
+ * hardened core's `RequestOptions` — auth (the app token) and the injected
4066
+ * fetch/sleep seams are bound by the requester, not passed per call. */
4067
+ interface AppRequestOptions {
4068
+ method?: string;
4069
+ body?: unknown;
4070
+ headers?: Record<string, string>;
4071
+ query?: Record<string, unknown>;
4072
+ /** Sent as `Idempotency-Key` for safe POST/PATCH retries. */
4073
+ idempotencyKey?: string;
4074
+ /** Max retry attempts on 429/5xx/network (default 2). */
4075
+ maxRetries?: number;
4076
+ /** Base backoff in ms (default 200). */
4077
+ retryBaseMs?: number;
4078
+ signal?: AbortSignal;
4079
+ }
4080
+ /** A token-bound request function: same ergonomics as the raw `request()` core
4081
+ * minus the credential, which the token manager supplies. */
4082
+ type AppRequest = <T = unknown>(path: string, opts?: AppRequestOptions) => Promise<T>;
4083
+ /** Caches + refreshes one app token. */
4084
+ interface TokenManager {
4085
+ /** Return a valid token, refreshing on/near expiry. `force` refreshes now. */
4086
+ getToken(force?: boolean): Promise<string>;
4087
+ /** Current token expiry as an epoch-ms timestamp (0 before the first mint). */
4088
+ expiresAt(): number;
4089
+ }
4090
+ /**
4091
+ * Build a token manager over a `refresh` exchange.
4092
+ *
4093
+ * Freshness rule: a cached token is reused until it is within `refreshSkewMs`
4094
+ * of expiry, then a refresh is triggered. Concurrent callers during a refresh
4095
+ * share ONE in-flight exchange (no stampede). `now` is injectable for tests.
4096
+ */
4097
+ declare function createTokenManager(args: {
4098
+ refresh: () => Promise<AppTokenResponse>;
4099
+ now?: () => number;
4100
+ refreshSkewMs?: number;
4101
+ }): TokenManager;
4102
+ /**
4103
+ * Bind a {@link TokenManager} onto the hardened `request()` core.
4104
+ *
4105
+ * Every call fetches the current token, attaches `Authorization: Bearer …`
4106
+ * (plus any `extraHeaders`, e.g. a service client's `X-Target-Org-Id`), and
4107
+ * reuses all of the core's typed errors / retries / idempotency. On a 401 —
4108
+ * a token revoked or gone stale mid-window — it force-refreshes ONCE and retries.
4109
+ */
4110
+ declare function createAppRequester(args: {
4111
+ baseUrl: string;
4112
+ tokens: TokenManager;
4113
+ extraHeaders?: Record<string, string>;
4114
+ fetchImpl?: typeof fetch;
4115
+ sleepImpl?: (ms: number) => Promise<void>;
4116
+ }): AppRequest;
4117
+ /**
4118
+ * Exchange the caller's PropelAuth token for a short-lived BROWSER app token.
4119
+ * `POST /api/v1/app-sessions/exchange` (body = target app + scopes only;
4120
+ * identity/role/tenant are derived server-side from the validated principal).
4121
+ */
4122
+ declare function exchangeBrowserToken(args: {
4123
+ baseUrl: string;
4124
+ appId: string;
4125
+ scopes?: string[];
4126
+ getPropelAuthToken: () => string | Promise<string>;
4127
+ fetchImpl?: typeof fetch;
4128
+ sleepImpl?: (ms: number) => Promise<void>;
4129
+ }): Promise<AppTokenResponse>;
4130
+ /**
4131
+ * Exchange service client-credentials for a SERVICE app token.
4132
+ * `POST /api/v1/service-token` — credentials travel in the body; this endpoint
4133
+ * has no bearer auth, so no `Authorization` is sent on the exchange itself.
4134
+ */
4135
+ declare function exchangeServiceToken(args: {
4136
+ baseUrl: string;
4137
+ clientId: string;
4138
+ clientSecret: string;
4139
+ scopes?: string[];
4140
+ ttlSeconds?: number;
4141
+ fetchImpl?: typeof fetch;
4142
+ sleepImpl?: (ms: number) => Promise<void>;
4143
+ }): Promise<AppTokenResponse>;
4144
+
4145
+ /**
4146
+ * Hosted app-platform clients (M6-9).
4147
+ *
4148
+ * Two entry points, both additive to `@graph8/sdk` and independent of the
4149
+ * `g8` tracking/API-key singleton:
4150
+ *
4151
+ * - `createGraph8AppClient` — BROWSER client. Exchanges the caller's
4152
+ * PropelAuth token for a short-lived app token, refreshes it on/near expiry,
4153
+ * and attaches `Authorization: Bearer <app-token>` to every call. It NEVER
4154
+ * accepts a permanent org API key for browser init (the whole reason the
4155
+ * token-exchange exists).
4156
+ * - `createGraph8ServiceClient` — BACKEND client. Exchanges service
4157
+ * client-credentials for a service app token and sends `X-Target-Org-Id`
4158
+ * for the single configured tenant on every call.
4159
+ *
4160
+ * Both expose a token-bound `request()` — the hardened `request()` core with the
4161
+ * minted app token attached — so callers reach Developer API routes with the
4162
+ * app token and reuse the core's typed `G8Error`, retries, idempotency, and
4163
+ * cursor pagination. The typed `apps` (control-plane) and `objects`
4164
+ * (custom-object CRUD) resource modules are DEFERRED until their backend routes
4165
+ * ship and freeze (M6-3 / M6-5); only the auth clients ship here.
4166
+ */
4167
+
4168
+ /** Config for {@link createGraph8AppClient} (browser). No API key is accepted. */
4169
+ interface Graph8AppClientConfig {
4170
+ /** Target app id (dapp_-prefixed). */
4171
+ appId: string;
4172
+ /** The client org this browser session acts in (informational; the server
4173
+ * derives the authoritative tenant from the validated PropelAuth principal). */
4174
+ tenantOrgId: string;
4175
+ /** Returns the caller's current PropelAuth token (sync or async). */
4176
+ getPropelAuthToken: () => string | Promise<string>;
4177
+ /** Scopes to embed in the minted app token. */
4178
+ scopes?: string[];
4179
+ /** Backend API URL (default https://be.graph8.com). */
4180
+ apiUrl?: string;
4181
+ /** Refresh this many ms before expiry (default 60_000). */
4182
+ refreshSkewMs?: number;
4183
+ /** Injected for tests; defaults to global fetch. */
4184
+ fetchImpl?: typeof fetch;
4185
+ /** Injected for tests; defaults to a real setTimeout sleep. */
4186
+ sleepImpl?: (ms: number) => Promise<void>;
4187
+ /** Injected for tests; defaults to Date.now. */
4188
+ now?: () => number;
4189
+ }
4190
+ /** A browser app-platform client. */
4191
+ interface Graph8AppClient {
4192
+ readonly appId: string;
4193
+ readonly tenantOrgId: string;
4194
+ /** Token-bound requester: mints/refreshes the app token and attaches
4195
+ * `Authorization: Bearer <app-token>` to every Developer API call. */
4196
+ readonly request: AppRequest;
4197
+ /** Return the current app token, refreshing on/near expiry (`force` refreshes now). */
4198
+ getAppToken(force?: boolean): Promise<string>;
4199
+ }
4200
+ /**
4201
+ * Create a BROWSER app-platform client backed by PropelAuth->app-token exchange.
4202
+ * Refuses an org API key / write key — those must never reach a browser.
4203
+ */
4204
+ declare function createGraph8AppClient(config: Graph8AppClientConfig): Graph8AppClient;
4205
+ /** Config for {@link createGraph8ServiceClient} (backend / server-to-server). */
4206
+ interface Graph8ServiceClientConfig {
4207
+ /** Service credential client id. */
4208
+ clientId: string;
4209
+ /** Service credential client secret (checked against the stored hash). */
4210
+ clientSecret: string;
4211
+ /** The single consented client org this backend acts for (sent as X-Target-Org-Id). */
4212
+ tenantOrgId: string;
4213
+ /** Scopes to embed in the minted service token. */
4214
+ scopes?: string[];
4215
+ /** Requested token TTL; the server clamps it into its service band. */
4216
+ ttlSeconds?: number;
4217
+ /** Backend API URL (default https://be.graph8.com). */
4218
+ apiUrl?: string;
4219
+ /** Refresh this many ms before expiry (default 60_000). */
4220
+ refreshSkewMs?: number;
4221
+ /** Injected for tests; defaults to global fetch. */
4222
+ fetchImpl?: typeof fetch;
4223
+ /** Injected for tests; defaults to a real setTimeout sleep. */
4224
+ sleepImpl?: (ms: number) => Promise<void>;
4225
+ /** Injected for tests; defaults to Date.now. */
4226
+ now?: () => number;
4227
+ }
4228
+ /** A backend service app-platform client. */
4229
+ interface Graph8ServiceClient {
4230
+ readonly tenantOrgId: string;
4231
+ /** Token-bound requester: mints/refreshes the service token, attaches it, and
4232
+ * sends `X-Target-Org-Id` for the one consented tenant on every call. */
4233
+ readonly request: AppRequest;
4234
+ /** Return the current service token, refreshing on/near expiry (`force` refreshes now). */
4235
+ getServiceToken(force?: boolean): Promise<string>;
4236
+ }
4237
+ /**
4238
+ * Create a BACKEND service client backed by client-credentials->service-token
4239
+ * exchange. Every request carries `X-Target-Org-Id: <tenantOrgId>` for the one
4240
+ * configured consented tenant.
4241
+ */
4242
+ declare function createGraph8ServiceClient(config: Graph8ServiceClientConfig): Graph8ServiceClient;
4243
+
4244
+ export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type AppRequest, type AppRequestOptions, type AppTokenResponse, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type CopilotConfig, type CreatedField, DEFAULT_APP_API, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type Graph8AppClient, type Graph8AppClientConfig, type Graph8ServiceClient, type Graph8ServiceClientConfig, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TokenManager, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, createAppRequester, createGraph8AppClient, createGraph8ServiceClient, createTokenManager, exchangeBrowserToken, exchangeServiceToken, g8, isRetryableStatus, paginate, parseRetryAfter, request };