@usergist/sdk-core 0.1.0 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/segment-dsl.ts","../src/types/recipient.ts","../src/types/api.ts","../src/types/survey.ts","../src/types/inapp-message.ts","../src/types/request.ts","../src/types/targeting.ts","../src/types/themes.ts","../src/types/brand.ts","../src/types/integration.ts","../src/constants/push-events.ts","../src/constants/billing-plans.ts","../src/types/push-runtime.ts","../src/evaluate/segment.ts","../src/evaluate/branch.ts","../src/evaluate/periodic.ts","../src/contract/endpoints.ts","../src/schemas/index.ts","../src/schemas/primitives.ts","../src/schemas/auth.ts","../src/schemas/apps.ts"],"names":["cutoff","z"],"mappings":"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","file":"index.cjs","sourcesContent":["// ==========================================================\n// Segment DSL (shared between server and SDK). The DSL is a\n// JSON structure — not raw SQL — so that:\n// 1. The dashboard UI can safely build/edit rules.\n// 2. The SDK can evaluate a lightweight subset client-side\n// for instant trigger firing (the server re-verifies).\n// 3. The server can compile the full DSL to ClickHouse SQL.\n// ==========================================================\n\nexport type ScalarValue = string | number | boolean\nexport type ScalarList = ReadonlyArray<string | number>\n\nexport type ComparisonOp =\n | 'eq'\n | 'neq'\n | 'in'\n | 'nin'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'contains'\n | 'starts_with'\n | 'exists'\n | 'not_exists'\n\nexport interface UserPropertyPredicate {\n readonly kind: 'user_property'\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: ScalarValue | ScalarList\n}\n\nexport type CountOp = 'gte' | 'lte' | 'eq' | 'gt' | 'lt'\n\nexport interface EventCountPredicate {\n readonly kind: 'event_count'\n readonly eventName: string\n readonly op: CountOp\n readonly count: number\n readonly windowDays: number\n readonly propertyFilters?: ReadonlyArray<UserPropertyPredicate>\n}\n\nexport interface EventOccurredPredicate {\n readonly kind: 'event_occurred'\n readonly eventName: string\n readonly ever: boolean // true => \"has ever done X\", false => \"has never done X\"\n readonly windowDays?: number\n}\n\nexport type Predicate =\n | UserPropertyPredicate\n | EventCountPredicate\n | EventOccurredPredicate\n\nexport type Combinator = 'AND' | 'OR'\n\nexport interface PredicateGroup {\n readonly combinator: Combinator\n readonly predicates: ReadonlyArray<Predicate | PredicateGroup>\n}\n\nexport interface SegmentDsl {\n readonly version: 1\n readonly root: PredicateGroup\n}\n\nexport function emptySegmentDsl(): SegmentDsl {\n return { version: 1, root: { combinator: 'AND', predicates: [] } }\n}\n","import type { PromptResponse } from './response.js'\nimport type { SurveyAttemptSource, SurveyResponseRecord } from './survey.js'\n\nexport const RECIPIENTS_LIMIT = 100\n\nexport interface RecipientIdentity {\n readonly anonymousId: string\n readonly externalId: string | null\n readonly country: string | null\n readonly platform: string | null\n}\n\nexport interface RecipientList<T> {\n readonly items: ReadonlyArray<T>\n readonly total: number\n readonly limit: number\n}\n\nexport interface FeedbackRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly response: PromptResponse | null\n}\n\nexport type InAppRecipientStatus =\n | 'viewed'\n | 'dismissed'\n | 'auto_dismissed'\n | 'cta_clicked'\n\nexport interface InAppRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly status: InAppRecipientStatus\n readonly actionAt: string | null\n readonly ctaLabel: string | null\n}\n\nexport type SurveyRecipientStatus =\n | 'received'\n | 'declined'\n | 'in_progress'\n | 'completed'\n | 'abandoned'\n\nexport interface SurveyRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly source: SurveyAttemptSource\n readonly status: SurveyRecipientStatus\n readonly attemptId: string | null\n readonly startedAt: string | null\n readonly completedAt: string | null\n readonly abandonedAt: string | null\n readonly responses: ReadonlyArray<SurveyResponseRecord>\n}\n","export interface ApiError {\n readonly code: string\n readonly message: string\n readonly details?: unknown\n}\n\nexport interface ApiMeta {\n readonly total?: number\n readonly page?: number\n readonly limit?: number\n}\n\nexport interface ApiResponse<T> {\n readonly success: boolean\n readonly data?: T\n readonly error?: ApiError\n readonly meta?: ApiMeta\n}\n\nexport function ok<T>(data: T, meta?: ApiMeta): ApiResponse<T> {\n return meta ? { success: true, data, meta } : { success: true, data }\n}\n\nexport function err(\n code: string,\n message: string,\n details?: unknown,\n): ApiResponse<never> {\n return {\n success: false,\n error: details === undefined ? { code, message } : { code, message, details },\n }\n}\n","// ============================================================\n// Survey types — shared between API, dashboard, and SDKs.\n// A survey is a Campaign with type='survey'. The multi-step\n// question graph + branching lives here.\n// ============================================================\n\nimport type { PromptTheme, FrequencyCaps, SerializedSegmentRules } from './prompt.js'\nimport type { PushFrequencyCap, PushSchedule } from './campaign.js'\nimport type { AudienceSpec, TriggerSpec } from './targeting.js'\nimport type { ThemeMode } from './brand.js'\n\nexport type SurveyQuestionType =\n | 'single_choice'\n | 'multi_choice'\n | 'nps'\n | 'rating'\n | 'likert'\n | 'short_text'\n | 'long_text'\n | 'ranking'\n | 'single_date'\n | 'info_screen'\n\nexport type SurveyProgressStyle = 'bar' | 'dots' | 'none'\n\nexport interface SurveyChoiceOption {\n readonly id: string\n readonly label: string\n}\n\nexport interface SurveyTextValidation {\n readonly kind?: 'email' | 'url' | 'number' | 'regex'\n readonly pattern?: string\n readonly minLength?: number\n readonly maxLength?: number\n}\n\nexport interface BaseSurveyQuestion {\n readonly id: string\n readonly title: string\n readonly subtitle?: string\n readonly required?: boolean\n // Optional image rendered above the question title. Uploaded\n // through the dashboard composer; URL points at the public R2\n // bucket.\n readonly imageUrl?: string\n readonly mergeTagContext?: Readonly<Record<string, unknown>>\n}\n\nexport interface SingleChoiceQuestion extends BaseSurveyQuestion {\n readonly type: 'single_choice'\n readonly options: ReadonlyArray<SurveyChoiceOption>\n readonly allowOther?: boolean\n}\n\nexport interface MultiChoiceQuestion extends BaseSurveyQuestion {\n readonly type: 'multi_choice'\n readonly options: ReadonlyArray<SurveyChoiceOption>\n readonly minSelections?: number\n readonly maxSelections?: number\n readonly allowOther?: boolean\n}\n\nexport interface SurveyNpsQuestion extends BaseSurveyQuestion {\n readonly type: 'nps'\n readonly lowLabel?: string\n readonly highLabel?: string\n}\n\nexport interface SurveyRatingQuestion extends BaseSurveyQuestion {\n readonly type: 'rating'\n readonly scale: 5 | 10\n readonly style?: 'star' | 'numeric'\n readonly lowLabel?: string\n readonly highLabel?: string\n}\n\nexport interface LikertQuestion extends BaseSurveyQuestion {\n readonly type: 'likert'\n // 5-point: strongly disagree → strongly agree. Labels overridable.\n readonly labels?: readonly [string, string, string, string, string]\n}\n\nexport interface SurveyShortTextQuestion extends BaseSurveyQuestion {\n readonly type: 'short_text'\n readonly placeholder?: string\n readonly validation?: SurveyTextValidation\n}\n\nexport interface LongTextQuestion extends BaseSurveyQuestion {\n readonly type: 'long_text'\n readonly placeholder?: string\n readonly maxLength?: number\n}\n\nexport interface RankingQuestion extends BaseSurveyQuestion {\n readonly type: 'ranking'\n readonly items: ReadonlyArray<SurveyChoiceOption>\n}\n\nexport interface SingleDateQuestion extends BaseSurveyQuestion {\n readonly type: 'single_date'\n readonly minDate?: string\n readonly maxDate?: string\n}\n\nexport interface InfoScreenQuestion extends BaseSurveyQuestion {\n readonly type: 'info_screen'\n readonly body?: string\n}\n\nexport type SurveyQuestion =\n | SingleChoiceQuestion\n | MultiChoiceQuestion\n | SurveyNpsQuestion\n | SurveyRatingQuestion\n | LikertQuestion\n | SurveyShortTextQuestion\n | LongTextQuestion\n | RankingQuestion\n | SingleDateQuestion\n | InfoScreenQuestion\n\n// ---------- Branching DSL ----------\n\nexport type SurveyBranchOp =\n | 'eq'\n | 'neq'\n | 'lt'\n | 'lte'\n | 'gt'\n | 'gte'\n | 'includes'\n | 'not_includes'\n | 'answered'\n | 'unanswered'\n\nexport type SurveyBranchValue = string | number | boolean | ReadonlyArray<string | number>\n\nexport interface SurveyBranchCondition {\n readonly op: SurveyBranchOp\n readonly value?: SurveyBranchValue\n}\n\nexport interface SurveyBranch {\n readonly fromQuestionId: string\n readonly condition: SurveyBranchCondition\n readonly toQuestionId: string // or '__end__' to jump straight to end screen\n}\n\nexport const SURVEY_END_SENTINEL = '__end__'\n\n// ---------- End screen ----------\n\nexport type SurveyEndCtaKind = 'url' | 'deep_link' | 'close'\n\nexport interface SurveyEndCta {\n readonly kind: SurveyEndCtaKind\n readonly label: string\n readonly target?: string\n}\n\nexport interface SurveyFollowUp {\n readonly headline: string\n readonly body?: string\n readonly cta?: SurveyEndCta\n}\n\nexport interface SurveyEndScreen {\n readonly headline: string\n readonly body?: string\n readonly cta?: SurveyEndCta\n readonly followUp?: SurveyFollowUp\n}\n\n// ---------- Localization ----------\n\nexport interface SurveyLocalization {\n readonly defaultLanguage?: string\n readonly languages?: Readonly<Record<string, {\n readonly questions?: ReadonlyArray<SurveyQuestion>\n readonly endScreen?: SurveyEndScreen\n }>>\n}\n\n// ---------- Flow ----------\n\nexport interface SurveyFlow {\n readonly startQuestionId: string\n readonly questions: ReadonlyArray<SurveyQuestion>\n readonly branches: ReadonlyArray<SurveyBranch>\n readonly progressStyle: SurveyProgressStyle\n readonly backNavigation: boolean\n readonly localization?: SurveyLocalization\n readonly endScreen?: SurveyEndScreen\n}\n\n// ---------- Campaign surface ----------\n\nexport type SurveyDeliveryMode =\n | 'triggered'\n | 'scheduled'\n | 'on_demand'\n | 'link_only'\n\nexport type SurveyAttemptSource =\n | 'triggered'\n | 'scheduled'\n | 'link'\n | 'on_demand'\n | 'test'\n\nexport interface SurveyCampaign {\n readonly id: string\n readonly appId: string\n readonly name: string\n readonly type: 'survey'\n readonly mode: SurveyDeliveryMode\n readonly status: 'draft' | 'scheduled' | 'active' | 'paused' | 'completed' | 'archived'\n readonly audienceSegmentId: string | null\n readonly triggerEventName: string | null\n // Inline AudienceSpec + TriggerSpec mirroring prompts.audience/trigger.\n // Null until the dashboard / API write them; legacy\n // audienceSegmentId / triggerEventName remain authoritative until\n // both sides have migrated.\n readonly audience: AudienceSpec | null\n readonly trigger: TriggerSpec | null\n readonly schedule: PushSchedule | null\n readonly frequencyCap: PushFrequencyCap\n readonly cooldownSeconds: number | null\n readonly openAccess: boolean\n readonly saveResumeWindowSeconds: number\n readonly endScreen: SurveyEndScreen | null\n readonly themeMode: ThemeMode\n readonly theme: PromptTheme | null\n readonly startAt: string | null\n readonly endAt: string | null\n readonly startedAt: string | null\n readonly endedAt: string | null\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface SurveyCampaignWithFlow extends SurveyCampaign {\n readonly flow: SurveyFlow\n}\n\n// ---------- Attempts / responses ----------\n\nexport interface SurveyAnswerRecord {\n readonly [questionId: string]: SurveyAnswerValue\n}\n\nexport type SurveyAnswerValue =\n | string\n | number\n | boolean\n | null\n | ReadonlyArray<string>\n | ReadonlyArray<number>\n\nexport interface SurveyAttempt {\n readonly id: string\n readonly campaignId: string\n readonly anonymousId: string\n readonly externalId: string | null\n readonly startedAt: string\n readonly completedAt: string | null\n readonly abandonedAt: string | null\n readonly currentQuestionId: string | null\n readonly progressSnapshot: SurveyAnswerRecord\n readonly source: SurveyAttemptSource\n readonly language: string | null\n}\n\nexport interface SurveyResponseRecord {\n readonly id: string\n readonly attemptId: string\n readonly campaignId: string\n readonly questionId: string\n readonly answerValue: SurveyAnswerValue\n readonly answeredAt: string\n}\n\n// ---------- SDK-facing payloads ----------\n\nexport interface SurveySummary {\n readonly id: string\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly source: SurveyAttemptSource\n readonly offeredAt?: string\n readonly resumableAttemptId?: string | null\n}\n\nexport interface SurveyOfferInstruction {\n readonly type: 'survey.offer'\n readonly surveyId: string\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly source: SurveyAttemptSource\n readonly emittedAt: string\n}\n\nexport interface CreateSurveyAttemptRequest {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly source: SurveyAttemptSource\n readonly language?: string\n readonly resume?: boolean\n readonly sdkVersion?: string\n readonly appVersion?: string\n readonly platform?: string\n}\n\nexport interface CreateSurveyAttemptResponse {\n readonly attemptId: string\n readonly startQuestionId: string\n readonly progressSnapshot: SurveyAnswerRecord\n readonly currentQuestionId: string | null\n readonly resumed: boolean\n}\n\nexport interface SubmitSurveyAnswersRequest {\n readonly answers: ReadonlyArray<{\n readonly questionId: string\n readonly value: SurveyAnswerValue\n }>\n readonly currentQuestionId?: string | null\n}\n\nexport interface UpdateSurveyAttemptProgressRequest {\n readonly currentQuestionId: string | null\n readonly progressSnapshot: SurveyAnswerRecord\n}\n\nexport interface CompleteSurveyAttemptRequest {\n readonly finalAnswers?: ReadonlyArray<{\n readonly questionId: string\n readonly value: SurveyAnswerValue\n }>\n readonly latencyMs?: number\n}\n\nexport interface ResolveSurveyLinkRequest {\n readonly token: string\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\nexport interface ResolveSurveyLinkResponse {\n readonly surveyId: string\n readonly name: string\n readonly consentRequired: boolean\n readonly openAccess: boolean\n}\n\nexport interface SurveyShareLinkResponse {\n readonly url: string\n readonly token: string\n readonly expiresAt: string | null\n}\n\n// ---------- Templates ----------\n\nexport interface SurveyTemplate {\n readonly id: string\n readonly slug: string\n readonly name: string\n readonly description: string | null\n readonly flow: SurveyFlow\n readonly recommendedTriggerEvent: string | null\n readonly recommendedMode: SurveyDeliveryMode | null\n readonly createdAt: string\n}\n\n// ---------- Create / update requests ----------\n\nexport interface CreateSurveyRequest {\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly flow: SurveyFlow\n readonly audienceSegmentId?: string | null\n readonly triggerEventName?: string | null\n readonly schedule?: PushSchedule | null\n readonly frequencyCap?: PushFrequencyCap\n readonly frequency?: FrequencyCaps\n readonly cooldownSeconds?: number | null\n readonly openAccess?: boolean\n readonly saveResumeWindowSeconds?: number\n readonly endScreen?: SurveyEndScreen\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: SurveyCampaign['status']\n}\n\nexport interface UpdateSurveyRequest extends Partial<CreateSurveyRequest> {\n readonly status?: SurveyCampaign['status']\n}\n\nexport interface CloneSurveyFromTemplateRequest {\n readonly name?: string\n readonly audienceSegmentId?: string | null\n readonly triggerEventName?: string | null\n}\n\n// ---------- Analytics ----------\n\nexport interface SurveyFunnelStep {\n readonly questionId: string\n readonly shown: number\n readonly answered: number\n readonly skipped: number\n}\n\nexport interface SurveyQuestionDistribution {\n readonly questionId: string\n readonly type: SurveyQuestionType\n readonly distribution: Readonly<Record<string, number>>\n readonly average?: number\n readonly npsScore?: number\n readonly sampleSize: number\n}\n\nexport interface SurveyAnalytics {\n readonly surveyId: string\n readonly totals: {\n readonly started: number\n readonly completed: number\n readonly abandoned: number\n readonly completionRate: number\n }\n readonly funnel: ReadonlyArray<SurveyFunnelStep>\n readonly perQuestion: ReadonlyArray<SurveyQuestionDistribution>\n readonly npsOverTime?: ReadonlyArray<{ day: string; score: number; samples: number }>\n readonly perLanguage?: Readonly<Record<string, number>>\n}\n\n// ---------- SDK-side armed surveys ----------\n//\n// Mirrors `ArmedTrigger` (feedback). Returned by\n// `GET /v1/sdk/armed-surveys` for every triggered + active survey\n// the SDK should evaluate locally on each `track()`. The full\n// `survey` payload is included so the SDK can render immediately\n// on a match without a follow-up content fetch.\n\nexport interface ArmedSurvey {\n readonly campaignId: string\n readonly eventName: string\n readonly segmentRules?: SerializedSegmentRules | null\n /** True only when the SDK can make the same targeting decision locally. */\n readonly clientSideEligible?: boolean\n readonly cooldownSeconds: number | null\n readonly frequencyCap: PushFrequencyCap\n readonly survey: SurveyCampaignWithFlow\n}\n","import type { AudienceSpec, TriggerSpec } from './targeting.js'\nimport type { ThemeMode } from './brand.js'\n\nexport const INAPP_SHOWN_EVENT_NAME = '$inapp_shown'\nexport const INAPP_DISMISSED_EVENT_NAME = '$inapp_dismissed'\nexport const INAPP_AUTO_DISMISSED_EVENT_NAME = '$inapp_auto_dismissed'\nexport const INAPP_CTA_CLICKED_EVENT_NAME = '$inapp_cta_clicked'\n\nexport type InAppMessageFormat = 'modal' | 'modal_full' | 'slideup'\n\nexport type InAppMessageStatus =\n | 'draft'\n | 'scheduled'\n | 'active'\n | 'paused'\n | 'completed'\n | 'archived'\n\nexport type InAppMessageMode = 'triggered' | 'scheduled'\n\nexport type JsonAction = Readonly<Record<string, unknown>>\n\nexport type InAppCtaAction =\n | 'open_url'\n | 'deep_link'\n | 'dismiss'\n | 'custom_event'\n | 'json'\n\nexport interface InAppCta {\n readonly label: string\n readonly action: InAppCtaAction\n readonly target?: string\n /** Host-defined action data dispatched to the app when this CTA is tapped. */\n readonly actionJson?: JsonAction\n}\n\n// Three-state cooldowns + cross-pillar caps. Each key is optional —\n// omitting means \"no cap on this dimension\".\nexport interface InAppFrequency {\n readonly cooldownAfterShownDays?: number\n readonly cooldownAfterDismissedDays?: number\n readonly cooldownAfterCtaClickedDays?: number\n readonly maxImpressionsPerUser?: number\n readonly perPillarDays?: number\n readonly perGlobalDays?: number\n}\n\nexport interface InAppMessage {\n readonly id: string\n readonly appId: string\n readonly name: string\n readonly status: InAppMessageStatus\n readonly mode: InAppMessageMode\n\n readonly audienceSegmentId: string | null\n readonly audience: AudienceSpec | null\n readonly trigger: TriggerSpec | null\n readonly triggerEventName: string | null\n readonly schedule: unknown | null\n\n readonly screenAllowlist: ReadonlyArray<string>\n readonly screenDenylist: ReadonlyArray<string>\n\n readonly frequency: InAppFrequency\n\n readonly conversionGoalEvent: string | null\n readonly conversionWindowHours: number\n\n readonly priority: number\n readonly forceShow: boolean\n readonly autoDismissSeconds: number | null\n\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body: string | null\n readonly imageUrl: string | null\n readonly themeMode: ThemeMode\n readonly backgroundColor: string | null\n readonly accentColor: string | null\n readonly backdropEnabled: boolean\n readonly ctas: ReadonlyArray<InAppCta>\n\n readonly startAt: string | null\n readonly endAt: string | null\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface CreateInAppMessageRequest {\n readonly name: string\n readonly audienceSegmentId?: string | null\n readonly audience?: AudienceSpec\n readonly trigger?: TriggerSpec\n readonly triggerEventName?: string | null\n readonly screenAllowlist?: ReadonlyArray<string>\n readonly screenDenylist?: ReadonlyArray<string>\n readonly frequency?: InAppFrequency\n readonly conversionGoalEvent?: string | null\n readonly conversionWindowHours?: number\n readonly priority?: number\n readonly forceShow?: boolean\n readonly autoDismissSeconds?: number | null\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body?: string | null\n readonly imageUrl?: string | null\n readonly themeMode?: ThemeMode\n readonly backgroundColor?: string | null\n readonly accentColor?: string | null\n readonly backdropEnabled?: boolean\n readonly ctas?: ReadonlyArray<InAppCta>\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: InAppMessageStatus\n}\n\nexport interface UpdateInAppMessageRequest extends Partial<CreateInAppMessageRequest> {\n readonly status?: InAppMessageStatus\n}\n\nexport interface InAppMessageAnalytics {\n readonly totals: {\n readonly impressions: number\n readonly dismissed: number\n readonly autoDismissed: number\n readonly ctaClicked: number\n }\n readonly timeline: ReadonlyArray<{\n readonly day: string\n readonly impressions: number\n readonly dismissed: number\n readonly ctaClicked: number\n }>\n}\n\n// Subset of the message the SDK needs at render time. Mirrors\n// `ArmedTrigger.prompt` for feedback prompts — strips fields the device\n// doesn't need (audit columns, segment id) and leaves what the renderer\n// uses.\nexport interface ArmedInAppMessage {\n readonly messageId: string\n readonly eventName: string\n /** True only when the SDK can make the same targeting decision locally. */\n readonly clientSideEligible?: boolean\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body: string | null\n readonly imageUrl: string | null\n readonly themeMode?: ThemeMode\n readonly backgroundColor: string | null\n readonly accentColor: string | null\n /** Defaults to true when omitted by an older API/cache payload. */\n readonly backdropEnabled?: boolean\n readonly ctas: ReadonlyArray<InAppCta>\n readonly autoDismissSeconds: number | null\n readonly screenAllowlist: ReadonlyArray<string>\n readonly screenDenylist: ReadonlyArray<string>\n readonly forceShow: boolean\n}\n","// ============================================================\n// Feature requests (5th pillar) — public types\n// ============================================================\n// Shared between API, dashboard, web-roadmap, and SDKs.\n// All shapes are `readonly`. Identity uses anonymousId + externalId\n// as on every other SDK payload — no new identity types here.\n\nimport type { ThemeMode } from './brand.js'\n\nexport type RequestStatus =\n | 'under_review'\n | 'planned'\n | 'in_progress'\n | 'shipped'\n | 'declined'\n\nexport type RequestFollowSource = 'upvote_auto' | 'manual'\n\nexport type RequestSort = 'top' | 'newest' | 'recently_updated'\n\nexport type RequestPersonalFilter = 'submitted' | 'upvoted' | 'following'\n\n// Event-name constants for the 7 events emitted by the request engine.\n// All flow through services/ingest.ts and become segmentable like every\n// other event (no segment-engine code changes needed).\nexport const REQUEST_SUBMITTED_EVENT_NAME = '$request_submitted' as const\nexport const REQUEST_UPVOTED_EVENT_NAME = '$request_upvoted' as const\nexport const REQUEST_UNUPVOTED_EVENT_NAME = '$request_unupvoted' as const\nexport const REQUEST_FOLLOWED_EVENT_NAME = '$request_followed' as const\nexport const REQUEST_UNFOLLOWED_EVENT_NAME = '$request_unfollowed' as const\nexport const REQUEST_STATUS_CHANGED_EVENT_NAME = '$request_status_changed' as const\nexport const REQUEST_RESPONDED_EVENT_NAME = '$request_responded' as const\nexport const REQUEST_COMMENTED_EVENT_NAME = '$request_commented' as const\nexport const REQUEST_COMMENT_EDITED_EVENT_NAME = '$request_comment_edited' as const\nexport const REQUEST_COMMENT_DELETED_EVENT_NAME = '$request_comment_deleted' as const\n\n// ---------- core domain shapes ----------\n\n/**\n * A feature request with viewer-relative state attached. Returned from\n * detail and list endpoints; `viewer*` fields are computed server-side\n * from the caller's identity.\n */\nexport interface Request {\n readonly id: string\n readonly appId: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly devResponse: string | null\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly updatedAt: string\n readonly statusChangedAt: string\n readonly lastRespondedAt: string | null\n readonly viewerHasUpvoted: boolean\n readonly viewerIsFollowing: boolean\n readonly viewerIsSubmitter: boolean\n}\n\n/** Compact summary used in list views and search typeahead. */\nexport interface RequestSummary {\n readonly id: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly statusChangedAt: string\n readonly viewerHasUpvoted: boolean\n readonly viewerIsFollowing: boolean\n}\n\n/** Search-as-you-type result; the SDK shows up to 5. */\nexport interface RequestSearchResult {\n readonly id: string\n readonly title: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n}\n\n// ---------- toggle return shapes ----------\n\n/** Returned from POST/DELETE /v1/sdk/requests/:id/votes. */\nexport interface RequestVote {\n readonly requestId: string\n readonly upvoted: boolean\n readonly followed: boolean\n readonly upvoteCount: number\n readonly followerCount: number\n}\n\n/** Returned from POST/DELETE /v1/sdk/requests/:id/follows. */\nexport interface RequestFollow {\n readonly requestId: string\n readonly following: boolean\n readonly followerCount: number\n readonly source: RequestFollowSource\n}\n\n// ---------- request payloads ----------\n\nexport interface GetRequestsOptions {\n readonly sort?: RequestSort\n readonly statuses?: ReadonlyArray<RequestStatus>\n readonly mine?: RequestPersonalFilter\n readonly q?: string\n readonly cursor?: string | null\n readonly limit?: number\n}\n\nexport interface GetRequestsResult {\n readonly items: ReadonlyArray<RequestSummary>\n readonly nextCursor: string | null\n}\n\nexport interface SubmitRequestPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly title: string\n readonly description: string\n}\n\nexport interface RequestVotePayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\nexport interface RequestFollowPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\n// ---------- dashboard shapes ----------\n\nexport interface RequestDetail extends Request {\n readonly submitterAnonymousId: string\n readonly submitterExternalId: string | null\n readonly hidden: boolean\n}\n\nexport interface RequestUpvoterSegmentBreakdown {\n readonly requestId: string\n readonly totalUpvoters: number\n readonly segments: ReadonlyArray<{\n readonly segmentId: string\n readonly segmentName: string\n readonly count: number\n readonly percentage: number\n }>\n}\n\nexport type RequestTimelineEntryKind =\n | 'submitted'\n | 'upvote_burst'\n | 'follow_burst'\n | 'status_changed'\n | 'responded'\n\nexport interface RequestTimelineEntry {\n readonly kind: RequestTimelineEntryKind\n readonly at: string\n readonly count?: number\n readonly fromStatus?: RequestStatus\n readonly toStatus?: RequestStatus\n readonly responseExcerpt?: string\n}\n\nexport interface RequestAnalytics {\n readonly submissions: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly upvotes: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly follows: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly statusDistribution: Record<RequestStatus, number>\n readonly devResponseRate: number\n readonly medianResponseHours: number | null\n readonly leaderboard: ReadonlyArray<{\n readonly anonymousId: string\n readonly externalId: string | null\n readonly submissions: number\n readonly upvotes: number\n }>\n}\n\nexport interface UpdateRequestStatusRequest {\n readonly status: RequestStatus\n readonly responseAppend?: string\n}\n\nexport interface UpdateRequestResponseRequest {\n readonly body: string\n}\n\nexport interface UpdateRequestModerationRequest {\n readonly hidden: boolean\n}\n\nexport interface MergeRequestsRequest {\n readonly canonicalId: string\n readonly duplicateIds: ReadonlyArray<string>\n}\n\nexport interface BulkUpdateStatusRequest {\n readonly ids: ReadonlyArray<string>\n readonly status: RequestStatus\n}\n\nexport interface ListRequestsQuery {\n readonly sort?: RequestSort\n readonly status?: RequestStatus | ReadonlyArray<RequestStatus>\n readonly filter?: RequestPersonalFilter\n readonly anonymousId?: string\n readonly q?: string\n readonly hidden?: boolean\n readonly page?: number\n readonly limit?: number\n}\n\n// ---------- settings ----------\n\nexport interface RequestBranding {\n readonly logoUrl?: string | null\n readonly accentColor?: string | null\n readonly coverImageUrl?: string | null\n readonly introCopy?: string | null\n}\n\nexport interface RequestNotificationRules {\n readonly transitions?: Record<string, boolean>\n readonly responseFirst?: boolean\n readonly responseEdit?: boolean\n readonly templateOverrides?: {\n readonly statusChange?: string\n readonly response?: string\n }\n}\n\nexport interface RequestSettings {\n readonly appId: string\n readonly enabled: boolean\n readonly entryLabel: string\n readonly viewSegmentId: string | null\n readonly submitSegmentId: string | null\n readonly publicRoadmapEnabled: boolean\n readonly publicSlug: string | null\n readonly themeMode: ThemeMode\n readonly branding: RequestBranding\n readonly notificationRules: RequestNotificationRules\n}\n\nexport interface UpdateRequestSettingsRequest {\n readonly enabled?: boolean\n readonly entryLabel?: string\n readonly viewSegmentId?: string | null\n readonly submitSegmentId?: string | null\n readonly publicRoadmapEnabled?: boolean\n readonly publicSlug?: string | null\n readonly themeMode?: ThemeMode\n readonly branding?: RequestBranding\n readonly notificationRules?: RequestNotificationRules\n}\n\n// ---------- public web roadmap shapes ----------\n\n/** Public-safe request summary (no submitter identity). */\nexport interface RequestPublicSummary {\n readonly id: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly statusChangedAt: string\n}\n\nexport interface RequestPublicDetail extends RequestPublicSummary {\n readonly devResponse: string | null\n readonly lastRespondedAt: string | null\n}\n\nexport interface RequestPublicBranding {\n readonly entryLabel: string\n readonly appName: string\n readonly branding: RequestBranding\n readonly fallbackInstallUrl: string | null\n}\n\n// ---------- SDK push payload ----------\n\n/** Carried inside push/in-app message payloads when status changes. */\nexport interface RequestStatusChangedNotice {\n readonly requestId: string\n readonly title: string\n readonly oldStatus: RequestStatus\n readonly newStatus: RequestStatus\n readonly devResponseExcerpt?: string\n readonly receivedVia: 'push' | 'inapp'\n}\n\n// ---------- comments ----------\n\nexport interface RequestComment {\n readonly id: string\n readonly requestId: string\n readonly body: string\n readonly authorAnonymousId: string\n readonly authorExternalId: string | null\n readonly viewerIsAuthor: boolean\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface PostCommentPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly body: string\n}\n\nexport interface EditCommentPayload {\n readonly anonymousId: string\n readonly body: string\n}\n\n/** Host-app callbacks registered via `setRequestsHandlers`. */\nexport interface RequestsHandlers {\n readonly onSubmit?: (request: Request) => void\n readonly onVote?: (vote: RequestVote) => void\n readonly onFollow?: (follow: RequestFollow) => void\n readonly onStatusChanged?: (notice: RequestStatusChangedNotice) => void\n}\n","// ==========================================================\n// Inline targeting spec — used by feedback prompts, surveys,\n// and push campaigns. Wraps each pillar record with an\n// `AudienceSpec` (who) + `TriggerSpec` (when).\n//\n// One condition kind in `AudienceCondition` is `segment`,\n// which references saved Segments by id (so the dashboard\n// suggests existing segments in that one branch). All other\n// kinds are evaluated inline against user properties or\n// recent event aggregates.\n//\n// `TriggerSpec` is a discriminated union with a shared base\n// (`app_open`, `event`, `audience_join`). Pillar packages\n// add extra kinds locally (e.g. push adds `manual` /\n// `scheduled`) — engines `switch` on `kind` and treat\n// unknowns as no-op.\n// ==========================================================\n\nimport type { ComparisonOp } from './segment-dsl.js'\n\nexport type Platform = 'ios' | 'android' | 'web'\n\nexport type AudienceCombinator = 'all' | 'any'\n\nexport type AudienceMode = 'everyone' | 'match'\n\n// -------------------- Audience conditions ----------------\n\nexport interface SegmentCondition {\n readonly kind: 'segment'\n readonly op: 'is' | 'is_not'\n readonly segmentIds: ReadonlyArray<string>\n}\n\nexport interface CountryCondition {\n readonly kind: 'country'\n readonly op: 'is_any_of' | 'is_none_of'\n readonly values: ReadonlyArray<string> // ISO 3166-1 alpha-2\n}\n\nexport interface LastActiveCondition {\n readonly kind: 'last_active'\n readonly op: 'within_days' | 'before_days' | 'never'\n readonly days?: number\n}\n\nexport interface InstallDateCondition {\n readonly kind: 'install_date'\n // `*_days` operators are relative to today; `*_date` and `between`\n // pin to user-picked calendar dates (ISO yyyy-mm-dd).\n readonly op:\n | 'within_days'\n | 'before_days'\n | 'after_date'\n | 'before_date'\n | 'between'\n readonly days?: number\n readonly date?: string // ISO date — used by after_date / before_date\n readonly from?: string // ISO date — used by between\n readonly to?: string // ISO date — used by between\n}\n\nexport interface PlatformCondition {\n readonly kind: 'platform'\n readonly op: 'is' | 'is_not'\n readonly values: ReadonlyArray<Platform>\n}\n\nexport interface UserPropertyCondition {\n readonly kind: 'user_property'\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: string | number | boolean | ReadonlyArray<string | number>\n}\n\nexport interface EventPropertyFilter {\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: string | number | boolean | ReadonlyArray<string | number>\n}\n\nexport interface EventPerformedCondition {\n readonly kind: 'event_performed'\n readonly op: 'did' | 'did_not'\n readonly eventName: string\n /** @deprecated Kept so previously saved audience definitions still load. */\n readonly property?: EventPropertyFilter\n readonly propertyFilters?: ReadonlyArray<EventPropertyFilter>\n readonly windowDays?: number\n readonly minCount?: number\n}\n\nexport interface AppVersionCondition {\n readonly kind: 'app_version'\n // String comparison for v1 — \"2.10.0\" sorts before \"2.9.0\" lexically.\n // Acceptable until we ship a semver-aware compare; the dashboard\n // input warns users.\n readonly op: 'eq' | 'neq' | 'gte' | 'lte' | 'gt' | 'lt'\n readonly version: string\n}\n\nexport type AudienceCondition =\n | SegmentCondition\n | CountryCondition\n | LastActiveCondition\n | InstallDateCondition\n | PlatformCondition\n | UserPropertyCondition\n | EventPerformedCondition\n | AppVersionCondition\n\nexport type AudienceConditionKind = AudienceCondition['kind']\n\nexport interface AudienceSpec {\n readonly version: 1\n readonly mode: AudienceMode\n readonly combinator: AudienceCombinator\n readonly conditions: ReadonlyArray<AudienceCondition>\n}\n\nexport function emptyAudienceSpec(): AudienceSpec {\n return { version: 1, mode: 'everyone', combinator: 'all', conditions: [] }\n}\n\n// -------------------- Trigger spec -----------------------\n\nexport type TriggerOccurrenceMode = 'every' | 'after_nth' | 'first_only'\n\nexport interface TriggerOccurrence {\n readonly mode: TriggerOccurrenceMode\n readonly n?: number // required when mode === 'after_nth'\n}\n\nexport interface ActiveWindow {\n readonly startAt?: string // ISO datetime\n readonly endAt?: string // ISO datetime\n}\n\nexport interface AppOpenTrigger {\n readonly kind: 'app_open'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface EventTrigger {\n readonly kind: 'event'\n readonly eventName: string\n readonly propertyFilters?: ReadonlyArray<EventPropertyFilter>\n readonly occurrence?: TriggerOccurrence\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface AudienceJoinTrigger {\n readonly kind: 'audience_join'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface AppVersionChangedTrigger {\n readonly kind: 'app_version_changed'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport type TriggerSpec =\n | AppOpenTrigger\n | EventTrigger\n | AudienceJoinTrigger\n | AppVersionChangedTrigger\n\nexport type TriggerKind = TriggerSpec['kind']\n\n/**\n * Synthetic event name the SDK emits whenever the host app cold-starts\n * or transitions from background to foreground. The trigger engine\n * indexes `app_open`-kind prompts under this name so the same matching\n * pipeline handles both event-driven and lifecycle-driven prompts.\n */\nexport const APP_OPEN_EVENT_NAME = '$app_open'\n\n/**\n * Synthetic event the engine indexes `audience_join` campaigns under.\n * Mirrors APP_OPEN_EVENT_NAME so the same matching pipeline handles\n * both lifecycle and audience-membership triggers.\n */\nexport const AUDIENCE_JOIN_EVENT_NAME = '$audience_join'\n\nexport const AUDIENCE_JOIN_TRIGGER_KIND: AudienceJoinTrigger['kind'] = 'audience_join'\n\n/**\n * Synthetic event the SDK emits on cold-start when the persisted app\n * version differs from the running binary's version. Lets in-app\n * messages (and feedback / surveys) target users right after an update\n * — e.g. \"What's new\" modals.\n */\nexport const APP_VERSION_CHANGED_EVENT_NAME = '$app_version_changed'\n\nexport function defaultTriggerSpec(): TriggerSpec {\n return { kind: 'app_open' }\n}\n\nexport function defaultEventTrigger(eventName = ''): EventTrigger {\n return {\n kind: 'event',\n eventName,\n occurrence: { mode: 'every' },\n }\n}\n","// ==========================================================\n// Preset themes for the Feedback Design step. 12 curated\n// presets + a custom-your-own option in the UI. Each preset\n// surfaces 3 swatches in the gallery card for quick scan.\n// ==========================================================\n\nexport interface ThemeColors {\n readonly primary: string\n readonly background: string\n readonly text: string\n readonly subtext: string\n readonly border: string\n readonly accent?: string\n readonly button?: string\n}\n\nexport type CornerRadiusPreset = 'sharp' | 'soft' | 'rounded' | 'pill'\n\nexport const RADIUS_PRESETS: Record<CornerRadiusPreset, number> = {\n sharp: 4,\n soft: 12,\n rounded: 20,\n pill: 999,\n}\n\nexport interface ThemePreset {\n readonly id: string\n readonly name: string\n readonly description: string\n readonly colors: ThemeColors\n readonly radius: number\n readonly fontFamily: string\n readonly swatches: readonly [string, string, string]\n}\n\n// Default font family for every preset. Matches the SDK's\n// DEFAULT_THEME so a freshly-saved theme renders the same in the\n// dashboard preview (web font loaded via next/font + Google Fonts\n// stylesheet) and on the mobile app (host bundles the .ttf via\n// react-native.config.js). Previously the presets used 'Inter',\n// which neither side had loaded — both fell back to system sans,\n// so designers saw a font drift between the dashboard and device.\nconst JAKARTA = 'Plus Jakarta Sans'\n\nexport const THEME_PRESETS: ReadonlyArray<ThemePreset> = [\n {\n id: 'minimal',\n name: 'Minimal',\n description: 'Clean neutral palette',\n colors: {\n primary: '#111827',\n background: '#FFFFFF',\n text: '#111827',\n subtext: '#6B7280',\n border: '#E5E7EB',\n button: '#111827',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#111827', '#FFFFFF', '#E5E7EB'],\n },\n {\n id: 'ocean',\n name: 'Ocean',\n description: 'Cool blue tones',\n colors: {\n primary: '#0EA5E9',\n background: '#F0F9FF',\n text: '#0C4A6E',\n subtext: '#0369A1',\n border: '#BAE6FD',\n button: '#0EA5E9',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#0EA5E9', '#0C4A6E', '#BAE6FD'],\n },\n {\n id: 'sunset',\n name: 'Sunset',\n description: 'Warm orange glow',\n colors: {\n primary: '#F97316',\n background: '#FFF7ED',\n text: '#7C2D12',\n subtext: '#C2410C',\n border: '#FED7AA',\n button: '#F97316',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#F97316', '#7C2D12', '#FED7AA'],\n },\n {\n id: 'forest',\n name: 'Forest',\n description: 'Natural green hues',\n colors: {\n primary: '#16A34A',\n background: '#F0FDF4',\n text: '#14532D',\n subtext: '#166534',\n border: '#BBF7D0',\n button: '#16A34A',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#16A34A', '#14532D', '#BBF7D0'],\n },\n {\n id: 'midnight',\n name: 'Midnight',\n description: 'Deep dark mode',\n colors: {\n primary: '#A78BFA',\n background: '#0F172A',\n text: '#F8FAFC',\n subtext: '#94A3B8',\n border: '#1E293B',\n button: '#A78BFA',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#A78BFA', '#0F172A', '#1E293B'],\n },\n {\n id: 'candy',\n name: 'Candy',\n description: 'Playful pink + violet',\n colors: {\n primary: '#EC4899',\n background: '#FDF2F8',\n text: '#831843',\n subtext: '#BE185D',\n border: '#FBCFE8',\n button: '#EC4899',\n },\n radius: 20,\n fontFamily: JAKARTA,\n swatches: ['#EC4899', '#831843', '#FBCFE8'],\n },\n {\n id: 'mono',\n name: 'Mono',\n description: 'High-contrast B&W',\n colors: {\n primary: '#000000',\n background: '#FFFFFF',\n text: '#000000',\n subtext: '#525252',\n border: '#000000',\n button: '#000000',\n },\n radius: 4,\n fontFamily: JAKARTA,\n swatches: ['#000000', '#FFFFFF', '#525252'],\n },\n {\n id: 'coral',\n name: 'Coral',\n description: 'Soft coral accent',\n colors: {\n primary: '#FB7185',\n background: '#FFF1F2',\n text: '#881337',\n subtext: '#9F1239',\n border: '#FECDD3',\n button: '#FB7185',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#FB7185', '#881337', '#FECDD3'],\n },\n {\n id: 'ink',\n name: 'Ink',\n description: 'Deep navy editorial',\n colors: {\n primary: '#1E3A8A',\n background: '#F8FAFC',\n text: '#0F172A',\n subtext: '#475569',\n border: '#CBD5E1',\n button: '#1E3A8A',\n },\n radius: 12,\n fontFamily: JAKARTA,\n swatches: ['#1E3A8A', '#0F172A', '#CBD5E1'],\n },\n {\n id: 'mint',\n name: 'Mint',\n description: 'Fresh teal vibe',\n colors: {\n primary: '#14B8A6',\n background: '#F0FDFA',\n text: '#134E4A',\n subtext: '#0F766E',\n border: '#99F6E4',\n button: '#14B8A6',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#14B8A6', '#134E4A', '#99F6E4'],\n },\n {\n id: 'slate',\n name: 'Slate',\n description: 'Quiet professional',\n colors: {\n primary: '#475569',\n background: '#F1F5F9',\n text: '#0F172A',\n subtext: '#64748B',\n border: '#CBD5E1',\n button: '#475569',\n },\n radius: 12,\n fontFamily: JAKARTA,\n swatches: ['#475569', '#0F172A', '#CBD5E1'],\n },\n {\n id: 'aurora',\n name: 'Aurora',\n description: 'Vibrant gradient pop',\n colors: {\n primary: '#8B5CF6',\n background: '#FAF5FF',\n text: '#3B0764',\n subtext: '#7E22CE',\n border: '#E9D5FF',\n accent: '#EC4899',\n button: '#8B5CF6',\n },\n radius: 20,\n fontFamily: JAKARTA,\n swatches: ['#8B5CF6', '#EC4899', '#E9D5FF'],\n },\n] as const\n\nexport function getThemePresetById(id: string): ThemePreset | undefined {\n return THEME_PRESETS.find((preset) => preset.id === id)\n}\n\nexport function defaultThemePreset(): ThemePreset {\n // The presets list is non-empty by construction; assert via index access.\n return THEME_PRESETS[0] as ThemePreset\n}\n","import type { PromptTheme } from './prompt.js'\nimport type { ThemePreset } from './themes.js'\n\nexport type BrandPillar = 'feedback' | 'survey' | 'inapp' | 'requests'\nexport type ThemeMode = 'app_default' | 'custom'\n\nexport interface BrandThemeTokens {\n readonly colors: {\n readonly primary: string\n readonly background: string\n readonly text: string\n readonly subtext: string\n readonly border: string\n }\n readonly radius: number\n readonly fontFamily: string\n}\n\nexport type BrandThemeRef = `preset:${string}` | `custom:${string}`\n\nexport interface BrandTheme {\n readonly ref: BrandThemeRef\n readonly id: string\n readonly kind: 'preset' | 'custom'\n readonly name: string\n readonly description?: string\n readonly tokens: BrandThemeTokens\n readonly swatches: readonly [string, string, string]\n readonly editable: boolean\n readonly assignedPillars: ReadonlyArray<BrandPillar>\n readonly createdAt?: string\n readonly updatedAt?: string\n}\n\nexport type BrandThemeDefaults = Readonly<Record<BrandPillar, BrandThemeRef>>\n\nexport interface AppBrandSettings {\n readonly appId: string\n readonly themes: ReadonlyArray<BrandTheme>\n readonly defaults: BrandThemeDefaults\n readonly resolvedDefaults: Readonly<Record<BrandPillar, BrandThemeTokens>>\n readonly updatedAt: string\n}\n\nexport interface CreateBrandThemeRequest {\n readonly name: string\n readonly tokens: BrandThemeTokens\n}\n\nexport interface UpdateBrandThemeRequest {\n readonly name?: string\n readonly tokens?: BrandThemeTokens\n}\n\nexport interface UpdateBrandThemeDefaultsRequest {\n readonly defaults: BrandThemeDefaults\n}\n\nexport function brandTokensFromPreset(\n preset: Pick<ThemePreset, 'colors' | 'radius' | 'fontFamily'>,\n): BrandThemeTokens {\n return {\n colors: {\n primary: preset.colors.primary,\n background: preset.colors.background,\n text: preset.colors.text,\n subtext: preset.colors.subtext,\n border: preset.colors.border,\n },\n radius: preset.radius,\n fontFamily: preset.fontFamily,\n }\n}\n\nexport function promptThemeFromBrandTokens(tokens: BrandThemeTokens): PromptTheme {\n return {\n colors: { ...tokens.colors },\n radius: tokens.radius,\n fontFamily: tokens.fontFamily,\n }\n}\n\nexport function inAppColorsFromBrandTokens(tokens: BrandThemeTokens): {\n readonly backgroundColor: string\n readonly accentColor: string\n} {\n return {\n backgroundColor: tokens.colors.background,\n accentColor: tokens.colors.primary,\n }\n}\n\nexport function requestAccentFromBrandTokens(tokens: BrandThemeTokens): string {\n return tokens.colors.primary\n}\n","import type { EventPropertyValue } from './event.js'\n\nexport const INTEGRATION_PROVIDERS = ['amplitude', 'mixpanel'] as const\nexport type IntegrationProvider = (typeof INTEGRATION_PROVIDERS)[number]\n\nexport const INTEGRATION_CATEGORIES = [\n 'feedback', 'surveys', 'inapp', 'push', 'requests', 'lifecycle',\n] as const\nexport type IntegrationCategory = (typeof INTEGRATION_CATEGORIES)[number]\n\nexport type IntegrationStatus = 'connected' | 'paused' | 'needs_attention' | 'disconnected'\nexport type AmplitudeIntegrationRegion = 'us' | 'eu'\nexport type MixpanelIntegrationRegion = 'us' | 'eu' | 'in'\nexport type IntegrationRegion = 'us' | 'eu' | 'in'\nexport type IntegrationDeliveryStatus =\n | 'pending' | 'leased' | 'retrying' | 'delivered' | 'dead_lettered' | 'skipped'\nexport type CoreEventSubjectRole = 'actor' | 'affected_user'\n\nexport interface CoreIntegrationEventDefinition {\n readonly key: string\n readonly name: string\n readonly category: IntegrationCategory | 'identity'\n readonly subjectRole: CoreEventSubjectRole\n readonly required?: boolean\n /** Stable output property key -> accepted source property aliases. */\n readonly properties: Readonly<Record<string, ReadonlyArray<string>>>\n}\n\nexport const USER_IDENTIFIED_EVENT_NAME = '$user_identified' as const\n\nfunction camelize(value: string): string {\n return value.replace(/_([a-z])/g, (_match, letter: string) => letter.toUpperCase())\n}\n\nconst ids = (...keys: string[]): Readonly<Record<string, ReadonlyArray<string>>> =>\n Object.fromEntries(keys.map((key) => [key, [key, camelize(key)]]))\n\nconst pushEvents: ReadonlyArray<readonly [string, string]> = [\n ['$push_sent', 'UserGist Push Sent'],\n ['$push_delivered', 'UserGist Push Delivered'],\n ['$push_received', 'UserGist Push Received'],\n ['$push_displayed', 'UserGist Push Displayed'],\n ['$push_opened', 'UserGist Push Opened'],\n ['$push_dismissed', 'UserGist Push Dismissed'],\n ['$push_clicked', 'UserGist Push Clicked'],\n ['$push_action_clicked', 'UserGist Push Action Clicked'],\n ['$push_bounced', 'UserGist Push Bounced'],\n]\n\nconst requestEvents: ReadonlyArray<readonly [string, string, CoreEventSubjectRole]> = [\n ['$request_submitted', 'UserGist Request Submitted', 'actor'],\n ['$request_upvoted', 'UserGist Request Upvoted', 'actor'],\n ['$request_unupvoted', 'UserGist Request Unupvoted', 'actor'],\n ['$request_followed', 'UserGist Request Followed', 'actor'],\n ['$request_unfollowed', 'UserGist Request Unfollowed', 'actor'],\n ['$request_status_changed', 'UserGist Request Status Changed', 'affected_user'],\n ['$request_responded', 'UserGist Request Responded', 'affected_user'],\n ['$request_commented', 'UserGist Request Commented', 'actor'],\n ['$request_comment_edited', 'UserGist Request Comment Edited', 'actor'],\n ['$request_comment_deleted', 'UserGist Request Comment Deleted', 'affected_user'],\n]\n\nconst answerProperties: Readonly<Record<string, ReadonlyArray<string>>> = {\n ...ids(\n 'question_id',\n 'question_type',\n 'question_title',\n 'answer_format',\n 'answer_present',\n 'answer_numeric_value',\n 'answer_selection_count',\n 'answer_text_length',\n ),\n // These aliases are generated only by the trusted server response paths.\n // The API delivery boundary removes them from public SDK events before this\n // normalizer runs. The complete answer_value stays in UserGist; destinations\n // receive a value only for server-verified structured data.\n answer_value: ['__usergist_destination_answer_value'],\n answer_display_value: ['__usergist_destination_answer_display_value'],\n}\n\nexport const CORE_INTEGRATION_EVENTS: ReadonlyArray<CoreIntegrationEventDefinition> = [\n { key: '$app_open', name: 'UserGist App Opened', category: 'lifecycle', subjectRole: 'actor', properties: {} },\n { key: '$app_version_changed', name: 'UserGist App Version Changed', category: 'lifecycle', subjectRole: 'actor', properties: { ...ids('old_version', 'new_version') } },\n { key: USER_IDENTIFIED_EVENT_NAME, name: 'UserGist User Identified', category: 'identity', subjectRole: 'actor', required: true, properties: {} },\n { key: '$feedback_prompt_shown', name: 'UserGist Feedback Prompt Shown', category: 'feedback', subjectRole: 'actor', properties: { ...ids('prompt_id') } },\n { key: '$feedback_response', name: 'UserGist Feedback Response Submitted', category: 'feedback', subjectRole: 'actor', properties: { ...ids('response_id', 'prompt_id', 'prompt_name', 'dismissed', 'latency_ms', 'answer_count', 'feedback_types') } },\n { key: '$feedback_answer_submitted', name: 'UserGist Feedback Answer Submitted', category: 'feedback', subjectRole: 'actor', properties: { ...ids('response_id', 'prompt_id', 'prompt_name'), ...answerProperties } },\n { key: '$survey_started', name: 'UserGist Survey Started', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source') } },\n { key: '$survey_answer_submitted', name: 'UserGist Survey Answer Submitted', category: 'surveys', subjectRole: 'actor', properties: { ...ids('response_id', 'campaign_id', 'survey_name', 'attempt_id', 'language'), ...answerProperties } },\n { key: '$survey_completed', name: 'UserGist Survey Completed', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source', 'duration_ms') } },\n { key: '$survey_abandoned', name: 'UserGist Survey Abandoned', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source', 'duration_ms') } },\n { key: '$inapp_shown', name: 'UserGist In-App Message Shown', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id') } },\n { key: '$inapp_dismissed', name: 'UserGist In-App Message Dismissed', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'dismiss_reason') } },\n { key: '$inapp_auto_dismissed', name: 'UserGist In-App Message Auto-Dismissed', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'dismiss_reason') } },\n { key: '$inapp_cta_clicked', name: 'UserGist In-App Message CTA Clicked', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'cta_id', 'cta_index'), action: ['action', 'cta_action'] } },\n ...pushEvents.map(([key, name]) => ({\n key,\n name,\n category: 'push' as const,\n subjectRole: 'actor' as const,\n properties: {\n ...ids('delivery_id', 'campaign_id', 'delivery_state', 'failure_code'),\n action_id: ['action_id', 'actionId', 'action_button', 'actionButton'],\n },\n })),\n ...requestEvents.map(([key, name, subjectRole]) => ({ key, name, category: 'requests' as const, subjectRole, properties: { ...ids('request_id', 'comment_id', 'source', 'old_status', 'new_status', 'deleted_by'), usergist_actor_type: ['usergist_actor_type', 'actor_type'] } })),\n]\n\nconst CORE_EVENT_BY_KEY = new Map(CORE_INTEGRATION_EVENTS.map((event) => [event.key, event]))\n\nexport function getCoreIntegrationEvent(key: string): CoreIntegrationEventDefinition | null {\n return CORE_EVENT_BY_KEY.get(key) ?? null\n}\n\nexport function sanitizeCoreIntegrationProperties(\n definition: CoreIntegrationEventDefinition,\n input: Readonly<Record<string, unknown>> | null | undefined,\n): Readonly<Record<string, EventPropertyValue>> {\n if (!input) return {}\n const output: Record<string, EventPropertyValue> = {}\n for (const [outputKey, aliases] of Object.entries(definition.properties)) {\n const alias = aliases.find((candidate) => Object.prototype.hasOwnProperty.call(input, candidate))\n if (!alias) continue\n const value = input[alias]\n if (typeof value === 'string') output[outputKey] = value.slice(0, 1024)\n else if (typeof value === 'number' && Number.isFinite(value)) output[outputKey] = value\n else if (typeof value === 'boolean' || value === null) output[outputKey] = value\n }\n return output\n}\n\nexport interface IntegrationSummary {\n readonly id: string\n readonly provider: IntegrationProvider\n readonly status: IntegrationStatus\n readonly region: IntegrationRegion\n readonly categories: ReadonlyArray<IntegrationCategory>\n readonly credentialHint: string | null\n readonly connectedAt: string | null\n readonly pausedAt: string | null\n readonly lastVerifiedAt: string | null\n readonly lastSuccessAt: string | null\n readonly lastFailureAt: string | null\n readonly lastErrorCode: string | null\n readonly lastErrorMessage: string | null\n}\n\nexport type ConnectIntegrationRequest =\n | { readonly provider: 'amplitude'; readonly apiKey: string; readonly region: 'us' | 'eu'; readonly categories: ReadonlyArray<IntegrationCategory> }\n | { readonly provider: 'mixpanel'; readonly projectToken: string; readonly region: 'us' | 'eu' | 'in'; readonly categories: ReadonlyArray<IntegrationCategory>; readonly identityMode: 'simplified' }\n\nexport interface UpdateIntegrationRequest {\n readonly categories: ReadonlyArray<IntegrationCategory>\n}\n\nexport interface IntegrationTestResult {\n readonly accepted: true\n readonly eventName: 'UserGist Integration Connected'\n readonly deviceId: string\n readonly acceptedAt: string\n}\n\nexport interface IntegrationDeliverySummary {\n readonly id: string\n readonly eventKey: string\n readonly eventName: string\n readonly status: IntegrationDeliveryStatus\n readonly identity: { readonly anonymousId: string; readonly externalId: string | null }\n readonly occurredAt: string\n readonly attempts: number\n readonly providerStatusCode: number | null\n readonly lastErrorMessage: string | null\n}\n\nexport interface IntegrationDeliveriesResponse {\n readonly items: ReadonlyArray<IntegrationDeliverySummary>\n readonly nextCursor: string | null\n}\n","/**\n * Canonical event names emitted by the push pillar. These land in the\n * events pipeline so segments can query them like any other event.\n */\nexport const PUSH_EVENTS = {\n SENT: '$push_sent',\n DELIVERED: '$push_delivered',\n DISPLAYED: '$push_displayed',\n RECEIVED: '$push_received',\n OPENED: '$push_opened',\n DISMISSED: '$push_dismissed',\n CLICKED: '$push_clicked',\n ACTION_CLICKED: '$push_action_clicked',\n BOUNCED: '$push_bounced',\n SILENT_ACK: '$push_silent_ack',\n} as const\n\nexport type PushEventName = (typeof PUSH_EVENTS)[keyof typeof PUSH_EVENTS]\n","import type { BillingInterval, BillingPriceKind } from '../types/billing.js'\n\nexport interface CommercialPlanDefinition {\n readonly id: 'starter' | 'pro' | 'scale'\n readonly name: string\n readonly publicSlug: string\n readonly description: string\n readonly priceKind: BillingPriceKind\n readonly selfServe: boolean\n readonly baseAmountCents: number\n readonly currency: 'USD'\n readonly includedMau: number\n readonly overagePer1kCents: number\n readonly appLimit: number | null\n readonly billingInterval: BillingInterval\n readonly sortOrder: number\n readonly accessRank: number\n readonly catalogVersion: number\n}\n\nexport const COMMERCIAL_BILLING_PLANS: ReadonlyArray<CommercialPlanDefinition> = [\n {\n id: 'starter',\n name: 'Starter',\n publicSlug: 'starter',\n description: 'For small teams getting started with product feedback.',\n priceKind: 'fixed',\n selfServe: true,\n baseAmountCents: 1_999,\n currency: 'USD',\n includedMau: 1_000,\n overagePer1kCents: 200,\n appLimit: 1,\n billingInterval: 'month',\n sortOrder: 10,\n accessRank: 10,\n catalogVersion: 1,\n },\n {\n id: 'pro',\n name: 'Pro',\n publicSlug: 'pro',\n description: 'For growing products with multiple applications.',\n priceKind: 'fixed',\n selfServe: true,\n baseAmountCents: 4_900,\n currency: 'USD',\n includedMau: 25_000,\n overagePer1kCents: 100,\n appLimit: 3,\n billingInterval: 'month',\n sortOrder: 20,\n accessRank: 20,\n catalogVersion: 1,\n },\n {\n id: 'scale',\n name: 'Scale',\n publicSlug: 'scale',\n description: 'Contract pricing, usage, and application limits for larger organizations.',\n priceKind: 'custom',\n selfServe: false,\n baseAmountCents: 0,\n currency: 'USD',\n includedMau: 0,\n overagePer1kCents: 0,\n appLimit: null,\n billingInterval: 'month',\n sortOrder: 30,\n accessRank: 30,\n catalogVersion: 1,\n },\n]\n\nexport const TRIAL_DAYS = 14\nexport const BILLING_GRACE_DAYS = 7\nexport const TRIAL_APP_LIMIT = 1\nexport const STARTER_FOUNDING_OFFER_CODE = 'starter_founding_100'\nexport const STARTER_FOUNDING_CUSTOMER_LIMIT = 100\n","/**\n * Runtime types shared by the React Native, iOS, and Android SDKs for\n * the \"under the hood\" push primitives:\n * • Silent reachability ping payloads\n * • Delivery beacon contract (delivered / displayed / dismissed)\n * • Channel registry (Android NotificationChannel + iOS category)\n * • App-open beacon\n */\n\nexport interface SilentPushPayload {\n readonly usergist_silent: '1'\n readonly usergist_ping_id: string\n}\n\nexport type AndroidImportance = 0 | 1 | 2 | 3 | 4\n\nexport type ChannelCategory =\n | 'transactional'\n | 'marketing'\n | 'silent'\n | 'digest'\n | 'alert'\n\nexport interface PushChannelDef {\n readonly app_id: string\n readonly channel_id: string\n readonly display_name: string\n readonly description: string | null\n readonly importance: AndroidImportance\n readonly default_sound: string | null\n readonly default_vibrate: boolean\n readonly default_badge: boolean\n readonly category: ChannelCategory\n}\n\nexport interface DeliveryBeacon {\n readonly deliveryId: string\n readonly occurredAt?: string\n readonly attemptId?: string\n readonly actionButton?: string\n}\n\nexport type DeliveryBeaconKind =\n | 'delivered'\n | 'displayed'\n | 'dismissed'\n\nexport interface SilentAck {\n readonly pingId: string\n readonly anonymousId: string\n readonly receivedAt?: string\n}\n\nexport interface RebindRequest {\n readonly anonymousId: string\n readonly externalId: string\n readonly token: string\n}\n\nexport interface AppOpenBeacon {\n readonly anonymousId: string\n readonly occurredAt?: string\n}\n\n/**\n * SDK-side recognized payload after parsing a server-sent push. Both\n * APNs (via NSE) and FCM (via FirebaseMessagingService) decode into\n * this shape so the cross-platform UI/behaviour layer can stay\n * platform-agnostic.\n */\nexport interface ParsedPushPayload {\n readonly campaignId: string\n readonly variantId: string\n readonly deliveryId: string\n readonly title: string\n readonly body: string\n readonly imageUrl: string | null\n readonly deepLink: string | null\n readonly language: string | null\n readonly actionButtons: ReadonlyArray<{\n readonly label: string\n readonly action: 'open_app' | 'deep_link' | 'url' | 'dismiss'\n readonly target?: string\n }>\n readonly androidChannelId: string | null\n readonly silent: boolean\n readonly silentPingId: string | null\n}\n\n/**\n * Helper used by the data-only Android branch and the iOS NSE to\n * detect a silent reachability ping.\n */\nexport function isSilentPushPayload(\n raw: Record<string, unknown> | null | undefined,\n): boolean {\n if (!raw) return false\n return raw.usergist_silent === '1' && typeof raw.usergist_ping_id === 'string'\n}\n","import type {\n Predicate,\n PredicateGroup,\n SegmentDsl,\n UserPropertyPredicate,\n EventCountPredicate,\n EventOccurredPredicate,\n} from '../types/segment-dsl.js'\nimport type {\n SerializedSegmentRules,\n UserPropertyRule,\n} from '../types/prompt.js'\n\nexport interface UserState {\n readonly properties: Readonly<Record<string, string | number | boolean | null | undefined>>\n // eventCounts: eventName -> map of windowDays -> count\n readonly eventCounts: Readonly<Record<string, Readonly<Record<number, number>>>>\n // lastEventAt: eventName -> ISO timestamp (most recent)\n readonly lastEventAt: Readonly<Record<string, string | undefined>>\n}\n\n/**\n * Evaluate a segment DSL against a user snapshot.\n *\n * @param now - Reference timestamp (ms since epoch) used for time-window\n * predicates. MUST be supplied explicitly so evaluation is deterministic\n * across processes (server trigger engine + client SDK), independent of\n * wall-clock skew. Defaults to `Date.now()` for backwards compatibility,\n * but callers that care about parity should pass the same `now` they pass\n * to the matching server-side call.\n */\nexport function evaluateSegment(\n dsl: SegmentDsl,\n user: UserState,\n now: number = Date.now(),\n): boolean {\n return evaluateGroup(dsl.root, user, now)\n}\n\nfunction evaluateGroup(group: PredicateGroup, user: UserState, now: number): boolean {\n if (group.predicates.length === 0) return true\n if (group.combinator === 'AND') {\n return group.predicates.every((p) => evaluateNode(p, user, now))\n }\n return group.predicates.some((p) => evaluateNode(p, user, now))\n}\n\nfunction evaluateNode(node: Predicate | PredicateGroup, user: UserState, now: number): boolean {\n if ('combinator' in node) return evaluateGroup(node, user, now)\n switch (node.kind) {\n case 'user_property':\n return evaluateUserProperty(node, user)\n case 'event_count':\n return evaluateEventCount(node, user)\n case 'event_occurred':\n return evaluateEventOccurred(node, user, now)\n }\n}\n\nfunction evaluateUserProperty(p: UserPropertyPredicate, user: UserState): boolean {\n const actual = user.properties[p.key]\n switch (p.op) {\n case 'exists':\n return actual !== undefined && actual !== null\n case 'not_exists':\n return actual === undefined || actual === null\n case 'eq':\n return actual === p.value\n case 'neq':\n return actual !== p.value\n case 'in':\n return Array.isArray(p.value) && actual != null && (p.value as ReadonlyArray<unknown>).includes(actual)\n case 'nin':\n return Array.isArray(p.value) && actual != null && !(p.value as ReadonlyArray<unknown>).includes(actual)\n case 'gt':\n return typeof actual === 'number' && typeof p.value === 'number' && actual > p.value\n case 'gte':\n return typeof actual === 'number' && typeof p.value === 'number' && actual >= p.value\n case 'lt':\n return typeof actual === 'number' && typeof p.value === 'number' && actual < p.value\n case 'lte':\n return typeof actual === 'number' && typeof p.value === 'number' && actual <= p.value\n case 'contains':\n return typeof actual === 'string' && typeof p.value === 'string' && actual.includes(p.value)\n case 'starts_with':\n return typeof actual === 'string' && typeof p.value === 'string' && actual.startsWith(p.value)\n }\n}\n\nfunction evaluateEventCount(p: EventCountPredicate, user: UserState): boolean {\n const eventBucket = user.eventCounts[p.eventName]\n const count = eventBucket?.[p.windowDays] ?? 0\n switch (p.op) {\n case 'eq': return count === p.count\n case 'gte': return count >= p.count\n case 'lte': return count <= p.count\n case 'gt': return count > p.count\n case 'lt': return count < p.count\n }\n}\n\nfunction evaluateEventOccurred(p: EventOccurredPredicate, user: UserState, now: number): boolean {\n const last = user.lastEventAt[p.eventName]\n if (p.ever) {\n if (!last) return false\n if (p.windowDays == null) return true\n const cutoff = now - p.windowDays * 86400_000\n return Date.parse(last) >= cutoff\n }\n if (!last) return true\n if (p.windowDays == null) return false\n const cutoff = now - p.windowDays * 86400_000\n return Date.parse(last) < cutoff\n}\n\n// ============================================================\n// SerializedSegmentRules → SegmentDsl bridge.\n//\n// The SDK ships armed triggers with a flattened rule set\n// (`SerializedSegmentRules`) for transport efficiency. We deliberately keep\n// only ONE evaluator (`evaluateSegment`) so that server and SDK paths cannot\n// diverge. The bridge converts the serialized form into an AND-combined\n// PredicateGroup and delegates to the same engine.\n// ============================================================\n\nexport function evaluateSerializedSegmentRules(\n rules: SerializedSegmentRules | null | undefined,\n user: UserState,\n now: number = Date.now(),\n): boolean {\n if (!rules) return true\n const dsl = serializedRulesToDsl(rules)\n return evaluateSegment(dsl, user, now)\n}\n\nexport function serializedRulesToDsl(rules: SerializedSegmentRules): SegmentDsl {\n const predicates: Predicate[] = []\n\n for (const rule of rules.userProperties ?? []) {\n predicates.push(userPropertyRuleToPredicate(rule))\n }\n for (const rule of rules.eventCounts ?? []) {\n predicates.push({\n kind: 'event_count',\n eventName: rule.eventName,\n op: rule.op,\n count: rule.count,\n windowDays: rule.windowDays,\n })\n }\n\n return {\n version: 1,\n root: { combinator: 'AND', predicates },\n }\n}\n\nfunction userPropertyRuleToPredicate(rule: UserPropertyRule): UserPropertyPredicate {\n // SerializedSegmentRules constrains operators to a subset; cast safely.\n return {\n kind: 'user_property',\n key: rule.key,\n op: rule.op,\n value: rule.value as UserPropertyPredicate['value'],\n }\n}\n","// ============================================================\n// Branch DSL evaluator — shared by SDKs and dashboard preview.\n// Given a flow, a current question, and the answer just recorded,\n// returns the next question id (or SURVEY_END_SENTINEL).\n// ============================================================\n\nimport {\n SURVEY_END_SENTINEL,\n type SurveyAnswerRecord,\n type SurveyAnswerValue,\n type SurveyBranch,\n type SurveyBranchCondition,\n type SurveyFlow,\n type SurveyQuestion,\n} from '../types/survey.js'\n\nexport function evaluateBranchCondition(\n cond: SurveyBranchCondition,\n answer: SurveyAnswerValue | undefined,\n): boolean {\n if (cond.op === 'answered') return answer !== undefined && answer !== null && answer !== ''\n if (cond.op === 'unanswered') return answer === undefined || answer === null || answer === ''\n if (answer === undefined || answer === null) return false\n\n switch (cond.op) {\n case 'eq':\n return answer === cond.value\n case 'neq':\n return answer !== cond.value\n case 'lt':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer < cond.value\n case 'lte':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer <= cond.value\n case 'gt':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer > cond.value\n case 'gte':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer >= cond.value\n case 'includes':\n return Array.isArray(answer) && (answer as ReadonlyArray<unknown>).includes(cond.value as never)\n case 'not_includes':\n return Array.isArray(answer) && !(answer as ReadonlyArray<unknown>).includes(cond.value as never)\n default:\n return false\n }\n}\n\nexport function nextQuestionId(\n flow: SurveyFlow,\n currentQuestionId: string,\n answers: SurveyAnswerRecord,\n): string | null {\n const branches = flow.branches.filter((b) => b.fromQuestionId === currentQuestionId)\n const answer = answers[currentQuestionId]\n for (const branch of branches) {\n if (evaluateBranchCondition(branch.condition, answer)) {\n if (branch.toQuestionId === SURVEY_END_SENTINEL) return null\n return branch.toQuestionId\n }\n }\n return defaultNext(flow, currentQuestionId)\n}\n\nfunction defaultNext(flow: SurveyFlow, currentQuestionId: string): string | null {\n const idx = flow.questions.findIndex((q) => q.id === currentQuestionId)\n if (idx < 0 || idx >= flow.questions.length - 1) return null\n const next = flow.questions[idx + 1]\n return next ? next.id : null\n}\n\nexport function findQuestion(\n flow: SurveyFlow,\n questionId: string,\n): SurveyQuestion | undefined {\n return flow.questions.find((q) => q.id === questionId)\n}\n\nexport function findQuestionIndex(flow: SurveyFlow, questionId: string): number {\n return flow.questions.findIndex((q) => q.id === questionId)\n}\n\n// Conservative progress estimate: count the current index + 1 over total. Branching\n// makes an exact number impossible, so we expose the worst-case fraction.\nexport function estimateProgress(flow: SurveyFlow, currentQuestionId: string | null): number {\n if (!currentQuestionId) return 1\n const idx = findQuestionIndex(flow, currentQuestionId)\n if (idx < 0) return 0\n return (idx + 1) / Math.max(1, flow.questions.length)\n}\n\n// Given a branch filter list, compute the *reachable* set of questions from a starting\n// point. Used by the composer to render \"dead question\" warnings.\nexport function reachableQuestions(\n flow: SurveyFlow,\n startId?: string,\n): ReadonlySet<string> {\n const start = startId ?? flow.startQuestionId\n const visited = new Set<string>()\n const stack: string[] = [start]\n while (stack.length > 0) {\n const id = stack.pop()\n if (id === undefined) continue\n if (visited.has(id)) continue\n visited.add(id)\n const outgoing = flow.branches.filter((b) => b.fromQuestionId === id)\n for (const b of outgoing) {\n if (b.toQuestionId !== SURVEY_END_SENTINEL) stack.push(b.toQuestionId)\n }\n const idx = flow.questions.findIndex((q) => q.id === id)\n if (idx >= 0 && idx < flow.questions.length - 1) {\n const next = flow.questions[idx + 1]\n if (next) stack.push(next.id)\n }\n }\n return visited\n}\n","import type { PeriodicFrequency } from '../types/campaign.js'\n\nexport interface PeriodicSchedule {\n readonly frequency: PeriodicFrequency\n readonly hourLocal: number\n readonly minuteLocal: number\n /** 0..6 (Sun=0). Required for `weekly`. */\n readonly weekday?: number\n /** 1..31. Required for `monthly`. */\n readonly dayOfMonth?: number\n /** IANA timezone the hour/minute are expressed in. Defaults to UTC. */\n readonly tz?: string\n}\n\n/**\n * Returns the next firing instant (as a Date in UTC) for a structured\n * periodic schedule, strictly after `now`.\n *\n * Pure / dependency-free. Used both server-side (push-scheduler `isDue`\n * check) and client-side (dashboard \"Next occurrence\" preview). Keep\n * deterministic for a given (schedule, now) tuple — no randomness.\n *\n * The walk is bounded — daily 2 iters, weekly 8, monthly 13 — so DST\n * gaps and short-month overflows can't loop forever.\n */\nexport function nextPeriodicFire(\n schedule: PeriodicSchedule,\n now: Date = new Date(),\n): Date {\n const tz = schedule.tz || 'UTC'\n const start = startCandidate(schedule, now, tz)\n return walkForward(start, schedule, now, tz)\n}\n\n/**\n * Minutes east of UTC for `tz` at instant `at`. Falls back to 0 (UTC)\n * for invalid input. Exported so server-side callers can share the\n * same offset math the periodic walker uses (avoids a separate\n * implementation in push-scheduler.ts).\n */\nexport function tzOffsetMinutes(at: Date, tz: string): number {\n if (tz === 'UTC') return 0\n try {\n const fmt = getFormatter(tz)\n const parts = fmt.formatToParts(at).reduce<Record<string, string>>((acc, p) => {\n if (p.type !== 'literal') acc[p.type] = p.value\n return acc\n }, {})\n const utc = Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour) === 24 ? 0 : Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n )\n return Math.round((utc - at.getTime()) / 60_000)\n } catch {\n return 0\n }\n}\n\nfunction startCandidate(\n schedule: PeriodicSchedule,\n now: Date,\n tz: string,\n): Date {\n const localNow = wallClock(now, tz)\n const target = new Date(localNow)\n target.setHours(schedule.hourLocal, schedule.minuteLocal, 0, 0)\n return localToUtc(target, tz)\n}\n\nfunction walkForward(\n candidate: Date,\n schedule: PeriodicSchedule,\n now: Date,\n tz: string,\n): Date {\n let cursor = candidate\n const max = schedule.frequency === 'daily' ? 2 : schedule.frequency === 'weekly' ? 8 : 13\n for (let i = 0; i < max; i++) {\n const local = wallClock(cursor, tz)\n if (matchesFrequency(local, schedule) && cursor.getTime() > now.getTime()) {\n return cursor\n }\n cursor = step(cursor, local, schedule, tz)\n }\n return cursor\n}\n\nfunction matchesFrequency(local: Date, schedule: PeriodicSchedule): boolean {\n if (schedule.frequency === 'daily') return true\n if (schedule.frequency === 'weekly') {\n return schedule.weekday === undefined || local.getDay() === schedule.weekday\n }\n return schedule.dayOfMonth === undefined || local.getDate() === schedule.dayOfMonth\n}\n\nfunction step(\n cursor: Date,\n cursorLocal: Date,\n schedule: PeriodicSchedule,\n tz: string,\n): Date {\n if (schedule.frequency === 'daily' || schedule.frequency === 'weekly') {\n return addDays(cursor, 1)\n }\n // Monthly: jump to the next month at the same dayOfMonth (or last day if shorter).\n const next = new Date(cursorLocal)\n next.setMonth(next.getMonth() + 1)\n if (schedule.dayOfMonth !== undefined) {\n const lastDay = lastDayOfMonth(next.getFullYear(), next.getMonth())\n next.setDate(Math.min(schedule.dayOfMonth, lastDay))\n }\n next.setHours(schedule.hourLocal, schedule.minuteLocal, 0, 0)\n return localToUtc(next, tz)\n}\n\nfunction addDays(d: Date, days: number): Date {\n const next = new Date(d.getTime())\n next.setDate(next.getDate() + days)\n return next\n}\n\nfunction lastDayOfMonth(year: number, monthIndex: number): number {\n return new Date(year, monthIndex + 1, 0).getDate()\n}\n\n/** Returns the Date adjusted so its `getX()` methods read in `tz`'s wall clock. */\nfunction wallClock(d: Date, tz: string): Date {\n const offsetMin = tzOffsetMinutes(d, tz)\n return new Date(d.getTime() + offsetMin * 60_000)\n}\n\n/** Inverse of `wallClock` — given a Date whose getX reads in `tz`, return UTC. */\nfunction localToUtc(localView: Date, tz: string): Date {\n const offsetMin = tzOffsetMinutes(localView, tz)\n return new Date(localView.getTime() - offsetMin * 60_000)\n}\n\n// `Intl.DateTimeFormat` construction dominates this module's cost (~100 µs\n// per ctor). The scheduler can call `nextPeriodicFire` thousands of times\n// per tick across many users, so we cache one formatter per tz at module\n// scope. Map is keyed by IANA name and lookups are O(1). Safe to share —\n// formatter instances are stateless across calls.\nconst FORMATTER_CACHE = /* @__PURE__ */ new Map<string, Intl.DateTimeFormat>()\n\nfunction getFormatter(tz: string): Intl.DateTimeFormat {\n const cached = FORMATTER_CACHE.get(tz)\n if (cached) return cached\n const fmt = new Intl.DateTimeFormat('en-US', {\n timeZone: tz,\n hour12: false,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n FORMATTER_CACHE.set(tz, fmt)\n return fmt\n}\n","// ============================================================\n// API contract — every endpoint path, method, request, response.\n// The API implements this; clients (dashboard, SDKs) consume it.\n// If you add/modify a route, update this file first.\n// ============================================================\n\nimport type {\n EventDefinition,\n IngestBatch,\n EventPropertySchema,\n} from '../types/event.js'\nimport type {\n ArmedTrigger,\n Prompt,\n Question,\n PromptTheme,\n FrequencyCaps,\n PromptStatus,\n} from '../types/prompt.js'\nimport type { Segment } from '../types/segment.js'\nimport type { SegmentDsl } from '../types/segment-dsl.js'\nimport type { AudienceSpec } from '../types/targeting.js'\nimport type { PromptResponse, SubmitResponsePayload } from '../types/response.js'\nimport type {\n FeedbackRecipient,\n InAppRecipient,\n RecipientList,\n SurveyRecipient,\n} from '../types/recipient.js'\nimport type {\n App,\n ApiToken,\n CreatedApiToken,\n CreatedApp,\n CreateApiTokenRequest,\n CreatedWriteKey,\n RotateWriteKeyRequest,\n RotateWriteKeyResponse,\n User,\n Workspace,\n WorkspaceWithRole,\n WorkspaceInvite,\n WorkspaceMember,\n WorkspaceRole,\n WriteKey,\n AcceptWorkspaceInviteRequest,\n AcceptWorkspaceInviteResponse,\n} from '../types/workspace.js'\nimport type { Consent } from '../types/sdk.js'\nimport type {\n ConnectIntegrationRequest,\n IntegrationDeliveriesResponse,\n IntegrationSummary,\n IntegrationTestResult,\n UpdateIntegrationRequest,\n} from '../types/integration.js'\nimport type {\n AdminWorkspaceSummary,\n BillingCheckoutRequest,\n BillingCheckoutResponse,\n BillingPlan,\n BillingUsage,\n BillingTrial,\n BillingPeriod,\n BillingOfferAvailability,\n BillingChangePlanRequest,\n BillingChangePlanResponse,\n Subscription,\n} from '../types/billing.js'\nimport type {\n AdminActivityEntry,\n AdminCustomerDetail,\n AdminCustomerListRequest,\n AdminCustomerListResponse,\n AdminSession,\n CreateWorkspacePlanGrantRequest,\n EffectivePlanAccess,\n ExtendWorkspacePlanGrantRequest,\n RevokeWorkspacePlanGrantRequest,\n WorkspacePlanGrant,\n} from '../types/admin.js'\nimport type {\n Campaign,\n CampaignAnalytics,\n CampaignWithVariants,\n CreateCampaignRequest,\n InvalidateDeviceTokenPayload,\n PushCredentialSummary,\n PushTransactionalRequest,\n RegisterDeviceTokenPayload,\n UpdateCampaignRequest,\n UpdateDeviceTokenPayload,\n UploadCredentialRequest,\n} from '../types/campaign.js'\nimport type {\n ArmedSurvey,\n CloneSurveyFromTemplateRequest,\n CompleteSurveyAttemptRequest,\n CreateSurveyAttemptRequest,\n CreateSurveyAttemptResponse,\n CreateSurveyRequest,\n ResolveSurveyLinkRequest,\n ResolveSurveyLinkResponse,\n SubmitSurveyAnswersRequest,\n SurveyAnalytics,\n SurveyCampaign,\n SurveyCampaignWithFlow,\n SurveyResponseRecord,\n SurveyShareLinkResponse,\n SurveySummary,\n SurveyTemplate,\n UpdateSurveyAttemptProgressRequest,\n UpdateSurveyRequest,\n} from '../types/survey.js'\nimport type {\n ArmedInAppMessage,\n CreateInAppMessageRequest,\n InAppMessage,\n InAppMessageAnalytics,\n UpdateInAppMessageRequest,\n} from '../types/inapp-message.js'\nimport type {\n Request,\n RequestStatus,\n RequestSummary,\n RequestDetail,\n RequestSearchResult,\n RequestVote,\n RequestFollow,\n GetRequestsOptions,\n GetRequestsResult,\n SubmitRequestPayload,\n RequestSettings,\n UpdateRequestSettingsRequest,\n UpdateRequestStatusRequest,\n UpdateRequestResponseRequest,\n UpdateRequestModerationRequest,\n MergeRequestsRequest,\n BulkUpdateStatusRequest,\n ListRequestsQuery,\n RequestUpvoterSegmentBreakdown,\n RequestTimelineEntry,\n RequestAnalytics,\n RequestPublicSummary,\n RequestPublicDetail,\n RequestPublicBranding,\n RequestComment,\n PostCommentPayload,\n EditCommentPayload,\n} from '../types/request.js'\nimport type {\n AppBrandSettings,\n BrandTheme,\n CreateBrandThemeRequest,\n ThemeMode,\n UpdateBrandThemeDefaultsRequest,\n UpdateBrandThemeRequest,\n} from '../types/brand.js'\n\n// ---------- auth ----------\n// Sign-in / sign-up / sign-out are handled by WorkOS AuthKit on the\n// dashboard side. The API exposes only /v1/me to surface the locally\n// mapped user + workspace state.\n\n// ---------- workspaces ----------\n\nexport interface CreateWorkspaceRequest {\n readonly name: string\n readonly slug?: string\n}\n\nexport interface InviteMemberRequest {\n readonly email: string\n readonly role: Exclude<WorkspaceRole, 'owner'>\n}\n\n// ---------- apps ----------\n\nexport interface CreateAppRequest {\n readonly name: string\n readonly slug?: string\n readonly platforms: App['platforms']\n readonly environment?: WriteKey['environment']\n}\n\nexport interface UpdateAppRequest {\n readonly name?: string\n readonly platforms?: App['platforms']\n readonly piiAllowList?: ReadonlyArray<string>\n readonly lifecycleEventsEnabled?: boolean\n}\n\nexport interface CreateWriteKeyRequest {\n readonly label?: string\n readonly environment?: WriteKey['environment']\n}\n\n// ---------- event definitions ----------\n\nexport interface RegisterEventDefinitionRequest {\n readonly name: string\n readonly description?: string\n readonly properties?: ReadonlyArray<EventPropertySchema>\n}\n\nexport interface UpdateEventDefinitionRequest {\n readonly description?: string\n readonly properties?: ReadonlyArray<EventPropertySchema>\n readonly status?: EventDefinition['status']\n}\n\n// ---------- segments ----------\n\nexport interface CreateSegmentRequest {\n readonly name: string\n readonly description?: string\n // New segments persist `definition: AudienceSpec` (the same shape\n // feedback / surveys / push targeting use). `rules: SegmentDsl` is\n // accepted for back-compat — exactly one of the two must be set.\n readonly definition?: AudienceSpec\n readonly rules?: SegmentDsl\n readonly refreshMode?: 'hot' | 'cold' | 'manual'\n}\n\nexport interface AppUserSummary {\n readonly subjectId: string\n readonly anonymousId: string\n readonly anonymousIds: ReadonlyArray<string>\n readonly externalId?: string | null\n readonly firstSeenAt: string\n readonly lastSeenAt: string\n readonly eventCount?: number\n readonly topProperties?: Readonly<Record<string, string | number | boolean | null>>\n // Latest device-context fields surfaced from usergist.events (argMax\n // by occurred_at). Useful in the users list + user detail card.\n readonly country?: string | null\n readonly platform?: string | null\n}\n\nexport interface AppUserDetail {\n readonly subjectId: string\n readonly anonymousId: string\n readonly anonymousIds: ReadonlyArray<string>\n readonly externalId?: string | null\n readonly firstSeenAt: string\n readonly lastSeenAt: string\n readonly properties: Readonly<Record<string, string | number | boolean | null>>\n readonly eventCount: number\n readonly country?: string | null\n readonly platform?: string | null\n}\n\nexport interface AppUserEvent {\n readonly id: string\n readonly name: string\n readonly occurredAt: string\n readonly properties: Readonly<Record<string, unknown>>\n readonly platform?: string | null\n readonly appVersion?: string | null\n}\n\nexport interface PaginatedAppUsers {\n readonly items: ReadonlyArray<AppUserSummary>\n readonly total: number\n readonly nextCursor: string | null\n}\n\nexport interface PaginatedAppUserEvents {\n readonly items: ReadonlyArray<AppUserEvent>\n readonly nextCursor: string | null\n}\n\nexport interface ListUsersQuery {\n readonly q?: string\n readonly cursor?: string\n readonly limit?: number\n}\n\nexport interface ListUserEventsQuery {\n readonly from?: string\n readonly to?: string\n readonly cursor?: string\n readonly limit?: number\n}\n\nexport interface GenerateSegmentRulesRequest {\n readonly name?: string\n readonly description?: string\n}\n\nexport interface GenerateSegmentRulesResponse {\n readonly rules: SegmentDsl\n readonly rationale: string\n}\n\nexport interface GenerateSegmentNameRequest {\n readonly rules: SegmentDsl\n}\n\nexport interface GenerateSegmentNameResponse {\n readonly name: string\n readonly description: string\n}\n\nexport interface SegmentPreview {\n readonly estimatedCount: number\n readonly sampleUsers: ReadonlyArray<{\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly properties: Record<string, unknown>\n }>\n}\n\n// ---------- prompts ----------\n\nexport interface CreatePromptRequest {\n readonly name: string\n readonly triggerEventName: string\n readonly segmentId?: string | null\n readonly questions: ReadonlyArray<Question>\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly frequency?: FrequencyCaps\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: PromptStatus\n}\n\nexport interface UpdatePromptRequest {\n readonly name?: string\n readonly triggerEventName?: string\n readonly segmentId?: string | null\n readonly questions?: ReadonlyArray<Question>\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly frequency?: FrequencyCaps\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: PromptStatus\n}\n\nexport interface TestPromptOnDeviceRequest {\n readonly anonymousId: string\n}\n\n// ---------- responses ----------\n\nexport interface ListResponsesQuery {\n readonly promptId?: string\n readonly from?: string\n readonly to?: string\n readonly page?: number\n readonly limit?: number\n readonly segmentId?: string\n}\n\nexport interface PromptAnalytics {\n readonly promptId: string\n readonly shown: number\n readonly responded: number\n readonly dismissed: number\n readonly completionRate: number\n readonly perQuestion: ReadonlyArray<{\n readonly questionId: string\n readonly type: Question['type']\n readonly distribution: Readonly<Record<string, number>>\n readonly average?: number\n readonly npsScore?: number\n }>\n}\n\n// ---------- SDK-facing ----------\n\nexport interface SdkIngestRequest extends IngestBatch {}\n\nexport interface SdkIngestResponse {\n readonly accepted: number\n readonly rejected: number\n readonly errors?: ReadonlyArray<{ index: number; reason: string }>\n}\n\nexport interface SdkArmedTriggersResponse {\n readonly triggers: ReadonlyArray<ArmedTrigger>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkArmedInAppMessagesResponse {\n readonly messages: ReadonlyArray<ArmedInAppMessage>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkArmedSurveysResponse {\n readonly surveys: ReadonlyArray<ArmedSurvey>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkConsentPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly purposes: Consent\n readonly version: number\n readonly effectiveAt: string\n}\n\nexport interface SdkSessionResponse {\n readonly subjectToken: string\n readonly subjectId: string\n readonly expiresAt: string\n}\n\nexport interface SdkIdentifyPayload {\n readonly anonymousId: string\n readonly externalId: string\n readonly properties?: Record<string, string | number | boolean | null>\n}\n\n// ---------- GDPR ----------\n\nexport interface GdprDeleteRequest {\n readonly externalId?: string\n readonly anonymousId?: string\n}\n\nexport interface GdprExportRequest {\n readonly externalId?: string\n readonly anonymousId?: string\n}\n\n// ---------- endpoint map ----------\n// Keys are method+path. Values are { request, response } for typing.\n// This is kept as a literal object so it can be walked at build time\n// to generate a typed client and OpenAPI spec.\n\nexport type Endpoint<Req, Res> = { readonly __req?: Req; readonly __res: Res }\n\nexport const endpoints = {\n 'GET /v1/me': {} as Endpoint<void, { user: User; workspaces: ReadonlyArray<WorkspaceWithRole> }>,\n\n 'GET /v1/workspaces': {} as Endpoint<void, ReadonlyArray<Workspace>>,\n 'POST /v1/workspaces': {} as Endpoint<CreateWorkspaceRequest, Workspace>,\n 'GET /v1/workspaces/:wid/members': {} as Endpoint<void, ReadonlyArray<WorkspaceMember>>,\n 'GET /v1/workspaces/:wid/invites': {} as Endpoint<void, ReadonlyArray<WorkspaceInvite>>,\n 'POST /v1/workspaces/:wid/invites': {} as Endpoint<InviteMemberRequest, { queued: true }>,\n 'DELETE /v1/workspaces/:wid/invites/:inviteId': {} as Endpoint<void, { revoked: true }>,\n 'POST /v1/invites/accept': {} as Endpoint<\n AcceptWorkspaceInviteRequest,\n AcceptWorkspaceInviteResponse\n >,\n\n 'GET /v1/workspaces/:wid/apps': {} as Endpoint<void, ReadonlyArray<App>>,\n 'POST /v1/workspaces/:wid/apps': {} as Endpoint<CreateAppRequest, CreatedApp>,\n 'GET /v1/workspaces/:wid/api-tokens': {} as Endpoint<void, ReadonlyArray<ApiToken>>,\n 'POST /v1/workspaces/:wid/api-tokens': {} as Endpoint<CreateApiTokenRequest, CreatedApiToken>,\n 'DELETE /v1/workspaces/:wid/api-tokens/:tokenId': {} as Endpoint<void, { revoked: true }>,\n 'GET /v1/apps/:appId': {} as Endpoint<void, App>,\n 'PATCH /v1/apps/:appId': {} as Endpoint<UpdateAppRequest, App>,\n 'DELETE /v1/apps/:appId': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/sdk/subject-tokens': {} as Endpoint<\n { externalId: string },\n SdkSessionResponse\n >,\n\n // ---------- outbound analytics integrations ----------\n 'GET /v1/apps/:appId/integrations': {} as Endpoint<void, ReadonlyArray<IntegrationSummary>>,\n 'PUT /v1/apps/:appId/integrations/:provider': {} as Endpoint<ConnectIntegrationRequest, { integration: IntegrationSummary; test: IntegrationTestResult }>,\n 'PATCH /v1/apps/:appId/integrations/:provider': {} as Endpoint<UpdateIntegrationRequest, IntegrationSummary>,\n 'POST /v1/apps/:appId/integrations/:provider/test': {} as Endpoint<Record<string, never>, IntegrationTestResult>,\n 'POST /v1/apps/:appId/integrations/:provider/pause': {} as Endpoint<Record<string, never>, IntegrationSummary>,\n 'POST /v1/apps/:appId/integrations/:provider/resume': {} as Endpoint<Record<string, never>, IntegrationSummary>,\n 'DELETE /v1/apps/:appId/integrations/:provider': {} as Endpoint<void, { disconnected: true }>,\n 'GET /v1/apps/:appId/integrations/:provider/deliveries': {} as Endpoint<{ cursor?: string; limit?: number }, IntegrationDeliveriesResponse>,\n\n 'GET /v1/apps/:appId/brand-settings': {} as Endpoint<void, AppBrandSettings>,\n 'POST /v1/apps/:appId/brand-themes': {} as Endpoint<CreateBrandThemeRequest, BrandTheme>,\n 'PATCH /v1/apps/:appId/brand-themes/:themeId':\n {} as Endpoint<UpdateBrandThemeRequest, BrandTheme>,\n 'DELETE /v1/apps/:appId/brand-themes/:themeId': {} as Endpoint<void, { ok: true }>,\n 'PUT /v1/apps/:appId/brand-theme-defaults':\n {} as Endpoint<UpdateBrandThemeDefaultsRequest, AppBrandSettings>,\n\n 'GET /v1/apps/:appId/write-keys': {} as Endpoint<void, ReadonlyArray<WriteKey>>,\n 'POST /v1/apps/:appId/write-keys': {} as Endpoint<CreateWriteKeyRequest, CreatedWriteKey>,\n 'POST /v1/apps/:appId/write-keys/:keyId/rotate':\n {} as Endpoint<RotateWriteKeyRequest, RotateWriteKeyResponse>,\n 'DELETE /v1/apps/:appId/write-keys/:keyId': {} as Endpoint<void, { ok: true }>,\n\n 'GET /v1/apps/:appId/event-definitions': {} as Endpoint<void, ReadonlyArray<EventDefinition>>,\n 'POST /v1/apps/:appId/event-definitions': {} as Endpoint<RegisterEventDefinitionRequest, EventDefinition>,\n 'PATCH /v1/apps/:appId/event-definitions/:defId': {} as Endpoint<UpdateEventDefinitionRequest, EventDefinition>,\n\n 'GET /v1/apps/:appId/segments': {} as Endpoint<void, ReadonlyArray<Segment>>,\n 'POST /v1/apps/:appId/segments': {} as Endpoint<CreateSegmentRequest, Segment>,\n 'GET /v1/apps/:appId/segments/:segId': {} as Endpoint<void, Segment>,\n 'PATCH /v1/apps/:appId/segments/:segId': {} as Endpoint<Partial<CreateSegmentRequest>, Segment>,\n 'DELETE /v1/apps/:appId/segments/:segId': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/segments/:segId/preview': {} as Endpoint<void, SegmentPreview>,\n 'POST /v1/apps/:appId/segments/:segId/rebuild': {} as Endpoint<void, { scheduled: true }>,\n 'GET /v1/apps/:appId/users': {} as Endpoint<ListUsersQuery, PaginatedAppUsers>,\n 'GET /v1/apps/:appId/users/:anonymousId': {} as Endpoint<void, AppUserDetail>,\n 'GET /v1/apps/:appId/users/:anonymousId/events': {} as Endpoint<ListUserEventsQuery, PaginatedAppUserEvents>,\n 'GET /v1/apps/:appId/users/:anonymousId/push': {} as Endpoint<\n void,\n {\n consent: { push: boolean; feedback: boolean; analytics: boolean; recordedAt: string | null }\n devices: ReadonlyArray<{\n id: string\n platform: 'ios' | 'android'\n environment: 'production' | 'sandbox'\n language: string | null\n timezone: string | null\n appVersion: string | null\n sdkVersion: string | null\n optIn: boolean\n lastSeenAt: string\n invalidatedAt: string | null\n createdAt: string\n }>\n }\n >,\n 'POST /v1/apps/:appId/users/:anonymousId/push/test-send': {} as Endpoint<\n { title: string; body: string; imageUrl?: string; deepLink?: string },\n { dispatched: number; held: number; dropped: number; errors: ReadonlyArray<{ reason: string }> }\n >,\n\n 'POST /v1/apps/:appId/segments/ai-generate-rules': {} as Endpoint<GenerateSegmentRulesRequest, GenerateSegmentRulesResponse>,\n 'POST /v1/apps/:appId/segments/ai-generate-name': {} as Endpoint<GenerateSegmentNameRequest, GenerateSegmentNameResponse>,\n\n 'GET /v1/apps/:appId/prompts': {} as Endpoint<void, ReadonlyArray<Prompt>>,\n 'POST /v1/apps/:appId/prompts': {} as Endpoint<CreatePromptRequest, Prompt>,\n 'GET /v1/apps/:appId/prompts/:promptId': {} as Endpoint<void, Prompt>,\n 'PATCH /v1/apps/:appId/prompts/:promptId': {} as Endpoint<UpdatePromptRequest, Prompt>,\n 'DELETE /v1/apps/:appId/prompts/:promptId': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/prompts/:promptId/test-on-device': {} as Endpoint<TestPromptOnDeviceRequest, { dispatched: true }>,\n\n 'GET /v1/apps/:appId/prompts/:promptId/responses': {} as Endpoint<ListResponsesQuery, ReadonlyArray<PromptResponse>>,\n 'GET /v1/apps/:appId/prompts/:promptId/recipients': {} as Endpoint<\n { from?: string; to?: string },\n RecipientList<FeedbackRecipient>\n >,\n 'GET /v1/apps/:appId/prompts/:promptId/analytics': {} as Endpoint<\n { from?: string; to?: string },\n PromptAnalytics\n >,\n\n // App-level analytics rollup — daily (or hourly for 24h) buckets across all\n // four pillars. Used by the dashboard overview to render \"last N days\"\n // performance charts without spamming per-resource analytics endpoints.\n 'GET /v1/apps/:appId/analytics/overview': {} as Endpoint<\n { range?: '24h' | '7d' | '30d' },\n {\n readonly range: '24h' | '7d' | '30d'\n readonly bucket: 'hour' | 'day'\n readonly buckets: ReadonlyArray<{\n readonly bucket: string\n readonly push: { sent: number; opened: number; clicked: number }\n readonly inapp: { impressions: number; dismissed: number; ctaClicked: number }\n readonly prompts: { shown: number; responded: number; dismissed: number }\n readonly surveys: { started: number; completed: number }\n }>\n readonly totals: {\n readonly push: { sent: number; opened: number; clicked: number }\n readonly inapp: { impressions: number; dismissed: number; ctaClicked: number }\n readonly prompts: { shown: number; responded: number; dismissed: number }\n readonly surveys: { started: number; completed: number }\n }\n }\n >,\n\n // Inline AudienceSpec preview — count of users matching the (unsaved) spec.\n // Used by the dashboard's TARGET step to power the live count badge.\n 'POST /v1/apps/:appId/audience/preview': {} as Endpoint<\n import('../types/targeting.js').AudienceSpec,\n { matching: number; sampleUsers: ReadonlyArray<AppUserSummary> }\n >,\n\n // SDK-facing (authenticated via write key)\n 'POST /v1/sdk/ingest': {} as Endpoint<SdkIngestRequest, SdkIngestResponse>,\n 'GET /v1/sdk/armed-triggers': {} as Endpoint<{ anonymousId: string; externalId?: string }, SdkArmedTriggersResponse>,\n 'POST /v1/sdk/consent': {} as Endpoint<SdkConsentPayload, { ok: true }>,\n 'POST /v1/sdk/identify': {} as Endpoint<SdkIdentifyPayload, { ok: true }>,\n 'POST /v1/sdk/responses': {} as Endpoint<SubmitResponsePayload, { ok: true }>,\n\n // GDPR\n 'POST /v1/apps/:appId/gdpr/delete': {} as Endpoint<GdprDeleteRequest, { scheduled: true }>,\n 'POST /v1/apps/:appId/gdpr/export': {} as Endpoint<GdprExportRequest, { scheduled: true; exportId: string }>,\n 'GET /v1/apps/:appId/gdpr/exports/:exportId': {} as Endpoint<void, { status: 'pending' | 'running' | 'completed' | 'failed'; downloadUrl?: string }>,\n\n // Campaigns (push)\n 'GET /v1/apps/:appId/campaigns': {} as Endpoint<void, ReadonlyArray<Campaign>>,\n 'POST /v1/apps/:appId/campaigns': {} as Endpoint<CreateCampaignRequest, CampaignWithVariants>,\n 'GET /v1/apps/:appId/campaigns/:cid': {} as Endpoint<void, CampaignWithVariants>,\n 'PATCH /v1/apps/:appId/campaigns/:cid': {} as Endpoint<UpdateCampaignRequest, CampaignWithVariants>,\n 'DELETE /v1/apps/:appId/campaigns/:cid': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/campaigns/:cid/activate': {} as Endpoint<void, Campaign>,\n 'POST /v1/apps/:appId/campaigns/:cid/pause': {} as Endpoint<void, Campaign>,\n 'POST /v1/apps/:appId/campaigns/:cid/resend': {} as Endpoint<void, { queued: number }>,\n 'POST /v1/apps/:appId/campaigns/:cid/preview': {} as Endpoint<{ anonymousId?: string; mergeTags?: Record<string, unknown> }, ReadonlyArray<{ variantId: string; language: string | null; title: string; body: string }>>,\n 'POST /v1/apps/:appId/campaigns/:cid/test-send': {} as Endpoint<{ anonymousId: string }, { queued: true }>,\n 'GET /v1/apps/:appId/campaigns/:cid/analytics': {} as Endpoint<\n { from?: string; to?: string },\n CampaignAnalytics\n >,\n 'GET /v1/apps/:appId/campaigns/:cid/deliveries': {} as Endpoint<\n { limit?: number },\n ReadonlyArray<{\n delivery_id: string\n variant_id: string\n language: string | null\n anonymous_id: string\n external_id: string | null\n platform: string\n sent_at: string\n delivered_at: string | null\n displayed_at: string | null\n opened_at: string | null\n dismissed_at: string | null\n clicked_at: string | null\n error_code: string | null\n bounce_class: string\n provider_latency_ms: number\n }>\n >,\n\n // Push credentials\n 'GET /v1/apps/:appId/push/credentials': {} as Endpoint<void, ReadonlyArray<PushCredentialSummary>>,\n 'POST /v1/apps/:appId/push/credentials': {} as Endpoint<UploadCredentialRequest, PushCredentialSummary>,\n 'DELETE /v1/apps/:appId/push/credentials/:credId': {} as Endpoint<void, { ok: true }>,\n 'GET /v1/apps/:appId/push/stats': {} as Endpoint<\n void,\n {\n credentials: { ios: boolean; android: boolean }\n deviceTokens: { total: number; ios: number; android: number }\n campaignCount: number\n }\n >,\n 'GET /v1/apps/:appId/push/audience-estimate': {} as Endpoint<\n { segmentId?: string },\n { audienceSize: number; withPush: number; iosCount: number; androidCount: number }\n >,\n 'GET /v1/apps/:appId/push/reachability': {} as Endpoint<\n void,\n {\n optedIn: number\n reachable: number\n unreachable: number\n bouncedToday: number\n pingedToday: number\n }\n >,\n\n // Push channels (per-app NotificationChannel registry / iOS category id)\n 'GET /v1/apps/:appId/push/channels': {} as Endpoint<\n void,\n {\n channels: ReadonlyArray<{\n readonly app_id: string\n readonly channel_id: string\n readonly display_name: string\n readonly description: string | null\n readonly importance: number\n readonly default_sound: string | null\n readonly default_vibrate: boolean\n readonly default_badge: boolean\n readonly category: string\n }>\n }\n >,\n 'PUT /v1/apps/:appId/push/channels': {} as Endpoint<\n {\n channelId: string\n displayName: string\n description?: string | null\n importance?: number\n defaultSound?: string | null\n defaultVibrate?: boolean\n defaultBadge?: boolean\n category?: 'transactional' | 'marketing' | 'silent' | 'digest' | 'alert'\n },\n { saved: true }\n >,\n 'DELETE /v1/apps/:appId/push/channels/:channelId': {} as Endpoint<void, { archived: true }>,\n\n // Push outbound webhooks\n 'GET /v1/apps/:appId/push/webhooks': {} as Endpoint<\n void,\n {\n webhooks: ReadonlyArray<{\n id: string\n url: string\n event_types: ReadonlyArray<string>\n active: boolean\n description: string | null\n last_success_at: string | null\n last_failure_at: string | null\n last_failure_reason: string | null\n created_at: string\n updated_at: string\n }>\n }\n >,\n 'POST /v1/apps/:appId/push/webhooks': {} as Endpoint<\n {\n url: string\n eventTypes: ReadonlyArray<string>\n active?: boolean\n description?: string | null\n },\n { id: string; secret: string }\n >,\n 'PATCH /v1/apps/:appId/push/webhooks/:webhookId': {} as Endpoint<\n Partial<{\n url: string\n eventTypes: ReadonlyArray<string>\n active: boolean\n description: string | null\n }>,\n { saved: true }\n >,\n 'DELETE /v1/apps/:appId/push/webhooks/:webhookId': {} as Endpoint<void, { deleted: true }>,\n 'POST /v1/apps/:appId/push/webhooks/:webhookId/rotate': {} as Endpoint<void, { secret: string }>,\n 'POST /v1/apps/:appId/push/webhooks/:webhookId/test': {} as Endpoint<\n void,\n { success: boolean; statusCode: number; attempts: number; error?: string }\n >,\n\n // Push device-token registration (SDK-facing, write-key auth)\n 'POST /v1/sdk/push/register-token': {} as Endpoint<RegisterDeviceTokenPayload, { registered: true } | { skipped: 'consent' }>,\n 'POST /v1/sdk/push/update-token': {} as Endpoint<UpdateDeviceTokenPayload, { updated: true }>,\n 'POST /v1/sdk/push/invalidate-token': {} as Endpoint<InvalidateDeviceTokenPayload, { invalidated: true }>,\n 'POST /v1/sdk/push/rebind': {} as Endpoint<\n { anonymousId: string; externalId: string; token: string },\n { rebound: boolean }\n >,\n 'POST /v1/sdk/push/app-open': {} as Endpoint<\n { anonymousId: string; occurredAt?: string },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/delivered': {} as Endpoint<\n { deliveryId: string; occurredAt?: string; attemptId?: string; actionButton?: string },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/displayed': {} as Endpoint<\n { deliveryId: string; occurredAt?: string; attemptId?: string; actionButton?: string },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/dismissed': {} as Endpoint<\n { deliveryId: string; occurredAt?: string; attemptId?: string; actionButton?: string },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/silent-ack': {} as Endpoint<\n { pingId: string; anonymousId: string; receivedAt?: string },\n { recorded: true; pingId: string }\n >,\n 'GET /v1/sdk/push/channels': {} as Endpoint<\n void,\n { channels: ReadonlyArray<unknown> }\n >,\n 'POST /v1/sdk/push/channels/subscription': {} as Endpoint<\n { anonymousId: string; channelId: string; subscribed: boolean },\n { saved: true }\n >,\n\n // Transactional push (server API token auth)\n 'POST /v1/apps/:appId/push/transactional': {} as Endpoint<PushTransactionalRequest, { queued: true; deliveryId: string; idempotent?: boolean }>,\n\n // Surveys — dashboard CRUD\n 'GET /v1/apps/:appId/surveys': {} as Endpoint<void, ReadonlyArray<SurveyCampaign>>,\n 'POST /v1/apps/:appId/surveys': {} as Endpoint<CreateSurveyRequest, SurveyCampaignWithFlow>,\n 'GET /v1/apps/:appId/surveys/:sid': {} as Endpoint<void, SurveyCampaignWithFlow>,\n 'PATCH /v1/apps/:appId/surveys/:sid': {} as Endpoint<UpdateSurveyRequest, SurveyCampaignWithFlow>,\n 'DELETE /v1/apps/:appId/surveys/:sid': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/surveys/:sid/activate': {} as Endpoint<void, SurveyCampaign>,\n 'POST /v1/apps/:appId/surveys/:sid/pause': {} as Endpoint<void, SurveyCampaign>,\n 'POST /v1/apps/:appId/surveys/:sid/archive': {} as Endpoint<void, SurveyCampaign>,\n 'POST /v1/apps/:appId/surveys/:sid/preview': {} as Endpoint<\n { anonymousId?: string; mergeTags?: Record<string, unknown>; language?: string },\n SurveyCampaignWithFlow\n >,\n 'POST /v1/apps/:appId/surveys/:sid/test-on-device': {} as Endpoint<{ anonymousId: string }, { dispatched: true }>,\n 'GET /v1/apps/:appId/surveys/:sid/analytics': {} as Endpoint<\n { from?: string; to?: string },\n SurveyAnalytics\n >,\n 'GET /v1/apps/:appId/surveys/:sid/responses': {} as Endpoint<\n { from?: string; to?: string; page?: number; limit?: number; segmentId?: string; language?: string },\n ReadonlyArray<SurveyResponseRecord>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/recipients': {} as Endpoint<\n { from?: string; to?: string },\n RecipientList<SurveyRecipient>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/attempts': {} as Endpoint<\n void,\n ReadonlyArray<{\n id: string\n campaignId: string\n anonymousId: string\n externalId: string | null\n startedAt: string\n completedAt: string | null\n abandonedAt: string | null\n currentQuestionId: string | null\n progressSnapshot: unknown\n source: string\n language: string | null\n }>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/share-link': {} as Endpoint<void, SurveyShareLinkResponse>,\n 'GET /v1/apps/:appId/survey-templates': {} as Endpoint<void, ReadonlyArray<SurveyTemplate>>,\n 'POST /v1/apps/:appId/surveys/from-template/:slug': {} as Endpoint<\n CloneSurveyFromTemplateRequest,\n SurveyCampaignWithFlow\n >,\n\n // Surveys — SDK-facing (write-key auth)\n 'GET /v1/sdk/surveys/available': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n { surveys: ReadonlyArray<SurveySummary> }\n >,\n 'POST /v1/sdk/surveys/resolve-link': {} as Endpoint<ResolveSurveyLinkRequest, ResolveSurveyLinkResponse>,\n 'GET /v1/sdk/surveys/:sid': {} as Endpoint<\n { anonymousId: string; externalId?: string; language?: string },\n SurveyCampaignWithFlow\n >,\n 'POST /v1/sdk/surveys/:sid/attempts': {} as Endpoint<CreateSurveyAttemptRequest, CreateSurveyAttemptResponse>,\n 'PATCH /v1/sdk/surveys/attempts/:attemptId': {} as Endpoint<UpdateSurveyAttemptProgressRequest, { ok: true }>,\n 'POST /v1/sdk/surveys/attempts/:attemptId/responses': {} as Endpoint<SubmitSurveyAnswersRequest, { ok: true }>,\n 'POST /v1/sdk/surveys/attempts/:attemptId/complete': {} as Endpoint<CompleteSurveyAttemptRequest, { ok: true }>,\n 'POST /v1/sdk/surveys/attempts/:attemptId/abandon': {} as Endpoint<void, { ok: true }>,\n\n // ---------- in-app messages (4th pillar) ----------\n 'GET /v1/apps/:appId/inapp-messages': {} as Endpoint<void, ReadonlyArray<InAppMessage>>,\n 'POST /v1/apps/:appId/inapp-messages': {} as Endpoint<CreateInAppMessageRequest, InAppMessage>,\n 'GET /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<void, InAppMessage>,\n 'PATCH /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<UpdateInAppMessageRequest, InAppMessage>,\n 'DELETE /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/inapp-messages/:id/activate': {} as Endpoint<void, InAppMessage>,\n 'POST /v1/apps/:appId/inapp-messages/:id/pause': {} as Endpoint<void, InAppMessage>,\n 'GET /v1/apps/:appId/inapp-messages/:id/analytics': {} as Endpoint<\n { from?: string; to?: string },\n InAppMessageAnalytics\n >,\n 'GET /v1/apps/:appId/inapp-messages/:id/recipients': {} as Endpoint<\n { from?: string; to?: string },\n RecipientList<InAppRecipient>\n >,\n 'GET /v1/sdk/armed-inapp-messages': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n SdkArmedInAppMessagesResponse\n >,\n\n // ---------- feature requests (5th pillar) — dashboard ----------\n 'GET /v1/apps/:appId/requests': {} as Endpoint<ListRequestsQuery, ReadonlyArray<RequestSummary>>,\n 'GET /v1/apps/:appId/requests/:requestId': {} as Endpoint<void, RequestDetail>,\n 'PATCH /v1/apps/:appId/requests/:requestId/status':\n {} as Endpoint<UpdateRequestStatusRequest, RequestDetail>,\n 'PUT /v1/apps/:appId/requests/:requestId/response':\n {} as Endpoint<UpdateRequestResponseRequest, RequestDetail>,\n 'PATCH /v1/apps/:appId/requests/:requestId/moderation':\n {} as Endpoint<UpdateRequestModerationRequest, RequestDetail>,\n 'POST /v1/apps/:appId/requests/merge':\n {} as Endpoint<MergeRequestsRequest, { canonicalId: string; mergedCount: number }>,\n 'POST /v1/apps/:appId/requests/bulk/status':\n {} as Endpoint<BulkUpdateStatusRequest, { updated: number }>,\n 'GET /v1/apps/:appId/requests/:requestId/upvoter-segments':\n {} as Endpoint<void, RequestUpvoterSegmentBreakdown>,\n 'GET /v1/apps/:appId/requests/:requestId/timeline':\n {} as Endpoint<void, ReadonlyArray<RequestTimelineEntry>>,\n 'GET /v1/apps/:appId/requests/:requestId/analytics':\n {} as Endpoint<{ from?: string; to?: string }, RequestAnalytics>,\n 'GET /v1/apps/:appId/requests/:requestId/audience-spec':\n {} as Endpoint<void, { audience: AudienceSpec }>,\n 'GET /v1/apps/:appId/request-settings': {} as Endpoint<void, RequestSettings>,\n 'PUT /v1/apps/:appId/request-settings':\n {} as Endpoint<UpdateRequestSettingsRequest, RequestSettings>,\n 'GET /v1/apps/:appId/request-settings/slug-available':\n {} as Endpoint<{ slug: string }, { available: boolean }>,\n 'POST /v1/apps/:appId/requests/seed-segments': {} as Endpoint<void, { created: number }>,\n\n // ---------- feature requests — SDK (write-key) ----------\n 'GET /v1/sdk/requests': {} as Endpoint<\n GetRequestsOptions & { anonymousId: string; externalId?: string },\n GetRequestsResult\n >,\n 'GET /v1/sdk/request-branding': {} as Endpoint<\n void,\n {\n readonly entryLabel: string\n readonly accentColor: string | null\n readonly logoUrl: string | null\n readonly introCopy: string | null\n }\n >,\n 'GET /v1/sdk/requests/search': {} as Endpoint<\n { q: string; anonymousId: string; externalId?: string; limit?: number },\n { results: ReadonlyArray<RequestSearchResult> }\n >,\n 'GET /v1/sdk/requests/:requestId': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n Request\n >,\n 'POST /v1/sdk/requests': {} as Endpoint<SubmitRequestPayload, Request>,\n 'POST /v1/sdk/requests/:requestId/vote': {} as Endpoint<\n { anonymousId: string; externalId?: string | null; vote: boolean },\n RequestVote\n >,\n 'POST /v1/sdk/requests/:requestId/follow': {} as Endpoint<\n { anonymousId: string; externalId?: string | null; follow: boolean },\n RequestFollow\n >,\n\n // ---------- feature requests — comments ----------\n // Dashboard (cookie auth)\n 'GET /v1/apps/:appId/requests/:requestId/comments': {} as Endpoint<\n void,\n { items: ReadonlyArray<RequestComment> }\n >,\n 'DELETE /v1/apps/:appId/requests/:requestId/comments/:commentId': {} as Endpoint<\n void,\n { ok: true }\n >,\n\n // SDK (write-key)\n 'GET /v1/sdk/requests/:requestId/comments': {} as Endpoint<\n { anonymousId: string; externalId?: string | null },\n { items: ReadonlyArray<RequestComment> }\n >,\n 'POST /v1/sdk/requests/:requestId/comments': {} as Endpoint<\n PostCommentPayload,\n RequestComment\n >,\n 'PATCH /v1/sdk/requests/:requestId/comments/:commentId': {} as Endpoint<\n EditCommentPayload,\n RequestComment\n >,\n 'DELETE /v1/sdk/requests/:requestId/comments/:commentId': {} as Endpoint<\n { anonymousId: string },\n { ok: true }\n >,\n\n // ---------- billing (Paddle) ----------\n 'GET /v1/workspaces/:wid/billing/plans': {} as Endpoint<\n void,\n { plans: ReadonlyArray<BillingPlan>; foundingOffer: BillingOfferAvailability }\n >,\n 'GET /v1/workspaces/:wid/billing/subscription': {} as Endpoint<\n void,\n {\n subscription: Subscription | null\n plan: BillingPlan | null\n usage: BillingUsage\n access: EffectivePlanAccess\n trial: BillingTrial | null\n }\n >,\n 'POST /v1/workspaces/:wid/billing/checkout': {} as Endpoint<\n BillingCheckoutRequest,\n BillingCheckoutResponse\n >,\n 'POST /v1/workspaces/:wid/billing/portal': {} as Endpoint<\n void,\n { url: string }\n >,\n 'POST /v1/workspaces/:wid/billing/change-plan': {} as Endpoint<\n BillingChangePlanRequest,\n BillingChangePlanResponse\n >,\n 'GET /v1/workspaces/:wid/billing/periods': {} as Endpoint<\n void,\n { periods: ReadonlyArray<BillingPeriod> }\n >,\n\n // ---------- super admin ----------\n 'GET /v1/admin/session': {} as Endpoint<void, AdminSession>,\n 'GET /v1/admin/customers': {} as Endpoint<\n AdminCustomerListRequest,\n AdminCustomerListResponse\n >,\n 'GET /v1/admin/customers/:workspaceId': {} as Endpoint<void, AdminCustomerDetail>,\n 'POST /v1/admin/customers/:workspaceId/billing-events/:eventId/replay': {} as Endpoint<\n Record<string, never>,\n { replayed: true }\n >,\n 'POST /v1/admin/customers/:workspaceId/grants': {} as Endpoint<\n CreateWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'POST /v1/admin/customers/:workspaceId/grants/:grantId/extend': {} as Endpoint<\n ExtendWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'POST /v1/admin/customers/:workspaceId/grants/:grantId/revoke': {} as Endpoint<\n RevokeWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'GET /v1/admin/activity': {} as Endpoint<\n { workspaceId?: string; action?: string; cursor?: string; limit?: number },\n { entries: ReadonlyArray<AdminActivityEntry>; nextCursor: string | null }\n >,\n 'GET /v1/admin/workspaces': {} as Endpoint<\n void,\n { workspaces: ReadonlyArray<AdminWorkspaceSummary> }\n >,\n 'GET /v1/admin/plans': {} as Endpoint<\n { grantable?: boolean },\n {\n plans: ReadonlyArray<BillingPlan>\n foundingOffer: BillingOfferAvailability\n paddleEnvironment: 'sandbox' | 'production'\n configuration: {\n apiKeyConfigured: boolean\n clientTokenConfigured: boolean\n webhookSecretConfigured: boolean\n enforcementMode: 'observe' | 'warn' | 'enforce'\n overageMode: 'observe' | 'charge'\n }\n bindings: ReadonlyArray<{\n planId: string\n baseReady: boolean\n overageReady: boolean\n }>\n }\n >,\n 'GET /v1/admin/workspaces/:wid': {} as Endpoint<\n void,\n {\n workspace: { id: string; name: string; slug: string }\n subscription: Subscription | null\n plan: BillingPlan | null\n mau: number\n events: ReadonlyArray<{\n id: string\n event_type: string\n received_at: string\n processed_at: string | null\n processing_error: string | null\n }>\n }\n >,\n 'POST /v1/admin/workspaces/:wid/plan': {} as Endpoint<\n { planId: string },\n { subscription: Subscription }\n >,\n\n // ---------- feature requests — public web roadmap (no auth) ----------\n 'GET /v1/public/roadmap/:slug': {} as Endpoint<\n { status?: RequestStatus | ReadonlyArray<RequestStatus>; sort?: 'top' | 'newest' | 'recently_updated'; page?: number; limit?: number },\n { items: ReadonlyArray<RequestPublicSummary>; total: number }\n >,\n 'GET /v1/public/roadmap/:slug/r/:requestId': {} as Endpoint<void, RequestPublicDetail>,\n 'GET /v1/public/roadmap/:slug/branding': {} as Endpoint<void, RequestPublicBranding>,\n} as const\n\nexport type EndpointKey = keyof typeof endpoints\n","/**\n * Shared Zod schemas — single source of truth for request/response validation.\n *\n * Both the API (Fastify route handlers) and the dashboard (react-hook-form +\n * runtime response validation) import from here. If you change a schema,\n * every consumer sees the new constraint at compile time.\n *\n * Migration is incremental — pillars are landing here pillar-by-pillar. The\n * API still has duplicate schemas under `apps/api/src/schemas/` for the ones\n * not yet moved; those re-export from here to keep import paths stable.\n */\nexport * from './auth.js'\nexport * from './apps.js'\nexport * from './primitives.js'\n","import { z } from 'zod'\n\n/** Lowercase + digits + dashes; URL-safe slug. */\nexport const slugSchema = z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9-]+$/, 'Must be lowercase, digits, and dashes only')\n\n/** RFC 5321 max email length. */\nexport const emailSchema = z.string().email().max(320)\n\nexport const uuidSchema = z.string().uuid()\n\nexport const isoDateTimeSchema = z.string().datetime({ offset: true })\n\n/** Workspace role hierarchy used by tenant middleware. */\nexport const workspaceRoleSchema = z.enum(['owner', 'admin', 'editor', 'viewer'])\n\nexport type WorkspaceRoleInput = z.infer<typeof workspaceRoleSchema>\n","import { z } from 'zod'\nimport { emailSchema } from './primitives.js'\n\n/**\n * Password policy. Tightening this here flows to: API signup route, dashboard\n * SignupForm, password-reset flow, future SSO bridge. Don't fork it in a form.\n */\nexport const passwordSchema = z.string().min(8).max(256)\n\nexport const signupRequestSchema = z.object({\n email: emailSchema,\n password: passwordSchema,\n name: z.string().min(1).max(120).optional(),\n workspaceName: z.string().min(1).max(120),\n})\n\nexport const loginPasswordRequestSchema = z.object({\n email: emailSchema,\n password: z.string().min(1).max(256),\n})\n\nexport const loginMagicLinkRequestSchema = z.object({\n email: emailSchema,\n})\n\nexport const loginMagicLinkConsumeRequestSchema = z.object({\n token: z.string().min(16).max(512),\n})\n\nexport type SignupBody = z.infer<typeof signupRequestSchema>\nexport type LoginPasswordBody = z.infer<typeof loginPasswordRequestSchema>\nexport type LoginMagicLinkBody = z.infer<typeof loginMagicLinkRequestSchema>\nexport type LoginMagicLinkConsumeBody = z.infer<typeof loginMagicLinkConsumeRequestSchema>\n","import { z } from 'zod'\nimport { emailSchema, slugSchema } from './primitives.js'\n\nexport const platformSchema = z.enum(['ios', 'android', 'react-native', 'flutter'])\n\nexport const writeKeyEnvironmentSchema = z.enum(['production', 'staging', 'development'])\n\nexport const apiTokenScopeSchema = z.enum(['sdk:subjects', 'push.transactional'])\n\nexport const createAppSchema = z.object({\n name: z.string().min(1).max(120),\n slug: slugSchema.optional(),\n platforms: z.array(platformSchema).min(1).max(8),\n environment: writeKeyEnvironmentSchema.default('production'),\n})\n\nexport const updateAppSchema = z\n .object({\n name: z.string().min(1).max(120).optional(),\n platforms: z.array(platformSchema).min(1).max(8).optional(),\n piiAllowList: z.array(z.string().min(1).max(120)).max(128).optional(),\n lifecycleEventsEnabled: z.boolean().optional(),\n })\n .refine((v) => Object.keys(v).length > 0, { message: 'At least one field is required' })\n\nexport const createWriteKeySchema = z.object({\n label: z.string().min(1).max(120).optional(),\n environment: writeKeyEnvironmentSchema.default('production'),\n})\n\nexport const rotateWriteKeySchema = z.object({\n // Default 5 minutes; ceiling 24h to bound risk of forgotten old keys.\n graceSeconds: z.number().int().min(0).max(86_400).default(300),\n})\n\nexport const createApiTokenSchema = z.object({\n name: z.string().trim().min(1).max(120),\n scopes: z.array(apiTokenScopeSchema).min(1).max(8).transform((scopes) => [...new Set(scopes)]),\n expiresInDays: z.number().int().min(1).max(365).default(90),\n})\n\nexport const createWorkspaceSchema = z.object({\n name: z.string().min(1).max(120),\n slug: slugSchema.optional(),\n})\n\nexport const inviteMemberSchema = z.object({\n email: emailSchema,\n role: z.enum(['admin', 'editor', 'viewer']),\n})\n\nexport const acceptWorkspaceInviteSchema = z.object({\n token: z.string().regex(/^[a-f0-9]{64}$/i, 'Invalid invitation token'),\n})\n\nexport type CreateAppBody = z.infer<typeof createAppSchema>\nexport type UpdateAppBody = z.infer<typeof updateAppSchema>\nexport type CreateWriteKeyBody = z.infer<typeof createWriteKeySchema>\nexport type RotateWriteKeyBody = z.infer<typeof rotateWriteKeySchema>\nexport type CreateApiTokenBody = z.infer<typeof createApiTokenSchema>\nexport type CreateWorkspaceBody = z.infer<typeof createWorkspaceSchema>\nexport type InviteMemberBody = z.infer<typeof inviteMemberSchema>\nexport type AcceptWorkspaceInviteBody = z.infer<typeof acceptWorkspaceInviteSchema>\n"]}
1
+ {"version":3,"sources":["../src/types/segment-dsl.ts","../src/types/recipient.ts","../src/types/api.ts","../src/types/workspace.ts","../src/types/survey.ts","../src/types/inapp-message.ts","../src/types/request.ts","../src/types/targeting.ts","../src/types/themes.ts","../src/types/brand.ts","../src/types/integration.ts","../src/constants/push-events.ts","../src/constants/billing-plans.ts","../src/types/push-runtime.ts","../src/evaluate/segment.ts","../src/evaluate/branch.ts","../src/evaluate/periodic.ts","../src/timezone.ts","../src/contract/endpoints.ts","../src/schemas/index.ts","../src/schemas/primitives.ts","../src/schemas/auth.ts","../src/schemas/web.ts","../src/types/portal.ts","../src/schemas/portal.ts","../src/schemas/apps.ts","../src/types/portal-content.ts","../src/schemas/portal-content.ts","../src/types/mcp.ts","../src/schemas/mcp.ts","../src/types/web.ts","../src/personalization.ts","../src/presentation.ts"],"names":["id","key","node","cutoff","candidate","z","rendered"],"mappings":"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","file":"index.cjs","sourcesContent":["// ==========================================================\n// Segment DSL (shared between server and SDK). The DSL is a\n// JSON structure — not raw SQL — so that:\n// 1. The dashboard UI can safely build/edit rules.\n// 2. The SDK can evaluate a lightweight subset client-side\n// for instant trigger firing (the server re-verifies).\n// 3. The server can compile the full DSL to ClickHouse SQL.\n// ==========================================================\n\nexport type ScalarValue = string | number | boolean\nexport type ScalarList = ReadonlyArray<string | number>\n\nexport type ComparisonOp =\n | 'eq'\n | 'neq'\n | 'in'\n | 'nin'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'contains'\n | 'starts_with'\n | 'exists'\n | 'not_exists'\n\nexport interface UserPropertyPredicate {\n readonly kind: 'user_property'\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: ScalarValue | ScalarList\n}\n\nexport type CountOp = 'gte' | 'lte' | 'eq' | 'gt' | 'lt'\n\nexport interface EventCountPredicate {\n readonly kind: 'event_count'\n readonly eventName: string\n readonly op: CountOp\n readonly count: number\n readonly windowDays: number\n readonly propertyFilters?: ReadonlyArray<UserPropertyPredicate>\n}\n\nexport interface EventOccurredPredicate {\n readonly kind: 'event_occurred'\n readonly eventName: string\n readonly ever: boolean // true => \"has ever done X\", false => \"has never done X\"\n readonly windowDays?: number\n}\n\nexport type Predicate =\n | UserPropertyPredicate\n | EventCountPredicate\n | EventOccurredPredicate\n\nexport type Combinator = 'AND' | 'OR'\n\nexport interface PredicateGroup {\n readonly combinator: Combinator\n readonly predicates: ReadonlyArray<Predicate | PredicateGroup>\n}\n\nexport interface SegmentDsl {\n readonly version: 1\n readonly root: PredicateGroup\n}\n\nexport function emptySegmentDsl(): SegmentDsl {\n return { version: 1, root: { combinator: 'AND', predicates: [] } }\n}\n","import type { PromptResponse } from './response.js'\nimport type { SurveyAttemptSource, SurveyResponseRecord } from './survey.js'\n\nexport const RECIPIENTS_LIMIT = 100\n\nexport interface RecipientIdentity {\n readonly subjectId?: string | null\n readonly identityKind?: 'anonymous' | 'identified'\n readonly identityOrigin?: 'sdk' | 'portal' | 'unknown'\n readonly anonymousId: string\n readonly externalId: string | null\n readonly country: string | null\n readonly platform: string | null\n}\n\nexport interface RecipientList<T> {\n readonly nextCursor?: string | null\n readonly asOf?: string\n readonly totalKind?: 'exact' | 'estimate'\n readonly warnings?: readonly string[]\n readonly items: ReadonlyArray<T>\n readonly total: number\n readonly limit: number\n}\nexport interface RecipientPageQuery { from?: string; to?: string; cursor?: string; limit?: number; pagination?: 'cursor'; platform?: 'ios' | 'android' | 'web'; identity?: 'anonymous' | 'identified' }\n\nexport interface FeedbackRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly response: PromptResponse | null\n}\n\nexport type InAppRecipientStatus =\n | 'viewed'\n | 'dismissed'\n | 'auto_dismissed'\n | 'cta_clicked'\n\nexport interface InAppRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly status: InAppRecipientStatus\n readonly actionAt: string | null\n readonly ctaLabel: string | null\n}\n\nexport type SurveyRecipientStatus =\n | 'received'\n | 'declined'\n | 'in_progress'\n | 'completed'\n | 'abandoned'\n\nexport interface SurveyRecipient extends RecipientIdentity {\n readonly receivedAt: string\n readonly source: SurveyAttemptSource\n readonly status: SurveyRecipientStatus\n readonly attemptId: string | null\n readonly startedAt: string | null\n readonly completedAt: string | null\n readonly abandonedAt: string | null\n readonly responses: ReadonlyArray<SurveyResponseRecord>\n}\n","export interface ApiError {\n readonly code: string\n readonly message: string\n readonly details?: unknown\n}\n\nexport interface ApiMeta {\n readonly total?: number\n readonly page?: number\n readonly limit?: number\n}\n\nexport interface ApiResponse<T> {\n readonly success: boolean\n readonly data?: T\n readonly error?: ApiError\n readonly meta?: ApiMeta\n}\n\nexport function ok<T>(data: T, meta?: ApiMeta): ApiResponse<T> {\n return meta ? { success: true, data, meta } : { success: true, data }\n}\n\nexport function err(\n code: string,\n message: string,\n details?: unknown,\n): ApiResponse<never> {\n return {\n success: false,\n error: details === undefined ? { code, message } : { code, message, details },\n }\n}\n","export type WorkspaceRole = 'owner' | 'admin' | 'editor' | 'viewer'\n\nexport interface Workspace {\n readonly id: string\n readonly name: string\n readonly slug: string\n readonly region: string\n readonly timezone: string\n readonly createdAt: string\n readonly updatedAt: string\n}\n\n/** Workspace as returned from the authenticated `/v1/me` projection. */\nexport interface WorkspaceWithRole extends Workspace {\n readonly role: WorkspaceRole\n}\n\nexport interface WorkspaceMember {\n readonly workspaceId: string\n readonly userId: string\n readonly email: string\n readonly name?: string | null\n readonly role: WorkspaceRole\n readonly createdAt: string\n}\n\nexport interface WorkspaceInvite {\n readonly id: string\n readonly workspaceId: string\n readonly email: string\n readonly role: Exclude<WorkspaceRole, 'owner'>\n readonly deliveryStatus: 'pending' | 'sent' | 'failed'\n readonly expiresAt: string\n readonly createdAt: string\n}\n\nexport interface AcceptWorkspaceInviteRequest {\n readonly token: string\n}\n\nexport interface AcceptWorkspaceInviteResponse {\n readonly workspace: Workspace\n readonly role: WorkspaceRole\n readonly alreadyMember: boolean\n}\n\nexport interface User {\n readonly id: string\n readonly email: string\n readonly name?: string | null\n readonly emailVerifiedAt?: string | null\n readonly createdAt: string\n readonly onboardingCompletedAt: string | null\n // Cross-workspace operator flag. Set on a tiny number of internal\n // accounts; surfaced so the dashboard can render the /admin\n // surface. SDK consumers never see this — it's only populated by\n // /v1/me which write-keys can't call.\n readonly isSuperAdmin?: boolean\n}\n\nexport interface App {\n readonly setupMode?: 'sdk' | 'portal'\n readonly id: string\n readonly workspaceId: string\n readonly name: string\n readonly slug: string\n readonly platforms: ReadonlyArray<\n 'ios' | 'android' | 'react-native' | 'expo' | 'flutter' | 'web'\n >\n readonly webConfig?: import('./web.js').WebAppConfig\n readonly piiAllowList: ReadonlyArray<string>\n readonly lifecycleEventsEnabled: boolean\n readonly billingSuspendedAt: string | null\n readonly onboarding: AppOnboarding\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport type OnboardingGoal =\n | 'feedback'\n | 'survey'\n | 'inapp'\n | 'push'\n | 'requests'\nexport type OnboardingStatus = 'in_progress' | 'deferred' | 'completed'\nexport type OnboardingStep =\n | 'connect'\n | 'verify'\n | 'experience'\n | 'push'\n | 'launch'\nexport type OnboardingPushChoice = 'pending' | 'configured' | 'skipped'\n\nexport interface AppOnboarding {\n readonly goal: OnboardingGoal | null\n readonly status: OnboardingStatus\n readonly step: OnboardingStep\n readonly pushChoice: OnboardingPushChoice\n readonly startedAt: string\n readonly deferredAt: string | null\n readonly completedAt: string | null\n}\n\nexport interface OnboardingEvent {\n readonly name: '$app_open'\n readonly occurredAt: string\n readonly receivedAt: string\n readonly anonymousId: string\n readonly externalId: string | null\n readonly identityType: 'anonymous' | 'identified'\n readonly platform: string | null\n readonly sdkVersion: string | null\n readonly appVersion: string | null\n}\n\nexport interface OnboardingFirstFeedback {\n readonly promptId: string\n readonly question: string\n readonly status: 'draft' | 'active' | 'paused' | 'archived'\n readonly createdAt: string\n readonly shownAt: string | null\n readonly responseAt: string | null\n readonly responseValue: number | string | ReadonlyArray<string> | null\n readonly responseAnonymousId: string | null\n readonly responseExternalId: string | null\n readonly lastDismissedAt: string | null\n}\n\n/** Small, ready-to-use first message; the full composer stays in the dashboard. */\nexport interface OnboardingInAppContent {\n readonly title: string\n readonly body: string\n readonly buttonLabel: string\n readonly format: 'modal' | 'slideup'\n}\n\nexport function defaultOnboardingMessage(appName: string): OnboardingInAppContent {\n return {\n title: `Welcome to ${appName.trim() || 'our app'}`,\n body: 'Glad you’re here. Take a look around and make yourself at home.',\n buttonLabel: 'Got it',\n format: 'modal',\n }\n}\n\nexport interface OnboardingFirstInApp extends Omit<OnboardingInAppContent, 'format'> {\n readonly format: 'modal' | 'modal_full' | 'slideup'\n readonly messageId: string\n readonly status: 'draft' | 'scheduled' | 'active' | 'paused' | 'completed' | 'archived'\n readonly shownAt: string | null\n readonly interactedAt: string | null\n readonly interaction: 'cta_clicked' | 'dismissed' | null\n readonly identityType: 'anonymous' | 'identified' | null\n}\n\nexport interface AppOnboardingStatus extends AppOnboarding {\n readonly clientKeyAuthenticatedAt: string | null\n readonly environment: WriteKey['environment']\n readonly firstEvent: OnboardingEvent | null\n readonly firstAudienceUserCreated: boolean\n readonly firstFeedback: OnboardingFirstFeedback | null\n readonly firstInApp?: OnboardingFirstInApp | null\n readonly pushCredentials: {\n readonly ios: boolean\n readonly android: boolean\n }\n}\n\nexport interface UpdateAppOnboardingRequest {\n readonly action?:\n | 'resume'\n | 'defer'\n | 'create_first_inapp'\n | 'first_inapp_completed'\n | 'create_first_feedback'\n | 'first_feedback_completed'\n | 'push_configured'\n | 'push_skipped'\n | 'complete'\n readonly step?: OnboardingStep\n readonly question?: string\n readonly message?: OnboardingInAppContent\n}\n\nexport interface DeferCurrentUserOnboardingRequest {\n readonly action: 'defer'\n}\n\nexport interface WriteKey {\n readonly id: string\n readonly appId: string\n readonly keyPrefix: string\n readonly environment: 'production' | 'staging' | 'development'\n readonly label?: string | null\n readonly revokedAt?: string | null\n readonly lastUsedAt?: string | null\n readonly createdAt: string\n}\n\nexport interface CreatedWriteKey extends WriteKey {\n readonly plaintext: string // only returned on creation\n}\n\nexport type ApiTokenScope =\n | 'sdk:subjects'\n | 'push.transactional'\n | 'users.properties.write'\n\n/**\n * Metadata for a workspace-scoped server credential. The plaintext secret is\n * deliberately absent and is only returned by the create endpoint.\n */\nexport interface ApiToken {\n readonly id: string\n readonly workspaceId: string\n readonly name: string\n readonly tokenPrefix: string\n readonly scopes: ReadonlyArray<ApiTokenScope>\n readonly expiresAt: string\n readonly revokedAt: string | null\n readonly lastUsedAt: string | null\n readonly createdAt: string\n}\n\nexport interface CreatedApiToken extends ApiToken {\n /** One-time server secret. Never ship this value inside a client app. */\n readonly plaintext: string\n}\n\nexport interface CreateApiTokenRequest {\n readonly name: string\n readonly scopes: ReadonlyArray<ApiTokenScope>\n readonly expiresInDays?: number\n}\n\n/** App plus its first environment-specific write key, returned atomically. */\nexport interface CreatedApp extends App {\n readonly writeKey: CreatedWriteKey\n}\n\n/**\n * Request body for `POST /v1/apps/:appId/write-keys/:keyId/rotate`. The grace\n * window is how long the old key keeps authenticating before the API starts\n * returning 401 — gives SDK consumers a deploy window before the cutover.\n */\nexport interface RotateWriteKeyRequest {\n readonly graceSeconds?: number\n}\n\n/**\n * Response from a successful key rotation. The new key's plaintext is\n * returned ONCE and never again — operators must capture it on rotation.\n */\nexport interface RotateWriteKeyResponse {\n readonly newKey: CreatedWriteKey\n readonly oldKey: WriteKey\n readonly oldKeyExpiresAt: string\n}\n","import type { PersonalizationSpec } from './personalization.js'\n// ============================================================\n// Survey types — shared between API, dashboard, and SDKs.\n// A survey is a Campaign with type='survey'. The multi-step\n// question graph + branching lives here.\n// ============================================================\n\nimport type {\n PromptTheme,\n FrequencyCaps,\n SerializedSegmentRules,\n} from './prompt.js'\nimport type { PushFrequencyCap, PushSchedule } from './campaign.js'\nimport type { AudienceSpec, TriggerSpec } from './targeting.js'\nimport type { ThemeMode } from './brand.js'\n\nexport type SurveyQuestionType =\n | 'single_choice'\n | 'multi_choice'\n | 'nps'\n | 'rating'\n | 'likert'\n | 'short_text'\n | 'long_text'\n | 'ranking'\n | 'single_date'\n | 'info_screen'\n\nexport type SurveyProgressStyle = 'bar' | 'dots' | 'none'\n\nexport interface SurveyChoiceOption {\n readonly id: string\n readonly label: string\n}\n\nexport interface SurveyTextValidation {\n readonly kind?: 'email' | 'url' | 'number' | 'regex'\n readonly pattern?: string\n readonly minLength?: number\n readonly maxLength?: number\n}\n\nexport interface BaseSurveyQuestion {\n readonly id: string\n readonly title: string\n readonly subtitle?: string\n readonly required?: boolean\n // Optional image rendered above the question title. Uploaded\n // through the dashboard composer; URL points at the public R2\n // bucket.\n readonly imageUrl?: string\n readonly mergeTagContext?: Readonly<Record<string, unknown>>\n}\n\nexport interface SingleChoiceQuestion extends BaseSurveyQuestion {\n readonly type: 'single_choice'\n readonly options: ReadonlyArray<SurveyChoiceOption>\n readonly allowOther?: boolean\n}\n\nexport interface MultiChoiceQuestion extends BaseSurveyQuestion {\n readonly type: 'multi_choice'\n readonly options: ReadonlyArray<SurveyChoiceOption>\n readonly minSelections?: number\n readonly maxSelections?: number\n readonly allowOther?: boolean\n}\n\nexport interface SurveyNpsQuestion extends BaseSurveyQuestion {\n readonly type: 'nps'\n readonly lowLabel?: string\n readonly highLabel?: string\n}\n\nexport interface SurveyRatingQuestion extends BaseSurveyQuestion {\n readonly type: 'rating'\n readonly scale: 5 | 10\n readonly style?: 'star' | 'numeric'\n readonly lowLabel?: string\n readonly highLabel?: string\n}\n\nexport interface LikertQuestion extends BaseSurveyQuestion {\n readonly type: 'likert'\n // 5-point: strongly disagree → strongly agree. Labels overridable.\n readonly labels?: readonly [string, string, string, string, string]\n}\n\nexport interface SurveyShortTextQuestion extends BaseSurveyQuestion {\n readonly type: 'short_text'\n readonly placeholder?: string\n readonly validation?: SurveyTextValidation\n}\n\nexport interface LongTextQuestion extends BaseSurveyQuestion {\n readonly type: 'long_text'\n readonly placeholder?: string\n readonly maxLength?: number\n}\n\nexport interface RankingQuestion extends BaseSurveyQuestion {\n readonly type: 'ranking'\n readonly items: ReadonlyArray<SurveyChoiceOption>\n}\n\nexport interface SingleDateQuestion extends BaseSurveyQuestion {\n readonly type: 'single_date'\n readonly minDate?: string\n readonly maxDate?: string\n}\n\nexport interface InfoScreenQuestion extends BaseSurveyQuestion {\n readonly type: 'info_screen'\n readonly body?: string\n}\n\nexport type SurveyQuestion =\n | SingleChoiceQuestion\n | MultiChoiceQuestion\n | SurveyNpsQuestion\n | SurveyRatingQuestion\n | LikertQuestion\n | SurveyShortTextQuestion\n | LongTextQuestion\n | RankingQuestion\n | SingleDateQuestion\n | InfoScreenQuestion\n\n// ---------- Branching DSL ----------\n\nexport type SurveyBranchOp =\n | 'eq'\n | 'neq'\n | 'lt'\n | 'lte'\n | 'gt'\n | 'gte'\n | 'includes'\n | 'not_includes'\n | 'answered'\n | 'unanswered'\n\nexport type SurveyBranchValue =\n | string\n | number\n | boolean\n | ReadonlyArray<string | number>\n\nexport interface SurveyBranchCondition {\n readonly op: SurveyBranchOp\n readonly value?: SurveyBranchValue\n}\n\nexport interface SurveyBranch {\n readonly fromQuestionId: string\n readonly condition: SurveyBranchCondition\n readonly toQuestionId: string // or '__end__' to jump straight to end screen\n}\n\nexport const SURVEY_END_SENTINEL = '__end__'\n\n// ---------- End screen ----------\n\nexport type SurveyEndCtaKind = 'url' | 'deep_link' | 'close'\n\nexport interface SurveyEndCta {\n readonly kind: SurveyEndCtaKind\n readonly label: string\n readonly target?: string\n}\n\nexport interface SurveyFollowUp {\n readonly headline: string\n readonly body?: string\n readonly cta?: SurveyEndCta\n}\n\nexport interface SurveyEndScreen {\n readonly headline: string\n readonly body?: string\n readonly cta?: SurveyEndCta\n readonly followUp?: SurveyFollowUp\n}\n\n// ---------- Localization ----------\n\nexport interface SurveyLocalization {\n readonly defaultLanguage?: string\n readonly languages?: Readonly<\n Record<\n string,\n {\n readonly questions?: ReadonlyArray<SurveyQuestion>\n readonly endScreen?: SurveyEndScreen\n }\n >\n >\n}\n\n// ---------- Flow ----------\n\nexport interface SurveyFlow {\n readonly personalization?: PersonalizationSpec | null\n readonly startQuestionId: string\n readonly questions: ReadonlyArray<SurveyQuestion>\n readonly branches: ReadonlyArray<SurveyBranch>\n readonly progressStyle: SurveyProgressStyle\n readonly backNavigation: boolean\n readonly localization?: SurveyLocalization\n readonly endScreen?: SurveyEndScreen\n}\n\n// ---------- Campaign surface ----------\n\nexport type SurveyDeliveryMode =\n | 'triggered'\n | 'scheduled'\n | 'on_demand'\n | 'link_only'\n\nexport type SurveyAttemptSource =\n | 'triggered'\n | 'scheduled'\n | 'link'\n | 'on_demand'\n | 'test'\n\nexport interface SurveyCampaign {\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly id: string\n readonly appId: string\n readonly name: string\n readonly type: 'survey'\n readonly mode: SurveyDeliveryMode\n readonly status:\n | 'draft'\n | 'scheduled'\n | 'active'\n | 'paused'\n | 'completed'\n | 'archived'\n readonly audienceSegmentId: string | null\n readonly triggerEventName: string | null\n // Inline AudienceSpec + TriggerSpec mirroring prompts.audience/trigger.\n // Null until the dashboard / API write them; legacy\n // audienceSegmentId / triggerEventName remain authoritative until\n // both sides have migrated.\n readonly audience: AudienceSpec | null\n readonly trigger: TriggerSpec | null\n readonly schedule: PushSchedule | null\n readonly frequencyCap: PushFrequencyCap\n readonly cooldownSeconds: number | null\n readonly openAccess: boolean\n readonly saveResumeWindowSeconds: number\n readonly endScreen: SurveyEndScreen | null\n readonly themeMode: ThemeMode\n readonly theme: PromptTheme | null\n readonly startAt: string | null\n readonly endAt: string | null\n readonly startedAt: string | null\n readonly endedAt: string | null\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface SurveyCampaignWithFlow extends SurveyCampaign {\n /** Server-authorized content snapshot; present only on an SDK response. */\n readonly presentationId?: string\n readonly flow: SurveyFlow\n}\n\n// ---------- Attempts / responses ----------\n\nexport interface SurveyAnswerRecord {\n readonly [questionId: string]: SurveyAnswerValue\n}\n\nexport type SurveyAnswerValue =\n | string\n | number\n | boolean\n | null\n | ReadonlyArray<string>\n | ReadonlyArray<number>\n\nexport interface SurveyAttempt {\n readonly id: string\n readonly campaignId: string\n readonly anonymousId: string\n readonly externalId: string | null\n readonly startedAt: string\n readonly completedAt: string | null\n readonly abandonedAt: string | null\n readonly currentQuestionId: string | null\n readonly progressSnapshot: SurveyAnswerRecord\n readonly source: SurveyAttemptSource\n readonly language: string | null\n}\n\nexport interface SurveyResponseRecord {\n readonly id: string\n readonly attemptId: string\n readonly campaignId: string\n readonly questionId: string\n readonly answerValue: SurveyAnswerValue\n readonly answeredAt: string\n}\n\n// ---------- SDK-facing payloads ----------\n\nexport interface SurveySummary {\n readonly id: string\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly source: SurveyAttemptSource\n readonly offeredAt?: string\n readonly resumableAttemptId?: string | null\n}\n\nexport interface SurveyOfferInstruction {\n readonly type: 'survey.offer'\n readonly surveyId: string\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly source: SurveyAttemptSource\n readonly emittedAt: string\n}\n\nexport interface CreateSurveyAttemptRequest {\n /** Stable ID for an explicitly new attempt; retained across offline retries. */\n readonly clientAttemptId?: string\n readonly localStart?: {\n readonly token: string\n readonly startedAt: string\n }\n readonly presentationId?: string\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly source: SurveyAttemptSource\n readonly language?: string\n readonly resume?: boolean\n readonly sdkVersion?: string\n readonly appVersion?: string\n readonly platform?: string\n}\n\nexport interface CreateSurveyAttemptResponse {\n readonly resolvedContent?: SurveyCampaignWithFlow\n readonly attemptId: string\n readonly startQuestionId: string\n readonly progressSnapshot: SurveyAnswerRecord\n readonly currentQuestionId: string | null\n readonly resumed: boolean\n}\n\nexport interface SubmitSurveyAnswersRequest {\n readonly answers: ReadonlyArray<{\n readonly questionId: string\n readonly value: SurveyAnswerValue\n }>\n readonly currentQuestionId?: string | null\n}\n\nexport interface UpdateSurveyAttemptProgressRequest {\n readonly currentQuestionId: string | null\n readonly progressSnapshot: SurveyAnswerRecord\n}\n\nexport interface CompleteSurveyAttemptRequest {\n readonly finalAnswers?: ReadonlyArray<{\n readonly questionId: string\n readonly value: SurveyAnswerValue\n }>\n readonly latencyMs?: number\n}\n\nexport interface ResolveSurveyLinkRequest {\n readonly token: string\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\nexport interface ResolveSurveyLinkResponse {\n readonly surveyId: string\n readonly name: string\n readonly consentRequired: boolean\n readonly openAccess: boolean\n}\n\nexport interface SurveyShareLinkResponse {\n readonly url: string\n readonly token: string\n readonly expiresAt: string | null\n}\n\n// ---------- Templates ----------\n\nexport interface SurveyTemplate {\n readonly id: string\n readonly slug: string\n readonly name: string\n readonly description: string | null\n readonly flow: SurveyFlow\n readonly recommendedTriggerEvent: string | null\n readonly recommendedMode: SurveyDeliveryMode | null\n readonly createdAt: string\n}\n\n// ---------- Create / update requests ----------\n\nexport interface CreateSurveyRequest {\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly name: string\n readonly mode: SurveyDeliveryMode\n readonly flow: SurveyFlow\n readonly audienceSegmentId?: string | null\n readonly triggerEventName?: string | null\n readonly schedule?: PushSchedule | null\n readonly frequencyCap?: PushFrequencyCap\n readonly frequency?: FrequencyCaps\n readonly cooldownSeconds?: number | null\n readonly openAccess?: boolean\n readonly saveResumeWindowSeconds?: number\n readonly endScreen?: SurveyEndScreen\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: SurveyCampaign['status']\n}\n\nexport interface UpdateSurveyRequest extends Partial<CreateSurveyRequest> {\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly status?: SurveyCampaign['status']\n}\n\nexport interface CloneSurveyFromTemplateRequest {\n readonly name?: string\n readonly audienceSegmentId?: string | null\n readonly triggerEventName?: string | null\n}\n\n// ---------- Analytics ----------\n\nexport interface SurveyFunnelStep {\n readonly questionId: string\n readonly shown: number\n readonly answered: number\n readonly skipped: number\n}\n\nexport interface SurveyQuestionDistribution {\n readonly questionId: string\n readonly type: SurveyQuestionType\n readonly distribution: Readonly<Record<string, number>>\n readonly average?: number\n readonly npsScore?: number\n readonly sampleSize: number\n}\n\nexport interface SurveyAnalytics {\n readonly surveyId: string\n readonly totals: {\n readonly started: number\n readonly completed: number\n readonly abandoned: number\n readonly completionRate: number\n }\n readonly funnel: ReadonlyArray<SurveyFunnelStep>\n readonly perQuestion: ReadonlyArray<SurveyQuestionDistribution>\n readonly npsOverTime?: ReadonlyArray<{\n day: string\n score: number\n samples: number\n }>\n readonly perLanguage?: Readonly<Record<string, number>>\n}\n\n// ---------- SDK-side armed surveys ----------\n//\n// Mirrors `ArmedTrigger` (feedback). Returned by\n// `GET /v1/sdk/armed-surveys` for every triggered + active survey\n// the SDK should evaluate locally on each `track()`. The full\n// `survey` payload is included so the SDK can render immediately\n// on a match without a follow-up content fetch.\n\nexport interface ArmedSurvey {\n /** Server-signed, non-personalized content for a safe local start. */\n readonly localStart?: {\n readonly token: string\n readonly expiresAt: string\n }\n readonly campaignId: string\n readonly eventName: string\n readonly segmentRules?: SerializedSegmentRules | null\n /** True only when the SDK can make the same targeting decision locally. */\n readonly clientSideEligible?: boolean\n readonly cooldownSeconds: number | null\n readonly frequencyCap: PushFrequencyCap\n readonly survey: SurveyCampaignWithFlow\n}\n","import type { PersonalizationSpec } from './personalization.js'\nimport type { AudienceSpec, TriggerSpec } from './targeting.js'\nimport type { ThemeMode } from './brand.js'\n\nexport const INAPP_SHOWN_EVENT_NAME = '$inapp_shown'\nexport const INAPP_DISMISSED_EVENT_NAME = '$inapp_dismissed'\nexport const INAPP_AUTO_DISMISSED_EVENT_NAME = '$inapp_auto_dismissed'\nexport const INAPP_CTA_CLICKED_EVENT_NAME = '$inapp_cta_clicked'\n\nexport type InAppMessageFormat = 'modal' | 'modal_full' | 'slideup'\n\nexport type InAppMessageStatus =\n | 'draft'\n | 'scheduled'\n | 'active'\n | 'paused'\n | 'completed'\n | 'archived'\n\nexport type InAppMessageMode = 'triggered' | 'scheduled'\n\nexport type JsonAction = Readonly<Record<string, unknown>>\n\nexport type InAppCtaAction =\n | 'open_url'\n | 'deep_link'\n | 'dismiss'\n | 'custom_event'\n | 'json'\n\nexport interface InAppCta {\n readonly label: string\n readonly action: InAppCtaAction\n readonly target?: string\n /** Host-defined action data dispatched to the app when this CTA is tapped. */\n readonly actionJson?: JsonAction\n}\n\n// Three-state cooldowns + cross-pillar caps. Each key is optional —\n// omitting means \"no cap on this dimension\".\nexport interface InAppFrequency {\n readonly cooldownAfterShownDays?: number\n readonly cooldownAfterDismissedDays?: number\n readonly cooldownAfterCtaClickedDays?: number\n readonly maxImpressionsPerUser?: number\n readonly perPillarDays?: number\n readonly perGlobalDays?: number\n}\n\nexport interface InAppMessage {\n readonly personalization?: PersonalizationSpec | null\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly id: string\n readonly appId: string\n readonly name: string\n readonly status: InAppMessageStatus\n readonly mode: InAppMessageMode\n\n readonly audienceSegmentId: string | null\n readonly audience: AudienceSpec | null\n readonly trigger: TriggerSpec | null\n readonly triggerEventName: string | null\n readonly schedule: unknown | null\n\n readonly screenAllowlist: ReadonlyArray<string>\n readonly screenDenylist: ReadonlyArray<string>\n\n readonly frequency: InAppFrequency\n\n readonly conversionGoalEvent: string | null\n readonly conversionWindowHours: number\n\n readonly priority: number\n readonly forceShow: boolean\n readonly autoDismissSeconds: number | null\n\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body: string | null\n readonly imageUrl: string | null\n readonly themeMode: ThemeMode\n readonly backgroundColor: string | null\n readonly accentColor: string | null\n readonly backdropEnabled: boolean\n readonly ctas: ReadonlyArray<InAppCta>\n\n readonly startAt: string | null\n readonly endAt: string | null\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface CreateInAppMessageRequest {\n readonly personalization?: PersonalizationSpec | null\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly name: string\n readonly audienceSegmentId?: string | null\n readonly audience?: AudienceSpec\n readonly trigger?: TriggerSpec\n readonly triggerEventName?: string | null\n readonly screenAllowlist?: ReadonlyArray<string>\n readonly screenDenylist?: ReadonlyArray<string>\n readonly frequency?: InAppFrequency\n readonly conversionGoalEvent?: string | null\n readonly conversionWindowHours?: number\n readonly priority?: number\n readonly forceShow?: boolean\n readonly autoDismissSeconds?: number | null\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body?: string | null\n readonly imageUrl?: string | null\n readonly themeMode?: ThemeMode\n readonly backgroundColor?: string | null\n readonly accentColor?: string | null\n readonly backdropEnabled?: boolean\n readonly ctas?: ReadonlyArray<InAppCta>\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: InAppMessageStatus\n}\n\nexport interface UpdateInAppMessageRequest\n extends Partial<CreateInAppMessageRequest> {\n readonly status?: InAppMessageStatus\n}\n\nexport interface InAppMessageAnalytics {\n readonly totals: {\n readonly impressions: number\n readonly dismissed: number\n readonly autoDismissed: number\n readonly ctaClicked: number\n }\n readonly timeline: ReadonlyArray<{\n readonly day: string\n readonly impressions: number\n readonly dismissed: number\n readonly ctaClicked: number\n }>\n}\n\n// Subset of the message the SDK needs at render time. Mirrors\n// `ArmedTrigger.prompt` for feedback prompts — strips fields the device\n// doesn't need (audit columns, segment id) and leaves what the renderer\n// uses.\nexport interface ArmedInAppMessage {\n readonly personalization?:\n | import('./personalization.js').PersonalizationSpec\n | null\n readonly deliveryPlatforms?: ReadonlyArray<\n import('./web.js').DeliveryPlatform\n >\n readonly webPresentation?: import('./web.js').WebPresentation | null\n readonly messageId: string\n readonly eventName: string\n /** True only when the SDK can make the same targeting decision locally. */\n readonly clientSideEligible?: boolean\n readonly format: InAppMessageFormat\n readonly title: string\n readonly body: string | null\n readonly imageUrl: string | null\n readonly themeMode?: ThemeMode\n readonly backgroundColor: string | null\n readonly accentColor: string | null\n /** Defaults to true when omitted by an older API/cache payload. */\n readonly backdropEnabled?: boolean\n readonly ctas: ReadonlyArray<InAppCta>\n readonly autoDismissSeconds: number | null\n readonly screenAllowlist: ReadonlyArray<string>\n readonly screenDenylist: ReadonlyArray<string>\n readonly forceShow: boolean\n}\n","// ============================================================\n// Feature requests (5th pillar) — public types\n// ============================================================\n// Shared between API, dashboard, web-roadmap, and SDKs.\n// All shapes are `readonly`. Identity uses anonymousId + externalId\n// as on every other SDK payload — no new identity types here.\n\nimport type { ThemeMode } from './brand.js'\n\nexport type RequestStatus =\n | 'under_review'\n | 'planned'\n | 'in_progress'\n | 'shipped'\n | 'declined'\n\nexport type RequestFollowSource = 'upvote_auto' | 'manual'\n\nexport type RequestSort = 'top' | 'newest' | 'recently_updated'\n\nexport type RequestPersonalFilter = 'submitted' | 'upvoted' | 'following'\n\n// Event-name constants for the 7 events emitted by the request engine.\n// All flow through services/ingest.ts and become segmentable like every\n// other event (no segment-engine code changes needed).\nexport const REQUEST_SUBMITTED_EVENT_NAME = '$request_submitted' as const\nexport const REQUEST_UPVOTED_EVENT_NAME = '$request_upvoted' as const\nexport const REQUEST_UNUPVOTED_EVENT_NAME = '$request_unupvoted' as const\nexport const REQUEST_FOLLOWED_EVENT_NAME = '$request_followed' as const\nexport const REQUEST_UNFOLLOWED_EVENT_NAME = '$request_unfollowed' as const\nexport const REQUEST_STATUS_CHANGED_EVENT_NAME = '$request_status_changed' as const\nexport const REQUEST_RESPONDED_EVENT_NAME = '$request_responded' as const\nexport const REQUEST_COMMENTED_EVENT_NAME = '$request_commented' as const\nexport const REQUEST_COMMENT_EDITED_EVENT_NAME = '$request_comment_edited' as const\nexport const REQUEST_COMMENT_DELETED_EVENT_NAME = '$request_comment_deleted' as const\n\n// ---------- core domain shapes ----------\n\n/**\n * A feature request with viewer-relative state attached. Returned from\n * detail and list endpoints; `viewer*` fields are computed server-side\n * from the caller's identity.\n */\nexport interface Request {\n readonly id: string\n readonly appId: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly devResponse: string | null\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly updatedAt: string\n readonly statusChangedAt: string\n readonly lastRespondedAt: string | null\n readonly viewerHasUpvoted: boolean\n readonly viewerIsFollowing: boolean\n readonly viewerIsSubmitter: boolean\n}\n\n/** Compact summary used in list views and search typeahead. */\nexport interface RequestSummary {\n readonly id: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly statusChangedAt: string\n readonly viewerHasUpvoted: boolean\n readonly viewerIsFollowing: boolean\n /** Dashboard-only publication metadata. Omitted from SDK responses. */\n readonly portalVisible?: boolean\n readonly source?: 'sdk' | 'portal'\n readonly hidden?: boolean\n readonly devResponse?: string | null\n}\n\n/** Search-as-you-type result; the SDK shows up to 5. */\nexport interface RequestSearchResult {\n readonly id: string\n readonly title: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n}\n\n// ---------- toggle return shapes ----------\n\n/** Returned from POST/DELETE /v1/sdk/requests/:id/votes. */\nexport interface RequestVote {\n readonly requestId: string\n readonly upvoted: boolean\n readonly followed: boolean\n readonly upvoteCount: number\n readonly followerCount: number\n}\n\n/** Returned from POST/DELETE /v1/sdk/requests/:id/follows. */\nexport interface RequestFollow {\n readonly requestId: string\n readonly following: boolean\n readonly followerCount: number\n readonly source: RequestFollowSource\n}\n\n// ---------- request payloads ----------\n\nexport interface GetRequestsOptions {\n readonly sort?: RequestSort\n readonly statuses?: ReadonlyArray<RequestStatus>\n readonly mine?: RequestPersonalFilter\n readonly q?: string\n readonly cursor?: string | null\n readonly limit?: number\n}\n\nexport interface GetRequestsResult {\n readonly items: ReadonlyArray<RequestSummary>\n readonly nextCursor: string | null\n}\n\nexport interface SubmitRequestPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly title: string\n readonly description: string\n}\n\nexport interface RequestVotePayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\nexport interface RequestFollowPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n}\n\n// ---------- dashboard shapes ----------\n\nexport interface RequestDetail extends Request {\n readonly submitterAnonymousId: string\n readonly submitterExternalId: string | null\n readonly hidden: boolean\n readonly portalVisible?: boolean\n readonly source?: 'sdk' | 'portal'\n readonly portalVisitorEmail?: string | null\n}\n\nexport interface RequestUpvoterSegmentBreakdown {\n readonly requestId: string\n readonly totalUpvoters: number\n readonly segments: ReadonlyArray<{\n readonly segmentId: string\n readonly segmentName: string\n readonly count: number\n readonly percentage: number\n }>\n}\n\nexport type RequestTimelineEntryKind =\n | 'submitted'\n | 'upvote_burst'\n | 'follow_burst'\n | 'status_changed'\n | 'responded'\n\nexport interface RequestTimelineEntry {\n readonly kind: RequestTimelineEntryKind\n readonly at: string\n readonly count?: number\n readonly fromStatus?: RequestStatus\n readonly toStatus?: RequestStatus\n readonly responseExcerpt?: string\n}\n\nexport interface RequestAnalytics {\n readonly submissions: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly upvotes: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly follows: ReadonlyArray<{ readonly date: string; readonly count: number }>\n readonly statusDistribution: Record<RequestStatus, number>\n readonly devResponseRate: number\n readonly medianResponseHours: number | null\n readonly leaderboard: ReadonlyArray<{\n readonly anonymousId: string\n readonly externalId: string | null\n readonly submissions: number\n readonly upvotes: number\n }>\n}\n\nexport interface UpdateRequestStatusRequest {\n readonly status: RequestStatus\n readonly responseAppend?: string\n}\n\nexport interface UpdateRequestResponseRequest {\n readonly body: string\n}\n\nexport interface UpdateRequestModerationRequest {\n readonly hidden: boolean\n}\n\nexport interface MergeRequestsRequest {\n readonly canonicalId: string\n readonly duplicateIds: ReadonlyArray<string>\n}\n\nexport interface BulkUpdateStatusRequest {\n readonly ids: ReadonlyArray<string>\n readonly status: RequestStatus\n}\n\nexport interface ListRequestsQuery {\n readonly sort?: RequestSort\n readonly status?: RequestStatus | ReadonlyArray<RequestStatus>\n readonly filter?: RequestPersonalFilter\n readonly anonymousId?: string\n readonly q?: string\n readonly hidden?: boolean\n readonly page?: number\n readonly limit?: number\n}\n\n// ---------- settings ----------\n\nexport interface RequestBranding {\n readonly logoUrl?: string | null\n readonly accentColor?: string | null\n readonly coverImageUrl?: string | null\n readonly introCopy?: string | null\n}\n\nexport interface RequestNotificationRules {\n readonly transitions?: Record<string, boolean>\n readonly responseFirst?: boolean\n readonly responseEdit?: boolean\n readonly templateOverrides?: {\n readonly statusChange?: string\n readonly response?: string\n }\n}\n\nexport interface RequestSettings {\n readonly appId: string\n readonly enabled: boolean\n readonly entryLabel: string\n readonly viewSegmentId: string | null\n readonly submitSegmentId: string | null\n readonly publicRoadmapEnabled: boolean\n readonly publicSlug: string | null\n readonly themeMode: ThemeMode\n readonly branding: RequestBranding\n readonly notificationRules: RequestNotificationRules\n}\n\nexport interface UpdateRequestSettingsRequest {\n readonly enabled?: boolean\n readonly entryLabel?: string\n readonly viewSegmentId?: string | null\n readonly submitSegmentId?: string | null\n readonly publicRoadmapEnabled?: boolean\n readonly publicSlug?: string | null\n readonly themeMode?: ThemeMode\n readonly branding?: RequestBranding\n readonly notificationRules?: RequestNotificationRules\n}\n\n// ---------- public web roadmap shapes ----------\n\n/** Public-safe request summary (no submitter identity). */\nexport interface RequestPublicSummary {\n readonly id: string\n readonly title: string\n readonly description: string\n readonly status: RequestStatus\n readonly upvoteCount: number\n readonly followerCount: number\n readonly createdAt: string\n readonly statusChangedAt: string\n}\n\nexport interface RequestPublicDetail extends RequestPublicSummary {\n readonly devResponse: string | null\n readonly lastRespondedAt: string | null\n}\n\nexport interface RequestPublicBranding {\n readonly entryLabel: string\n readonly appName: string\n readonly branding: RequestBranding\n readonly fallbackInstallUrl: string | null\n}\n\n// ---------- SDK push payload ----------\n\n/** Carried inside push/in-app message payloads when status changes. */\nexport interface RequestStatusChangedNotice {\n readonly requestId: string\n readonly title: string\n readonly oldStatus: RequestStatus\n readonly newStatus: RequestStatus\n readonly devResponseExcerpt?: string\n readonly receivedVia: 'push' | 'inapp'\n}\n\n// ---------- comments ----------\n\nexport interface RequestComment {\n readonly id: string\n readonly requestId: string\n readonly body: string\n readonly authorAnonymousId: string\n readonly authorExternalId: string | null\n readonly viewerIsAuthor: boolean\n readonly createdAt: string\n readonly updatedAt: string\n}\n\nexport interface PostCommentPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly body: string\n}\n\nexport interface EditCommentPayload {\n readonly anonymousId: string\n readonly body: string\n}\n\n/** Host-app callbacks registered via `setRequestsHandlers`. */\nexport interface RequestsHandlers {\n readonly onSubmit?: (request: Request) => void\n readonly onVote?: (vote: RequestVote) => void\n readonly onFollow?: (follow: RequestFollow) => void\n readonly onStatusChanged?: (notice: RequestStatusChangedNotice) => void\n}\n","// ==========================================================\n// Inline targeting spec — used by feedback prompts, surveys,\n// and push campaigns. Wraps each pillar record with an\n// `AudienceSpec` (who) + `TriggerSpec` (when).\n//\n// One condition kind in `AudienceCondition` is `segment`,\n// which references saved Segments by id (so the dashboard\n// suggests existing segments in that one branch). All other\n// kinds are evaluated inline against user properties or\n// recent event aggregates.\n//\n// `TriggerSpec` is a discriminated union with a shared base\n// (`app_open`, `event`, `audience_join`). Pillar packages\n// add extra kinds locally (e.g. push adds `manual` /\n// `scheduled`) — engines `switch` on `kind` and treat\n// unknowns as no-op.\n// ==========================================================\n\nimport type { ComparisonOp } from './segment-dsl.js'\n\nexport type Platform = 'ios' | 'android' | 'web'\n\nexport type AudienceCombinator = 'all' | 'any'\n\nexport type AudienceMode = 'everyone' | 'match'\n\n// -------------------- Audience conditions ----------------\n\nexport interface SegmentCondition {\n readonly kind: 'segment'\n readonly op: 'is' | 'is_not'\n readonly segmentIds: ReadonlyArray<string>\n}\n\nexport interface CountryCondition {\n readonly kind: 'country'\n readonly op: 'is_any_of' | 'is_none_of'\n readonly values: ReadonlyArray<string> // ISO 3166-1 alpha-2\n}\n\nexport interface LastActiveCondition {\n readonly kind: 'last_active'\n readonly op: 'within_days' | 'before_days' | 'never'\n readonly days?: number\n}\n\nexport interface InstallDateCondition {\n readonly kind: 'install_date'\n // `*_days` operators are relative to today; `*_date` and `between`\n // pin to user-picked calendar dates (ISO yyyy-mm-dd).\n readonly op:\n | 'within_days'\n | 'before_days'\n | 'after_date'\n | 'before_date'\n | 'between'\n readonly days?: number\n readonly date?: string // ISO date — used by after_date / before_date\n readonly from?: string // ISO date — used by between\n readonly to?: string // ISO date — used by between\n}\n\nexport interface PlatformCondition {\n readonly kind: 'platform'\n readonly op: 'is' | 'is_not'\n readonly values: ReadonlyArray<Platform>\n}\n\nexport interface UserPropertyCondition {\n readonly kind: 'user_property'\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: string | number | boolean | ReadonlyArray<string | number>\n}\n\nexport interface EventPropertyFilter {\n readonly key: string\n readonly op: ComparisonOp\n readonly value?: string | number | boolean | ReadonlyArray<string | number>\n}\n\nexport interface EventPerformedCondition {\n readonly kind: 'event_performed'\n readonly op: 'did' | 'did_not'\n readonly eventName: string\n /** @deprecated Kept so previously saved audience definitions still load. */\n readonly property?: EventPropertyFilter\n readonly propertyFilters?: ReadonlyArray<EventPropertyFilter>\n readonly windowDays?: number\n readonly minCount?: number\n}\n\nexport interface AppVersionCondition {\n readonly kind: 'app_version'\n // String comparison for v1 — \"2.10.0\" sorts before \"2.9.0\" lexically.\n // Acceptable until we ship a semver-aware compare; the dashboard\n // input warns users.\n readonly op: 'eq' | 'neq' | 'gte' | 'lte' | 'gt' | 'lt'\n readonly version: string\n}\n\nexport type AudienceCondition =\n | SegmentCondition\n | CountryCondition\n | LastActiveCondition\n | InstallDateCondition\n | PlatformCondition\n | UserPropertyCondition\n | EventPerformedCondition\n | AppVersionCondition\n\nexport type AudienceConditionKind = AudienceCondition['kind']\n\nexport interface AudienceSpec {\n readonly version: 1\n readonly mode: AudienceMode\n readonly combinator: AudienceCombinator\n readonly conditions: ReadonlyArray<AudienceCondition>\n}\n\nexport function emptyAudienceSpec(): AudienceSpec {\n return { version: 1, mode: 'everyone', combinator: 'all', conditions: [] }\n}\n\n// -------------------- Trigger spec -----------------------\n\nexport type TriggerOccurrenceMode = 'every' | 'after_nth' | 'first_only'\n\nexport interface TriggerOccurrence {\n readonly mode: TriggerOccurrenceMode\n readonly n?: number // required when mode === 'after_nth'\n}\n\nexport interface ActiveWindow {\n readonly startAt?: string // ISO datetime\n readonly endAt?: string // ISO datetime\n}\n\nexport interface AppOpenTrigger {\n readonly kind: 'app_open'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface EventTrigger {\n readonly kind: 'event'\n readonly eventName: string\n readonly propertyFilters?: ReadonlyArray<EventPropertyFilter>\n readonly occurrence?: TriggerOccurrence\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface AudienceJoinTrigger {\n readonly kind: 'audience_join'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport interface AppVersionChangedTrigger {\n readonly kind: 'app_version_changed'\n readonly delaySeconds?: number\n readonly onceOnly?: boolean\n readonly activeWindow?: ActiveWindow\n}\n\nexport type TriggerSpec =\n | AppOpenTrigger\n | EventTrigger\n | AudienceJoinTrigger\n | AppVersionChangedTrigger\n\nexport type TriggerKind = TriggerSpec['kind']\n\n/**\n * Synthetic event name the SDK emits whenever the host app cold-starts\n * or transitions from background to foreground. The trigger engine\n * indexes `app_open`-kind prompts under this name so the same matching\n * pipeline handles both event-driven and lifecycle-driven prompts.\n */\nexport const APP_OPEN_EVENT_NAME = '$app_open'\n\n/**\n * Synthetic event the engine indexes `audience_join` campaigns under.\n * Mirrors APP_OPEN_EVENT_NAME so the same matching pipeline handles\n * both lifecycle and audience-membership triggers.\n */\nexport const AUDIENCE_JOIN_EVENT_NAME = '$audience_join'\n\nexport const AUDIENCE_JOIN_TRIGGER_KIND: AudienceJoinTrigger['kind'] = 'audience_join'\n\n/**\n * Synthetic event the SDK emits on cold-start when the persisted app\n * version differs from the running binary's version. Lets in-app\n * messages (and feedback / surveys) target users right after an update\n * — e.g. \"What's new\" modals.\n */\nexport const APP_VERSION_CHANGED_EVENT_NAME = '$app_version_changed'\n\nexport function defaultTriggerSpec(): TriggerSpec {\n return { kind: 'app_open' }\n}\n\nexport function defaultEventTrigger(eventName = ''): EventTrigger {\n return {\n kind: 'event',\n eventName,\n occurrence: { mode: 'every' },\n }\n}\n","// ==========================================================\n// Preset themes for the Feedback Design step. 12 curated\n// presets + a custom-your-own option in the UI. Each preset\n// surfaces 3 swatches in the gallery card for quick scan.\n// ==========================================================\n\nexport interface ThemeColors {\n readonly primary: string\n readonly background: string\n readonly text: string\n readonly subtext: string\n readonly border: string\n readonly accent?: string\n readonly button?: string\n}\n\nexport type CornerRadiusPreset = 'sharp' | 'soft' | 'rounded' | 'pill'\n\nexport const RADIUS_PRESETS: Record<CornerRadiusPreset, number> = {\n sharp: 4,\n soft: 12,\n rounded: 20,\n pill: 999,\n}\n\nexport interface ThemePreset {\n readonly id: string\n readonly name: string\n readonly description: string\n readonly colors: ThemeColors\n readonly radius: number\n readonly fontFamily: string\n readonly swatches: readonly [string, string, string]\n}\n\n// Default font family for every preset. Matches the SDK's\n// DEFAULT_THEME so a freshly-saved theme renders the same in the\n// dashboard preview (web font loaded via next/font + Google Fonts\n// stylesheet) and on the mobile app (host bundles the .ttf via\n// react-native.config.js). Previously the presets used 'Inter',\n// which neither side had loaded — both fell back to system sans,\n// so designers saw a font drift between the dashboard and device.\nconst JAKARTA = 'Plus Jakarta Sans'\n\nexport const THEME_PRESETS: ReadonlyArray<ThemePreset> = [\n {\n id: 'minimal',\n name: 'Minimal',\n description: 'Clean neutral palette',\n colors: {\n primary: '#111827',\n background: '#FFFFFF',\n text: '#111827',\n subtext: '#6B7280',\n border: '#E5E7EB',\n button: '#111827',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#111827', '#FFFFFF', '#E5E7EB'],\n },\n {\n id: 'ocean',\n name: 'Ocean',\n description: 'Cool blue tones',\n colors: {\n primary: '#0EA5E9',\n background: '#F0F9FF',\n text: '#0C4A6E',\n subtext: '#0369A1',\n border: '#BAE6FD',\n button: '#0EA5E9',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#0EA5E9', '#0C4A6E', '#BAE6FD'],\n },\n {\n id: 'sunset',\n name: 'Sunset',\n description: 'Warm orange glow',\n colors: {\n primary: '#F97316',\n background: '#FFF7ED',\n text: '#7C2D12',\n subtext: '#C2410C',\n border: '#FED7AA',\n button: '#F97316',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#F97316', '#7C2D12', '#FED7AA'],\n },\n {\n id: 'forest',\n name: 'Forest',\n description: 'Natural green hues',\n colors: {\n primary: '#16A34A',\n background: '#F0FDF4',\n text: '#14532D',\n subtext: '#166534',\n border: '#BBF7D0',\n button: '#16A34A',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#16A34A', '#14532D', '#BBF7D0'],\n },\n {\n id: 'midnight',\n name: 'Midnight',\n description: 'Deep dark mode',\n colors: {\n primary: '#A78BFA',\n background: '#0F172A',\n text: '#F8FAFC',\n subtext: '#94A3B8',\n border: '#1E293B',\n button: '#A78BFA',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#A78BFA', '#0F172A', '#1E293B'],\n },\n {\n id: 'candy',\n name: 'Candy',\n description: 'Playful pink + violet',\n colors: {\n primary: '#EC4899',\n background: '#FDF2F8',\n text: '#831843',\n subtext: '#BE185D',\n border: '#FBCFE8',\n button: '#EC4899',\n },\n radius: 20,\n fontFamily: JAKARTA,\n swatches: ['#EC4899', '#831843', '#FBCFE8'],\n },\n {\n id: 'mono',\n name: 'Mono',\n description: 'High-contrast B&W',\n colors: {\n primary: '#000000',\n background: '#FFFFFF',\n text: '#000000',\n subtext: '#525252',\n border: '#000000',\n button: '#000000',\n },\n radius: 4,\n fontFamily: JAKARTA,\n swatches: ['#000000', '#FFFFFF', '#525252'],\n },\n {\n id: 'coral',\n name: 'Coral',\n description: 'Soft coral accent',\n colors: {\n primary: '#FB7185',\n background: '#FFF1F2',\n text: '#881337',\n subtext: '#9F1239',\n border: '#FECDD3',\n button: '#FB7185',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#FB7185', '#881337', '#FECDD3'],\n },\n {\n id: 'ink',\n name: 'Ink',\n description: 'Deep navy editorial',\n colors: {\n primary: '#1E3A8A',\n background: '#F8FAFC',\n text: '#0F172A',\n subtext: '#475569',\n border: '#CBD5E1',\n button: '#1E3A8A',\n },\n radius: 12,\n fontFamily: JAKARTA,\n swatches: ['#1E3A8A', '#0F172A', '#CBD5E1'],\n },\n {\n id: 'mint',\n name: 'Mint',\n description: 'Fresh teal vibe',\n colors: {\n primary: '#14B8A6',\n background: '#F0FDFA',\n text: '#134E4A',\n subtext: '#0F766E',\n border: '#99F6E4',\n button: '#14B8A6',\n },\n radius: 16,\n fontFamily: JAKARTA,\n swatches: ['#14B8A6', '#134E4A', '#99F6E4'],\n },\n {\n id: 'slate',\n name: 'Slate',\n description: 'Quiet professional',\n colors: {\n primary: '#475569',\n background: '#F1F5F9',\n text: '#0F172A',\n subtext: '#64748B',\n border: '#CBD5E1',\n button: '#475569',\n },\n radius: 12,\n fontFamily: JAKARTA,\n swatches: ['#475569', '#0F172A', '#CBD5E1'],\n },\n {\n id: 'aurora',\n name: 'Aurora',\n description: 'Vibrant gradient pop',\n colors: {\n primary: '#8B5CF6',\n background: '#FAF5FF',\n text: '#3B0764',\n subtext: '#7E22CE',\n border: '#E9D5FF',\n accent: '#EC4899',\n button: '#8B5CF6',\n },\n radius: 20,\n fontFamily: JAKARTA,\n swatches: ['#8B5CF6', '#EC4899', '#E9D5FF'],\n },\n] as const\n\nexport function getThemePresetById(id: string): ThemePreset | undefined {\n return THEME_PRESETS.find((preset) => preset.id === id)\n}\n\nexport function defaultThemePreset(): ThemePreset {\n // The presets list is non-empty by construction; assert via index access.\n return THEME_PRESETS[0] as ThemePreset\n}\n","import type { PromptTheme } from './prompt.js'\nimport type { ThemePreset } from './themes.js'\n\nexport type BrandPillar = 'feedback' | 'survey' | 'inapp' | 'requests'\nexport type ThemeMode = 'app_default' | 'custom'\n\nexport interface BrandThemeTokens {\n readonly colors: {\n readonly primary: string\n readonly background: string\n readonly text: string\n readonly subtext: string\n readonly border: string\n }\n readonly radius: number\n readonly fontFamily: string\n}\n\nexport type BrandThemeRef = `preset:${string}` | `custom:${string}`\n\nexport interface BrandTheme {\n readonly ref: BrandThemeRef\n readonly id: string\n readonly kind: 'preset' | 'custom'\n readonly name: string\n readonly description?: string\n readonly tokens: BrandThemeTokens\n readonly swatches: readonly [string, string, string]\n readonly editable: boolean\n readonly assignedPillars: ReadonlyArray<BrandPillar>\n readonly createdAt?: string\n readonly updatedAt?: string\n}\n\nexport type BrandThemeDefaults = Readonly<Record<BrandPillar, BrandThemeRef>>\n\nexport interface AppBrandSettings {\n readonly appId: string\n readonly themes: ReadonlyArray<BrandTheme>\n readonly defaults: BrandThemeDefaults\n readonly resolvedDefaults: Readonly<Record<BrandPillar, BrandThemeTokens>>\n readonly updatedAt: string\n}\n\nexport interface CreateBrandThemeRequest {\n readonly name: string\n readonly tokens: BrandThemeTokens\n}\n\nexport interface UpdateBrandThemeRequest {\n readonly name?: string\n readonly tokens?: BrandThemeTokens\n}\n\nexport interface UpdateBrandThemeDefaultsRequest {\n readonly defaults: BrandThemeDefaults\n}\n\nexport function brandTokensFromPreset(\n preset: Pick<ThemePreset, 'colors' | 'radius' | 'fontFamily'>,\n): BrandThemeTokens {\n return {\n colors: {\n primary: preset.colors.primary,\n background: preset.colors.background,\n text: preset.colors.text,\n subtext: preset.colors.subtext,\n border: preset.colors.border,\n },\n radius: preset.radius,\n fontFamily: preset.fontFamily,\n }\n}\n\nexport function promptThemeFromBrandTokens(tokens: BrandThemeTokens): PromptTheme {\n return {\n colors: { ...tokens.colors },\n radius: tokens.radius,\n fontFamily: tokens.fontFamily,\n }\n}\n\nexport function inAppColorsFromBrandTokens(tokens: BrandThemeTokens): {\n readonly backgroundColor: string\n readonly accentColor: string\n} {\n return {\n backgroundColor: tokens.colors.background,\n accentColor: tokens.colors.primary,\n }\n}\n\nexport function requestAccentFromBrandTokens(tokens: BrandThemeTokens): string {\n return tokens.colors.primary\n}\n","import type { EventPropertyValue } from './event.js'\n\nexport const INTEGRATION_PROVIDERS = ['amplitude', 'mixpanel'] as const\nexport type IntegrationProvider = (typeof INTEGRATION_PROVIDERS)[number]\n\nexport const INTEGRATION_CATEGORIES = [\n 'feedback', 'surveys', 'inapp', 'push', 'requests', 'lifecycle',\n] as const\nexport type IntegrationCategory = (typeof INTEGRATION_CATEGORIES)[number]\n\nexport type IntegrationStatus = 'connected' | 'paused' | 'needs_attention' | 'disconnected'\nexport type AmplitudeIntegrationRegion = 'us' | 'eu'\nexport type MixpanelIntegrationRegion = 'us' | 'eu' | 'in'\nexport type IntegrationRegion = 'us' | 'eu' | 'in'\nexport type IntegrationDeliveryStatus =\n | 'pending' | 'leased' | 'retrying' | 'delivered' | 'dead_lettered' | 'skipped'\nexport type CoreEventSubjectRole = 'actor' | 'affected_user'\n\nexport interface CoreIntegrationEventDefinition {\n readonly key: string\n readonly name: string\n readonly category: IntegrationCategory | 'identity'\n readonly subjectRole: CoreEventSubjectRole\n readonly required?: boolean\n /** Stable output property key -> accepted source property aliases. */\n readonly properties: Readonly<Record<string, ReadonlyArray<string>>>\n}\n\nexport const USER_IDENTIFIED_EVENT_NAME = '$user_identified' as const\n\nfunction camelize(value: string): string {\n return value.replace(/_([a-z])/g, (_match, letter: string) => letter.toUpperCase())\n}\n\nconst ids = (...keys: string[]): Readonly<Record<string, ReadonlyArray<string>>> =>\n Object.fromEntries(keys.map((key) => [key, [key, camelize(key)]]))\n\nconst pushEvents: ReadonlyArray<readonly [string, string]> = [\n ['$push_sent', 'UserGist Push Sent'],\n ['$push_delivered', 'UserGist Push Delivered'],\n ['$push_received', 'UserGist Push Received'],\n ['$push_displayed', 'UserGist Push Displayed'],\n ['$push_opened', 'UserGist Push Opened'],\n ['$push_dismissed', 'UserGist Push Dismissed'],\n ['$push_clicked', 'UserGist Push Clicked'],\n ['$push_action_clicked', 'UserGist Push Action Clicked'],\n ['$push_bounced', 'UserGist Push Bounced'],\n]\n\nconst requestEvents: ReadonlyArray<readonly [string, string, CoreEventSubjectRole]> = [\n ['$request_submitted', 'UserGist Request Submitted', 'actor'],\n ['$request_upvoted', 'UserGist Request Upvoted', 'actor'],\n ['$request_unupvoted', 'UserGist Request Unupvoted', 'actor'],\n ['$request_followed', 'UserGist Request Followed', 'actor'],\n ['$request_unfollowed', 'UserGist Request Unfollowed', 'actor'],\n ['$request_status_changed', 'UserGist Request Status Changed', 'affected_user'],\n ['$request_responded', 'UserGist Request Responded', 'affected_user'],\n ['$request_commented', 'UserGist Request Commented', 'actor'],\n ['$request_comment_edited', 'UserGist Request Comment Edited', 'actor'],\n ['$request_comment_deleted', 'UserGist Request Comment Deleted', 'affected_user'],\n]\n\nconst answerProperties: Readonly<Record<string, ReadonlyArray<string>>> = {\n ...ids(\n 'question_id',\n 'question_type',\n 'question_title',\n 'answer_format',\n 'answer_present',\n 'answer_numeric_value',\n 'answer_selection_count',\n 'answer_text_length',\n ),\n // These aliases are generated only by the trusted server response paths.\n // The API delivery boundary removes them from public SDK events before this\n // normalizer runs. The complete answer_value stays in UserGist; destinations\n // receive a value only for server-verified structured data.\n answer_value: ['__usergist_destination_answer_value'],\n answer_display_value: ['__usergist_destination_answer_display_value'],\n}\n\nexport const CORE_INTEGRATION_EVENTS: ReadonlyArray<CoreIntegrationEventDefinition> = [\n { key: '$app_open', name: 'UserGist App Opened', category: 'lifecycle', subjectRole: 'actor', properties: {} },\n { key: '$app_version_changed', name: 'UserGist App Version Changed', category: 'lifecycle', subjectRole: 'actor', properties: { ...ids('old_version', 'new_version') } },\n { key: USER_IDENTIFIED_EVENT_NAME, name: 'UserGist User Identified', category: 'identity', subjectRole: 'actor', required: true, properties: {} },\n { key: '$feedback_prompt_shown', name: 'UserGist Feedback Prompt Shown', category: 'feedback', subjectRole: 'actor', properties: { ...ids('prompt_id') } },\n { key: '$feedback_response', name: 'UserGist Feedback Response Submitted', category: 'feedback', subjectRole: 'actor', properties: { ...ids('response_id', 'prompt_id', 'prompt_name', 'dismissed', 'latency_ms', 'answer_count', 'feedback_types') } },\n { key: '$feedback_answer_submitted', name: 'UserGist Feedback Answer Submitted', category: 'feedback', subjectRole: 'actor', properties: { ...ids('response_id', 'prompt_id', 'prompt_name'), ...answerProperties } },\n { key: '$survey_started', name: 'UserGist Survey Started', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source') } },\n { key: '$survey_answer_submitted', name: 'UserGist Survey Answer Submitted', category: 'surveys', subjectRole: 'actor', properties: { ...ids('response_id', 'campaign_id', 'survey_name', 'attempt_id', 'language'), ...answerProperties } },\n { key: '$survey_completed', name: 'UserGist Survey Completed', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source', 'duration_ms') } },\n { key: '$survey_abandoned', name: 'UserGist Survey Abandoned', category: 'surveys', subjectRole: 'actor', properties: { ...ids('campaign_id', 'survey_name', 'attempt_id', 'language', 'source', 'duration_ms') } },\n { key: '$inapp_shown', name: 'UserGist In-App Message Shown', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id') } },\n { key: '$inapp_dismissed', name: 'UserGist In-App Message Dismissed', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'dismiss_reason') } },\n { key: '$inapp_auto_dismissed', name: 'UserGist In-App Message Auto-Dismissed', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'dismiss_reason') } },\n { key: '$inapp_cta_clicked', name: 'UserGist In-App Message CTA Clicked', category: 'inapp', subjectRole: 'actor', properties: { ...ids('message_id', 'cta_id', 'cta_index'), action: ['action', 'cta_action'] } },\n ...pushEvents.map(([key, name]) => ({\n key,\n name,\n category: 'push' as const,\n subjectRole: 'actor' as const,\n properties: {\n ...ids('delivery_id', 'campaign_id', 'delivery_state', 'failure_code'),\n action_id: ['action_id', 'actionId', 'action_button', 'actionButton'],\n },\n })),\n ...requestEvents.map(([key, name, subjectRole]) => ({ key, name, category: 'requests' as const, subjectRole, properties: { ...ids('request_id', 'comment_id', 'source', 'old_status', 'new_status', 'deleted_by'), usergist_actor_type: ['usergist_actor_type', 'actor_type'] } })),\n]\n\nconst CORE_EVENT_BY_KEY = new Map(CORE_INTEGRATION_EVENTS.map((event) => [event.key, event]))\n\nexport function getCoreIntegrationEvent(key: string): CoreIntegrationEventDefinition | null {\n return CORE_EVENT_BY_KEY.get(key) ?? null\n}\n\nexport function sanitizeCoreIntegrationProperties(\n definition: CoreIntegrationEventDefinition,\n input: Readonly<Record<string, unknown>> | null | undefined,\n): Readonly<Record<string, EventPropertyValue>> {\n if (!input) return {}\n const output: Record<string, EventPropertyValue> = {}\n for (const [outputKey, aliases] of Object.entries(definition.properties)) {\n const alias = aliases.find((candidate) => Object.prototype.hasOwnProperty.call(input, candidate))\n if (!alias) continue\n const value = input[alias]\n if (typeof value === 'string') output[outputKey] = value.slice(0, 1024)\n else if (typeof value === 'number' && Number.isFinite(value)) output[outputKey] = value\n else if (typeof value === 'boolean' || value === null) output[outputKey] = value\n }\n return output\n}\n\nexport interface IntegrationSummary {\n readonly id: string\n readonly provider: IntegrationProvider\n readonly status: IntegrationStatus\n readonly region: IntegrationRegion\n readonly categories: ReadonlyArray<IntegrationCategory>\n readonly credentialHint: string | null\n readonly connectedAt: string | null\n readonly pausedAt: string | null\n readonly lastVerifiedAt: string | null\n readonly lastSuccessAt: string | null\n readonly lastFailureAt: string | null\n readonly lastErrorCode: string | null\n readonly lastErrorMessage: string | null\n}\n\nexport type ConnectIntegrationRequest =\n | { readonly provider: 'amplitude'; readonly apiKey: string; readonly region: 'us' | 'eu'; readonly categories: ReadonlyArray<IntegrationCategory> }\n | { readonly provider: 'mixpanel'; readonly projectToken: string; readonly region: 'us' | 'eu' | 'in'; readonly categories: ReadonlyArray<IntegrationCategory>; readonly identityMode: 'simplified' }\n\nexport interface UpdateIntegrationRequest {\n readonly categories: ReadonlyArray<IntegrationCategory>\n}\n\nexport interface IntegrationTestResult {\n readonly accepted: true\n readonly eventName: 'UserGist Integration Connected'\n readonly deviceId: string\n readonly acceptedAt: string\n}\n\nexport interface IntegrationDeliverySummary {\n readonly id: string\n readonly eventKey: string\n readonly eventName: string\n readonly status: IntegrationDeliveryStatus\n readonly identity: { readonly anonymousId: string; readonly externalId: string | null }\n readonly occurredAt: string\n readonly attempts: number\n readonly providerStatusCode: number | null\n readonly lastErrorMessage: string | null\n}\n\nexport interface IntegrationDeliveriesResponse {\n readonly items: ReadonlyArray<IntegrationDeliverySummary>\n readonly nextCursor: string | null\n}\n","/**\n * Canonical event names emitted by the push pillar. These land in the\n * events pipeline so segments can query them like any other event.\n */\nexport const PUSH_EVENTS = {\n SENT: '$push_sent',\n DELIVERED: '$push_delivered',\n DISPLAYED: '$push_displayed',\n RECEIVED: '$push_received',\n OPENED: '$push_opened',\n DISMISSED: '$push_dismissed',\n CLICKED: '$push_clicked',\n ACTION_CLICKED: '$push_action_clicked',\n BOUNCED: '$push_bounced',\n SILENT_ACK: '$push_silent_ack',\n} as const\n\nexport type PushEventName = (typeof PUSH_EVENTS)[keyof typeof PUSH_EVENTS]\n","import type { BillingInterval, BillingPriceKind } from '../types/billing.js'\n\nexport interface CommercialPlanDefinition {\n readonly id: 'starter' | 'pro' | 'scale'\n readonly name: string\n readonly publicSlug: string\n readonly description: string\n readonly priceKind: BillingPriceKind\n readonly selfServe: boolean\n readonly baseAmountCents: number\n readonly currency: 'USD'\n readonly includedMau: number\n readonly overagePer1kCents: number\n readonly appLimit: number | null\n readonly billingInterval: BillingInterval\n readonly sortOrder: number\n readonly accessRank: number\n readonly catalogVersion: number\n}\n\nexport const COMMERCIAL_BILLING_PLANS: ReadonlyArray<CommercialPlanDefinition> = [\n {\n id: 'starter',\n name: 'Starter',\n publicSlug: 'starter',\n description: 'For small teams getting started with product feedback.',\n priceKind: 'fixed',\n selfServe: true,\n baseAmountCents: 1_999,\n currency: 'USD',\n includedMau: 1_000,\n overagePer1kCents: 200,\n appLimit: 1,\n billingInterval: 'month',\n sortOrder: 10,\n accessRank: 10,\n catalogVersion: 1,\n },\n {\n id: 'pro',\n name: 'Pro',\n publicSlug: 'pro',\n description: 'For growing products with multiple applications.',\n priceKind: 'fixed',\n selfServe: true,\n baseAmountCents: 4_900,\n currency: 'USD',\n includedMau: 25_000,\n overagePer1kCents: 100,\n appLimit: 3,\n billingInterval: 'month',\n sortOrder: 20,\n accessRank: 20,\n catalogVersion: 1,\n },\n {\n id: 'scale',\n name: 'Scale',\n publicSlug: 'scale',\n description: 'Contract pricing, usage, and application limits for larger organizations.',\n priceKind: 'custom',\n selfServe: false,\n baseAmountCents: 0,\n currency: 'USD',\n includedMau: 0,\n overagePer1kCents: 0,\n appLimit: null,\n billingInterval: 'month',\n sortOrder: 30,\n accessRank: 30,\n catalogVersion: 1,\n },\n]\n\nexport const TRIAL_DAYS = 14\nexport const BILLING_GRACE_DAYS = 7\nexport const TRIAL_APP_LIMIT = 1\nexport const STARTER_FOUNDING_OFFER_CODE = 'starter_founding_100'\nexport const STARTER_FOUNDING_CUSTOMER_LIMIT = 100\n","/**\n * Runtime types shared by the React Native, iOS, and Android SDKs for\n * the \"under the hood\" push primitives:\n * • Silent reachability ping payloads\n * • Delivery beacon contract (delivered / displayed / dismissed)\n * • Channel registry (Android NotificationChannel + iOS category)\n * • App-open beacon\n */\n\nexport interface SilentPushPayload {\n readonly usergist_silent: '1'\n readonly usergist_ping_id: string\n}\n\nexport type AndroidImportance = 0 | 1 | 2 | 3 | 4\n\nexport type ChannelCategory =\n | 'transactional'\n | 'marketing'\n | 'silent'\n | 'digest'\n | 'alert'\n\nexport interface PushChannelDef {\n readonly app_id: string\n readonly channel_id: string\n readonly display_name: string\n readonly description: string | null\n readonly importance: AndroidImportance\n readonly default_sound: string | null\n readonly default_vibrate: boolean\n readonly default_badge: boolean\n readonly category: ChannelCategory\n}\n\nexport interface DeliveryBeacon {\n readonly deliveryId: string\n readonly occurredAt?: string\n readonly attemptId?: string\n readonly actionButton?: string\n}\n\nexport type DeliveryBeaconKind =\n | 'delivered'\n | 'displayed'\n | 'dismissed'\n\nexport interface SilentAck {\n readonly pingId: string\n readonly anonymousId: string\n readonly receivedAt?: string\n}\n\nexport interface RebindRequest {\n readonly anonymousId: string\n readonly externalId: string\n readonly token: string\n}\n\nexport interface AppOpenBeacon {\n readonly anonymousId: string\n readonly occurredAt?: string\n}\n\n/**\n * SDK-side recognized payload after parsing a server-sent push. Both\n * APNs (via NSE) and FCM (via FirebaseMessagingService) decode into\n * this shape so the cross-platform UI/behaviour layer can stay\n * platform-agnostic.\n */\nexport interface ParsedPushPayload {\n readonly campaignId: string\n readonly variantId: string\n readonly deliveryId: string\n readonly title: string\n readonly body: string\n readonly imageUrl: string | null\n readonly deepLink: string | null\n readonly language: string | null\n readonly actionButtons: ReadonlyArray<{\n readonly label: string\n readonly action: 'open_app' | 'deep_link' | 'url' | 'dismiss'\n readonly target?: string\n }>\n readonly androidChannelId: string | null\n readonly silent: boolean\n readonly silentPingId: string | null\n}\n\n/**\n * Helper used by the data-only Android branch and the iOS NSE to\n * detect a silent reachability ping.\n */\nexport function isSilentPushPayload(\n raw: Record<string, unknown> | null | undefined,\n): boolean {\n if (!raw) return false\n return raw.usergist_silent === '1' && typeof raw.usergist_ping_id === 'string'\n}\n","import type {\n Predicate,\n PredicateGroup,\n SegmentDsl,\n UserPropertyPredicate,\n EventCountPredicate,\n EventOccurredPredicate,\n} from '../types/segment-dsl.js'\nimport type {\n SerializedSegmentRules,\n UserPropertyRule,\n} from '../types/prompt.js'\n\nexport interface UserState {\n readonly properties: Readonly<Record<string, string | number | boolean | null | undefined>>\n // eventCounts: eventName -> map of windowDays -> count\n readonly eventCounts: Readonly<Record<string, Readonly<Record<number, number>>>>\n // lastEventAt: eventName -> ISO timestamp (most recent)\n readonly lastEventAt: Readonly<Record<string, string | undefined>>\n}\n\n/**\n * Evaluate a segment DSL against a user snapshot.\n *\n * @param now - Reference timestamp (ms since epoch) used for time-window\n * predicates. MUST be supplied explicitly so evaluation is deterministic\n * across processes (server trigger engine + client SDK), independent of\n * wall-clock skew. Defaults to `Date.now()` for backwards compatibility,\n * but callers that care about parity should pass the same `now` they pass\n * to the matching server-side call.\n */\nexport function evaluateSegment(\n dsl: SegmentDsl,\n user: UserState,\n now: number = Date.now(),\n): boolean {\n return evaluateGroup(dsl.root, user, now)\n}\n\nfunction evaluateGroup(group: PredicateGroup, user: UserState, now: number): boolean {\n if (group.predicates.length === 0) return true\n if (group.combinator === 'AND') {\n return group.predicates.every((p) => evaluateNode(p, user, now))\n }\n return group.predicates.some((p) => evaluateNode(p, user, now))\n}\n\nfunction evaluateNode(node: Predicate | PredicateGroup, user: UserState, now: number): boolean {\n if ('combinator' in node) return evaluateGroup(node, user, now)\n switch (node.kind) {\n case 'user_property':\n return evaluateUserProperty(node, user)\n case 'event_count':\n return evaluateEventCount(node, user)\n case 'event_occurred':\n return evaluateEventOccurred(node, user, now)\n }\n}\n\nfunction evaluateUserProperty(p: UserPropertyPredicate, user: UserState): boolean {\n const actual = user.properties[p.key]\n switch (p.op) {\n case 'exists':\n return actual !== undefined && actual !== null\n case 'not_exists':\n return actual === undefined || actual === null\n case 'eq':\n return actual === p.value\n case 'neq':\n return actual !== p.value\n case 'in':\n return Array.isArray(p.value) && actual != null && (p.value as ReadonlyArray<unknown>).includes(actual)\n case 'nin':\n return Array.isArray(p.value) && actual != null && !(p.value as ReadonlyArray<unknown>).includes(actual)\n case 'gt':\n return typeof actual === 'number' && typeof p.value === 'number' && actual > p.value\n case 'gte':\n return typeof actual === 'number' && typeof p.value === 'number' && actual >= p.value\n case 'lt':\n return typeof actual === 'number' && typeof p.value === 'number' && actual < p.value\n case 'lte':\n return typeof actual === 'number' && typeof p.value === 'number' && actual <= p.value\n case 'contains':\n return typeof actual === 'string' && typeof p.value === 'string' && actual.includes(p.value)\n case 'starts_with':\n return typeof actual === 'string' && typeof p.value === 'string' && actual.startsWith(p.value)\n }\n}\n\nfunction evaluateEventCount(p: EventCountPredicate, user: UserState): boolean {\n const eventBucket = user.eventCounts[p.eventName]\n const count = eventBucket?.[p.windowDays] ?? 0\n switch (p.op) {\n case 'eq': return count === p.count\n case 'gte': return count >= p.count\n case 'lte': return count <= p.count\n case 'gt': return count > p.count\n case 'lt': return count < p.count\n }\n}\n\nfunction evaluateEventOccurred(p: EventOccurredPredicate, user: UserState, now: number): boolean {\n const last = user.lastEventAt[p.eventName]\n if (p.ever) {\n if (!last) return false\n if (p.windowDays == null) return true\n const cutoff = now - p.windowDays * 86400_000\n return Date.parse(last) >= cutoff\n }\n if (!last) return true\n if (p.windowDays == null) return false\n const cutoff = now - p.windowDays * 86400_000\n return Date.parse(last) < cutoff\n}\n\n// ============================================================\n// SerializedSegmentRules → SegmentDsl bridge.\n//\n// The SDK ships armed triggers with a flattened rule set\n// (`SerializedSegmentRules`) for transport efficiency. We deliberately keep\n// only ONE evaluator (`evaluateSegment`) so that server and SDK paths cannot\n// diverge. The bridge converts the serialized form into an AND-combined\n// PredicateGroup and delegates to the same engine.\n// ============================================================\n\nexport function evaluateSerializedSegmentRules(\n rules: SerializedSegmentRules | null | undefined,\n user: UserState,\n now: number = Date.now(),\n): boolean {\n if (!rules) return true\n const dsl = serializedRulesToDsl(rules)\n return evaluateSegment(dsl, user, now)\n}\n\nexport function serializedRulesToDsl(rules: SerializedSegmentRules): SegmentDsl {\n const predicates: Predicate[] = []\n\n for (const rule of rules.userProperties ?? []) {\n predicates.push(userPropertyRuleToPredicate(rule))\n }\n for (const rule of rules.eventCounts ?? []) {\n predicates.push({\n kind: 'event_count',\n eventName: rule.eventName,\n op: rule.op,\n count: rule.count,\n windowDays: rule.windowDays,\n })\n }\n\n return {\n version: 1,\n root: { combinator: 'AND', predicates },\n }\n}\n\nfunction userPropertyRuleToPredicate(rule: UserPropertyRule): UserPropertyPredicate {\n // SerializedSegmentRules constrains operators to a subset; cast safely.\n return {\n kind: 'user_property',\n key: rule.key,\n op: rule.op,\n value: rule.value as UserPropertyPredicate['value'],\n }\n}\n","// ============================================================\n// Branch DSL evaluator — shared by SDKs and dashboard preview.\n// Given a flow, a current question, and the answer just recorded,\n// returns the next question id (or SURVEY_END_SENTINEL).\n// ============================================================\n\nimport {\n SURVEY_END_SENTINEL,\n type SurveyAnswerRecord,\n type SurveyAnswerValue,\n type SurveyBranch,\n type SurveyBranchCondition,\n type SurveyFlow,\n type SurveyQuestion,\n} from '../types/survey.js'\n\nexport function evaluateBranchCondition(\n cond: SurveyBranchCondition,\n answer: SurveyAnswerValue | undefined,\n): boolean {\n if (cond.op === 'answered') return answer !== undefined && answer !== null && answer !== ''\n if (cond.op === 'unanswered') return answer === undefined || answer === null || answer === ''\n if (answer === undefined || answer === null) return false\n\n switch (cond.op) {\n case 'eq':\n return answer === cond.value\n case 'neq':\n return answer !== cond.value\n case 'lt':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer < cond.value\n case 'lte':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer <= cond.value\n case 'gt':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer > cond.value\n case 'gte':\n return typeof answer === 'number' && typeof cond.value === 'number' && answer >= cond.value\n case 'includes':\n return Array.isArray(answer) && (answer as ReadonlyArray<unknown>).includes(cond.value as never)\n case 'not_includes':\n return Array.isArray(answer) && !(answer as ReadonlyArray<unknown>).includes(cond.value as never)\n default:\n return false\n }\n}\n\nexport function nextQuestionId(\n flow: SurveyFlow,\n currentQuestionId: string,\n answers: SurveyAnswerRecord,\n): string | null {\n const branches = flow.branches.filter((b) => b.fromQuestionId === currentQuestionId)\n const answer = answers[currentQuestionId]\n for (const branch of branches) {\n if (evaluateBranchCondition(branch.condition, answer)) {\n if (branch.toQuestionId === SURVEY_END_SENTINEL) return null\n return branch.toQuestionId\n }\n }\n return defaultNext(flow, currentQuestionId)\n}\n\nfunction defaultNext(flow: SurveyFlow, currentQuestionId: string): string | null {\n const idx = flow.questions.findIndex((q) => q.id === currentQuestionId)\n if (idx < 0 || idx >= flow.questions.length - 1) return null\n const next = flow.questions[idx + 1]\n return next ? next.id : null\n}\n\nexport function findQuestion(\n flow: SurveyFlow,\n questionId: string,\n): SurveyQuestion | undefined {\n return flow.questions.find((q) => q.id === questionId)\n}\n\nexport function findQuestionIndex(flow: SurveyFlow, questionId: string): number {\n return flow.questions.findIndex((q) => q.id === questionId)\n}\n\n// Conservative progress estimate: count the current index + 1 over total. Branching\n// makes an exact number impossible, so we expose the worst-case fraction.\nexport function estimateProgress(flow: SurveyFlow, currentQuestionId: string | null): number {\n if (!currentQuestionId) return 1\n const idx = findQuestionIndex(flow, currentQuestionId)\n if (idx < 0) return 0\n return (idx + 1) / Math.max(1, flow.questions.length)\n}\n\n// Given a branch filter list, compute the *reachable* set of questions from a starting\n// point. Used by the composer to render \"dead question\" warnings.\nexport function reachableQuestions(\n flow: SurveyFlow,\n startId?: string,\n): ReadonlySet<string> {\n const start = startId ?? flow.startQuestionId\n const visited = new Set<string>()\n const stack: string[] = [start]\n while (stack.length > 0) {\n const id = stack.pop()\n if (id === undefined) continue\n if (visited.has(id)) continue\n visited.add(id)\n const outgoing = flow.branches.filter((b) => b.fromQuestionId === id)\n for (const b of outgoing) {\n if (b.toQuestionId !== SURVEY_END_SENTINEL) stack.push(b.toQuestionId)\n }\n const idx = flow.questions.findIndex((q) => q.id === id)\n if (idx >= 0 && idx < flow.questions.length - 1) {\n const next = flow.questions[idx + 1]\n if (next) stack.push(next.id)\n }\n }\n return visited\n}\n","import type { PeriodicFrequency } from '../types/campaign.js'\n\nexport interface PeriodicSchedule {\n readonly frequency: PeriodicFrequency\n readonly hourLocal: number\n readonly minuteLocal: number\n /** 0..6 (Sun=0). Required for `weekly`. */\n readonly weekday?: number\n /** 1..31. Required for `monthly`. */\n readonly dayOfMonth?: number\n /** IANA timezone the hour/minute are expressed in. Defaults to UTC. */\n readonly tz?: string\n}\n\n/**\n * Returns the next firing instant (as a Date in UTC) for a structured\n * periodic schedule, strictly after `now`.\n *\n * Pure / dependency-free. Used both server-side (push-scheduler `isDue`\n * check) and client-side (dashboard \"Next occurrence\" preview). Keep\n * deterministic for a given (schedule, now) tuple — no randomness.\n *\n * The walk is bounded — daily 2 iters, weekly 8, monthly 13 — so DST\n * gaps and short-month overflows can't loop forever.\n */\nexport function nextPeriodicFire(\n schedule: PeriodicSchedule,\n now: Date = new Date(),\n): Date {\n const tz = schedule.tz || 'UTC'\n const start = startCandidate(schedule, now, tz)\n return walkForward(start, schedule, now, tz)\n}\n\n/**\n * Minutes east of UTC for `tz` at instant `at`. Falls back to 0 (UTC)\n * for invalid input. Exported so server-side callers can share the\n * same offset math the periodic walker uses (avoids a separate\n * implementation in push-scheduler.ts).\n */\nexport function tzOffsetMinutes(at: Date, tz: string): number {\n if (tz === 'UTC') return 0\n try {\n const fmt = getFormatter(tz)\n const parts = fmt.formatToParts(at).reduce<Record<string, string>>((acc, p) => {\n if (p.type !== 'literal') acc[p.type] = p.value\n return acc\n }, {})\n const utc = Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour) === 24 ? 0 : Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n )\n return Math.round((utc - at.getTime()) / 60_000)\n } catch {\n return 0\n }\n}\n\nfunction startCandidate(\n schedule: PeriodicSchedule,\n now: Date,\n tz: string,\n): Date {\n const localNow = wallClock(now, tz)\n const target = new Date(localNow)\n // `wallClock` is an artificial UTC-backed view of the target timezone.\n // Always use UTC accessors so this calculation cannot inherit the host's\n // timezone (the browser for previews, or the server for delivery).\n target.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0)\n return localToUtc(target, tz)\n}\n\nfunction walkForward(\n candidate: Date,\n schedule: PeriodicSchedule,\n now: Date,\n tz: string,\n): Date {\n let cursor = candidate\n const max = schedule.frequency === 'daily' ? 2 : schedule.frequency === 'weekly' ? 8 : 13\n for (let i = 0; i < max; i++) {\n const local = wallClock(cursor, tz)\n if (matchesFrequency(local, schedule) && cursor.getTime() > now.getTime()) {\n return cursor\n }\n cursor = step(cursor, local, schedule, tz)\n }\n return cursor\n}\n\nfunction matchesFrequency(local: Date, schedule: PeriodicSchedule): boolean {\n if (schedule.frequency === 'daily') return true\n if (schedule.frequency === 'weekly') {\n return schedule.weekday === undefined || local.getUTCDay() === schedule.weekday\n }\n return schedule.dayOfMonth === undefined || local.getUTCDate() === schedule.dayOfMonth\n}\n\nfunction step(\n cursor: Date,\n cursorLocal: Date,\n schedule: PeriodicSchedule,\n tz: string,\n): Date {\n if (schedule.frequency === 'daily' || schedule.frequency === 'weekly') {\n return addDays(cursor, 1)\n }\n // Monthly: jump to the next month at the same dayOfMonth (or last day if shorter).\n const next = new Date(cursorLocal)\n next.setUTCMonth(next.getUTCMonth() + 1)\n if (schedule.dayOfMonth !== undefined) {\n const lastDay = lastDayOfMonth(next.getUTCFullYear(), next.getUTCMonth())\n next.setUTCDate(Math.min(schedule.dayOfMonth, lastDay))\n }\n next.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0)\n return localToUtc(next, tz)\n}\n\nfunction addDays(d: Date, days: number): Date {\n const next = new Date(d.getTime())\n next.setUTCDate(next.getUTCDate() + days)\n return next\n}\n\nfunction lastDayOfMonth(year: number, monthIndex: number): number {\n return new Date(Date.UTC(year, monthIndex + 1, 0)).getUTCDate()\n}\n\n/** Returns a UTC-backed Date whose `getUTCX()` methods read in `tz`'s wall clock. */\nfunction wallClock(d: Date, tz: string): Date {\n const offsetMin = tzOffsetMinutes(d, tz)\n return new Date(d.getTime() + offsetMin * 60_000)\n}\n\n/** Inverse of `wallClock` — given a Date whose getX reads in `tz`, return UTC. */\nfunction localToUtc(localView: Date, tz: string): Date {\n const offsetMin = tzOffsetMinutes(localView, tz)\n return new Date(localView.getTime() - offsetMin * 60_000)\n}\n\n// `Intl.DateTimeFormat` construction dominates this module's cost (~100 µs\n// per ctor). The scheduler can call `nextPeriodicFire` thousands of times\n// per tick across many users, so we cache one formatter per tz at module\n// scope. Map is keyed by IANA name and lookups are O(1). Safe to share —\n// formatter instances are stateless across calls.\nconst FORMATTER_CACHE = /* @__PURE__ */ new Map<string, Intl.DateTimeFormat>()\n\nfunction getFormatter(tz: string): Intl.DateTimeFormat {\n const cached = FORMATTER_CACHE.get(tz)\n if (cached) return cached\n const fmt = new Intl.DateTimeFormat('en-US', {\n timeZone: tz,\n hour12: false,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n FORMATTER_CACHE.set(tz, fmt)\n return fmt\n}\n","const PARTS_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>()\n\nexport interface ZonedDateTimeParts {\n readonly date: string\n readonly time: string\n readonly weekday: number\n readonly dayOfMonth: number\n}\n\nexport function isValidIanaTimeZone(value: string): boolean {\n if (!value.trim()) return false\n try {\n new Intl.DateTimeFormat('en-US', { timeZone: value }).format()\n return true\n } catch {\n return false\n }\n}\n\nexport function zonedDateTimeParts(\n instant: Date,\n timeZone: string,\n): ZonedDateTimeParts {\n if (!isValidIanaTimeZone(timeZone)) {\n throw new RangeError(`Invalid IANA timezone: ${timeZone}`)\n }\n if (!Number.isFinite(instant.getTime())) {\n throw new RangeError('Invalid date')\n }\n\n const formatter = getPartsFormatter(timeZone)\n const parts = formatter.formatToParts(instant).reduce<Record<string, string>>(\n (result, part) => {\n if (part.type !== 'literal') result[part.type] = part.value\n return result\n },\n {},\n )\n const year = Number(parts.year)\n const month = Number(parts.month)\n const day = Number(parts.day)\n const hour = Number(parts.hour)\n const minute = Number(parts.minute)\n\n return {\n date: `${year}-${pad2(month)}-${pad2(day)}`,\n time: `${pad2(hour)}:${pad2(minute)}`,\n weekday: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),\n dayOfMonth: day,\n }\n}\n\n/**\n * Converts an IANA-zone wall-clock value into an absolute instant.\n *\n * Ambiguous fall-back times resolve to the earlier occurrence. Nonexistent\n * spring-forward times are rejected instead of silently moving a campaign.\n */\nexport function zonedDateTimeToUtc(\n date: string,\n time: string,\n timeZone: string,\n): Date {\n if (!isValidIanaTimeZone(timeZone)) {\n throw new RangeError(`Invalid IANA timezone: ${timeZone}`)\n }\n\n const dateMatch = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(date)\n const timeMatch = /^(\\d{2}):(\\d{2})$/.exec(time)\n if (!dateMatch || !timeMatch) throw new RangeError('Invalid local date or time')\n\n const year = Number(dateMatch[1])\n const month = Number(dateMatch[2])\n const day = Number(dateMatch[3])\n const hour = Number(timeMatch[1])\n const minute = Number(timeMatch[2])\n const naive = Date.UTC(year, month - 1, day, hour, minute, 0, 0)\n const calendarCheck = new Date(naive)\n if (\n calendarCheck.getUTCFullYear() !== year ||\n calendarCheck.getUTCMonth() !== month - 1 ||\n calendarCheck.getUTCDate() !== day ||\n hour > 23 ||\n minute > 59\n ) {\n throw new RangeError('Invalid local date or time')\n }\n\n // A wall-clock value can have zero, one, or two matching instants around a\n // timezone transition. Sample both sides of the local date so we observe\n // every applicable offset, then retain only exact round trips.\n const offsets = new Set(\n [-36, -12, 0, 12, 36].map((hours) =>\n timeZoneOffsetMinutes(new Date(naive + hours * 3_600_000), timeZone),\n ),\n )\n const candidates = [...offsets]\n .map((offset) => new Date(naive - offset * 60_000))\n .filter((candidate) => {\n const roundTrip = zonedDateTimeParts(candidate, timeZone)\n return roundTrip.date === date && roundTrip.time === time\n })\n .sort((left, right) => left.getTime() - right.getTime())\n\n const candidate = candidates[0]\n if (!candidate) {\n throw new RangeError('This local time does not exist in the selected timezone')\n }\n return candidate\n}\n\n/** Returns the final millisecond of a calendar date in an IANA timezone. */\nexport function zonedDateEndToUtc(date: string, timeZone: string): Date {\n const lastMinute = zonedDateTimeToUtc(date, '23:59', timeZone)\n return new Date(lastMinute.getTime() + 59_999)\n}\n\nfunction timeZoneOffsetMinutes(instant: Date, timeZone: string): number {\n const parts = getPartsFormatter(timeZone)\n .formatToParts(instant)\n .reduce<Record<string, string>>((result, part) => {\n if (part.type !== 'literal') result[part.type] = part.value\n return result\n }, {})\n const asUtc = Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n )\n return Math.round((asUtc - instant.getTime()) / 60_000)\n}\n\nfunction getPartsFormatter(timeZone: string): Intl.DateTimeFormat {\n const cached = PARTS_FORMATTER_CACHE.get(timeZone)\n if (cached) return cached\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n PARTS_FORMATTER_CACHE.set(timeZone, formatter)\n return formatter\n}\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, '0')\n}\n","import type * as Content from '../types/portal-content.js'\nimport type * as Mcp from '../types/mcp.js'\n// ============================================================\n// API contract — every endpoint path, method, request, response.\n// The API implements this; clients (dashboard, SDKs) consume it.\n// If you add/modify a route, update this file first.\n// ============================================================\n\nimport type {\n EventDefinition,\n IngestBatch,\n EventPropertySchema,\n} from '../types/event.js'\nimport type {\n ArmedTrigger,\n Prompt,\n Question,\n PromptTheme,\n FrequencyCaps,\n PromptStatus,\n} from '../types/prompt.js'\nimport type { Segment } from '../types/segment.js'\nimport type * as Portal from '../types/portal.js'\nimport type { SegmentDsl } from '../types/segment-dsl.js'\nimport type { AudienceSpec } from '../types/targeting.js'\nimport type {\n PromptResponse,\n SubmitResponsePayload,\n} from '../types/response.js'\nimport type {\n FeedbackRecipient,\n InAppRecipient,\n RecipientList,\n RecipientPageQuery,\n SurveyRecipient,\n} from '../types/recipient.js'\nimport type {\n App,\n ApiToken,\n CreatedApiToken,\n CreatedApp,\n CreateApiTokenRequest,\n CreatedWriteKey,\n RotateWriteKeyRequest,\n RotateWriteKeyResponse,\n User,\n Workspace,\n WorkspaceWithRole,\n WorkspaceInvite,\n WorkspaceMember,\n WorkspaceRole,\n WriteKey,\n AcceptWorkspaceInviteRequest,\n AcceptWorkspaceInviteResponse,\n AppOnboardingStatus,\n DeferCurrentUserOnboardingRequest,\n OnboardingGoal,\n UpdateAppOnboardingRequest,\n} from '../types/workspace.js'\nimport type { Consent } from '../types/sdk.js'\nimport type {\n ConnectIntegrationRequest,\n IntegrationDeliveriesResponse,\n IntegrationSummary,\n IntegrationTestResult,\n UpdateIntegrationRequest,\n} from '../types/integration.js'\nimport type {\n AdminWorkspaceSummary,\n BillingCheckoutRequest,\n BillingCheckoutResponse,\n BillingPlan,\n BillingUsage,\n BillingTrial,\n BillingPeriod,\n BillingOfferAvailability,\n BillingChangePlanRequest,\n BillingChangePlanResponse,\n Subscription,\n} from '../types/billing.js'\nimport type {\n AdminActivityEntry,\n AdminDashboardUserListRequest,\n AdminDashboardUserListResponse,\n AdminDeletionJob,\n AdminCustomerDetail,\n AdminCustomerListRequest,\n AdminCustomerListResponse,\n AdminSession,\n DeleteAdminDashboardUserRequest,\n DeleteAdminWorkspaceRequest,\n CreateWorkspacePlanGrantRequest,\n EffectivePlanAccess,\n ExtendWorkspacePlanGrantRequest,\n RevokeWorkspacePlanGrantRequest,\n WorkspacePlanGrant,\n GlobalFeatureFlag,\n ProductFeatureFlags,\n PublicSignupStatus,\n UpdateGlobalFeatureFlagRequest,\n} from '../types/admin.js'\nimport type {\n Campaign,\n CampaignAnalytics,\n CampaignWithVariants,\n CreateCampaignRequest,\n InvalidateDeviceTokenPayload,\n PushCredentialSummary,\n PushTransactionalRequest,\n RegisterDeviceTokenPayload,\n UpdateCampaignRequest,\n UpdateDeviceTokenPayload,\n UploadCredentialRequest,\n} from '../types/campaign.js'\nimport type {\n ArmedSurvey,\n CloneSurveyFromTemplateRequest,\n CompleteSurveyAttemptRequest,\n CreateSurveyAttemptRequest,\n CreateSurveyAttemptResponse,\n CreateSurveyRequest,\n ResolveSurveyLinkRequest,\n ResolveSurveyLinkResponse,\n SubmitSurveyAnswersRequest,\n SurveyAnalytics,\n SurveyCampaign,\n SurveyCampaignWithFlow,\n SurveyResponseRecord,\n SurveyShareLinkResponse,\n SurveySummary,\n SurveyTemplate,\n UpdateSurveyAttemptProgressRequest,\n UpdateSurveyRequest,\n} from '../types/survey.js'\nimport type {\n ArmedInAppMessage,\n CreateInAppMessageRequest,\n InAppMessage,\n InAppMessageAnalytics,\n UpdateInAppMessageRequest,\n} from '../types/inapp-message.js'\nimport type {\n Request,\n RequestStatus,\n RequestSummary,\n RequestDetail,\n RequestSearchResult,\n RequestVote,\n RequestFollow,\n GetRequestsOptions,\n GetRequestsResult,\n SubmitRequestPayload,\n RequestSettings,\n UpdateRequestSettingsRequest,\n UpdateRequestStatusRequest,\n UpdateRequestResponseRequest,\n UpdateRequestModerationRequest,\n MergeRequestsRequest,\n BulkUpdateStatusRequest,\n ListRequestsQuery,\n RequestUpvoterSegmentBreakdown,\n RequestTimelineEntry,\n RequestAnalytics,\n RequestPublicSummary,\n RequestPublicDetail,\n RequestPublicBranding,\n RequestComment,\n PostCommentPayload,\n EditCommentPayload,\n} from '../types/request.js'\nimport type {\n AppBrandSettings,\n BrandTheme,\n CreateBrandThemeRequest,\n ThemeMode,\n UpdateBrandThemeDefaultsRequest,\n UpdateBrandThemeRequest,\n} from '../types/brand.js'\n\n// ---------- auth ----------\n// Sign-in / sign-up / sign-out are handled by WorkOS AuthKit on the\n// dashboard side. The API exposes only /v1/me to surface the locally\n// mapped user + workspace state.\n\nexport interface UpdateCurrentUserRequest {\n readonly name?: string\n}\n\n// ---------- workspaces ----------\n\nexport interface CreateWorkspaceRequest {\n readonly name: string\n readonly slug?: string\n readonly timezone?: string\n}\n\nexport interface UpdateWorkspaceRequest {\n readonly name?: string\n readonly timezone?: string\n}\n\nexport interface InviteMemberRequest {\n readonly email: string\n readonly role: Exclude<WorkspaceRole, 'owner'>\n}\n\n// ---------- apps ----------\n\nexport interface CreateAppRequest {\n readonly setupMode?: 'sdk' | 'portal'\n readonly portal?: Portal.CreateAppPortal\n readonly webConfig?: App['webConfig']\n readonly name: string\n readonly slug?: string\n readonly platforms: App['platforms']\n readonly environment?: WriteKey['environment']\n readonly onboardingGoal?: OnboardingGoal\n}\n\nexport interface UpdateAppRequest {\n readonly webConfig?: App['webConfig']\n readonly name?: string\n readonly platforms?: App['platforms']\n readonly piiAllowList?: ReadonlyArray<string>\n readonly lifecycleEventsEnabled?: boolean\n}\n\nexport interface CreateWriteKeyRequest {\n readonly label?: string\n readonly environment?: WriteKey['environment']\n}\n\n// ---------- event definitions ----------\n\nexport interface RegisterEventDefinitionRequest {\n readonly name: string\n readonly description?: string\n readonly properties?: ReadonlyArray<EventPropertySchema>\n}\n\nexport interface UpdateEventDefinitionRequest {\n readonly description?: string\n readonly properties?: ReadonlyArray<EventPropertySchema>\n readonly status?: EventDefinition['status']\n}\n\n// ---------- segments ----------\n\nexport interface CreateSegmentRequest {\n readonly name: string\n readonly description?: string\n // New segments persist `definition: AudienceSpec` (the same shape\n // feedback / surveys / push targeting use). `rules: SegmentDsl` is\n // accepted for back-compat — exactly one of the two must be set.\n readonly definition?: AudienceSpec\n readonly rules?: SegmentDsl\n readonly refreshMode?: 'hot' | 'cold' | 'manual'\n}\n\nexport interface AppUserSummary {\n readonly origin?: 'sdk' | 'portal'\n readonly subjectId: string\n readonly anonymousId: string\n readonly anonymousIds: ReadonlyArray<string>\n readonly externalId?: string | null\n readonly firstSeenAt: string\n readonly lastSeenAt: string\n readonly eventCount?: number\n readonly topProperties?: Readonly<\n Record<string, string | number | boolean | null>\n >\n // Latest device-context fields surfaced from usergist.events (argMax\n // by occurred_at). Useful in the users list + user detail card.\n readonly country?: string | null\n readonly platform?: string | null\n}\n\nexport interface AppUserDetail {\n readonly origin?: 'sdk' | 'portal'\n readonly subjectId: string\n readonly anonymousId: string\n readonly anonymousIds: ReadonlyArray<string>\n readonly externalId?: string | null\n readonly firstSeenAt: string\n readonly lastSeenAt: string\n readonly properties: Readonly<\n Record<string, string | number | boolean | null>\n >\n readonly eventCount: number\n readonly country?: string | null\n readonly platform?: string | null\n}\n\nexport interface AppUserEvent {\n readonly id: string\n readonly name: string\n readonly occurredAt: string\n readonly properties: Readonly<Record<string, unknown>>\n readonly platform?: string | null\n readonly appVersion?: string | null\n}\n\nexport interface PaginatedAppUsers {\n readonly items: ReadonlyArray<AppUserSummary>\n readonly total: number\n readonly nextCursor: string | null\n}\n\nexport interface PaginatedAppUserEvents {\n readonly items: ReadonlyArray<AppUserEvent>\n readonly nextCursor: string | null\n}\n\nexport interface ListUsersQuery {\n readonly q?: string\n readonly identityKind?: 'anonymous' | 'identified'\n readonly origin?: 'sdk' | 'portal'\n readonly cursor?: string\n readonly limit?: number\n}\n\nexport interface ListUserEventsQuery {\n readonly from?: string\n readonly to?: string\n readonly cursor?: string\n readonly limit?: number\n}\n\nexport interface GenerateSegmentRulesRequest {\n readonly name?: string\n readonly description?: string\n}\n\nexport interface GenerateSegmentRulesResponse {\n readonly rules: SegmentDsl\n readonly rationale: string\n}\n\nexport interface GenerateSegmentNameRequest {\n readonly rules: SegmentDsl\n}\n\nexport interface GenerateSegmentNameResponse {\n readonly name: string\n readonly description: string\n}\n\nexport interface SegmentPreview {\n readonly estimatedCount: number\n readonly sampleUsers: ReadonlyArray<{\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly properties: Record<string, unknown>\n }>\n}\n\n// ---------- prompts ----------\n\nexport interface CreatePromptRequest {\n readonly personalization?:\n | import('../types/personalization.js').PersonalizationSpec\n | null\n readonly name: string\n readonly triggerEventName: string\n readonly segmentId?: string | null\n readonly questions: ReadonlyArray<Question>\n readonly deliveryPlatforms?: ReadonlyArray<\n import('../types/web.js').DeliveryPlatform\n >\n readonly webPresentation?:\n | import('../types/web.js').WebPresentation | null\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly frequency?: FrequencyCaps\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: PromptStatus\n}\n\nexport interface UpdatePromptRequest {\n readonly personalization?:\n | import('../types/personalization.js').PersonalizationSpec\n | null\n readonly name?: string\n readonly triggerEventName?: string\n readonly segmentId?: string | null\n readonly questions?: ReadonlyArray<Question>\n readonly deliveryPlatforms?: ReadonlyArray<\n import('../types/web.js').DeliveryPlatform\n >\n readonly webPresentation?:\n | import('../types/web.js').WebPresentation | null\n readonly themeMode?: ThemeMode\n readonly theme?: PromptTheme\n readonly frequency?: FrequencyCaps\n readonly startAt?: string | null\n readonly endAt?: string | null\n readonly status?: PromptStatus\n}\n\nexport interface TestPromptOnDeviceRequest {\n readonly anonymousId: string\n}\n\n// ---------- responses ----------\n\nexport interface ListResponsesQuery {\n readonly promptId?: string\n readonly from?: string\n readonly to?: string\n readonly page?: number\n readonly limit?: number\n readonly segmentId?: string\n}\n\nexport interface PromptAnalytics {\n readonly promptId: string\n readonly shown: number\n readonly responded: number\n readonly dismissed: number\n readonly completionRate: number\n readonly perQuestion: ReadonlyArray<{\n readonly questionId: string\n readonly type: Question['type']\n readonly distribution: Readonly<Record<string, number>>\n readonly average?: number\n readonly npsScore?: number\n }>\n}\n\n// ---------- SDK-facing ----------\n\nexport interface SdkIngestRequest extends IngestBatch {\n /** Resolve these persisted trigger events in this request, without waiting\n * for background projection and instruction polling. */\n readonly delivery?: {\n readonly eventIds: ReadonlyArray<string>\n readonly clientId?: string\n readonly screenName?: string\n }\n}\n\nexport interface SdkDeliveryInstruction {\n readonly id: number\n readonly type: string\n readonly payload: Readonly<Record<string, unknown>>\n readonly emittedAt: string\n readonly expiresAt: string\n}\n\nexport interface SdkIngestResponse {\n readonly accepted: number\n readonly rejected: number\n readonly errors?: ReadonlyArray<{ index: number; reason: string }>\n readonly instructions?: ReadonlyArray<SdkDeliveryInstruction>\n}\n\nexport interface SdkArmedTriggersResponse {\n /** Event-name hints only; personalized content is resolved on the server. */\n readonly deliveryEventNames?: ReadonlyArray<string>\n readonly triggers: ReadonlyArray<ArmedTrigger>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkArmedInAppMessagesResponse {\n readonly deliveryEventNames?: ReadonlyArray<string>\n readonly messages: ReadonlyArray<ArmedInAppMessage>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkArmedSurveysResponse {\n readonly deliveryEventNames?: ReadonlyArray<string>\n readonly surveys: ReadonlyArray<ArmedSurvey>\n readonly serverTime: string\n readonly nextSyncMs: number\n}\n\nexport interface SdkConsentPayload {\n readonly anonymousId: string\n readonly externalId?: string | null\n readonly purposes: Consent\n readonly version: number\n readonly effectiveAt: string\n}\n\nexport interface SdkSessionResponse {\n readonly subjectToken: string\n readonly subjectId: string\n readonly expiresAt: string\n}\n\nexport interface SdkIdentifyPayload {\n readonly anonymousId: string\n readonly externalId: string\n readonly properties?: Record<string, string | number | boolean | null>\n}\n\nexport interface RegisterSdkClientRequest {\n readonly anonymousId: string\n readonly instanceId: string\n readonly platform: import('../types/web.js').DeliveryPlatform\n readonly sdkVersion: string\n readonly protocolVersion: 2\n readonly capabilities?: ReadonlyArray<string>\n readonly screenName?: string | null\n}\nexport interface SdkDeliveryInstruction {\n readonly id: number\n readonly type: string\n readonly payload: Readonly<Record<string, unknown>>\n readonly emittedAt: string\n readonly expiresAt: string\n}\nexport interface AuthorizePresentationRequest {\n readonly clientId: string\n readonly pillar: 'feedback' | 'survey' | 'inapp'\n readonly campaignId: string\n readonly idempotencyKey: string\n readonly instructionId?: number\n readonly screenName?: string\n}\nexport type AuthorizePresentationResponse =\n | {\n readonly status: 'authorized'\n readonly presentationId: string\n readonly content:\n | Prompt\n | import('../types/survey.js').SurveyCampaignWithFlow\n | import('../types/inapp-message.js').InAppMessage\n }\n | { readonly status: 'unavailable' | 'consent_required' }\n\n// ---------- GDPR ----------\n\nexport interface GdprDeleteRequest {\n readonly externalId?: string\n readonly anonymousId?: string\n}\n\nexport interface GdprExportRequest {\n readonly externalId?: string\n readonly anonymousId?: string\n}\n\n// ---------- endpoint map ----------\n// Keys are method+path. Values are { request, response } for typing.\n// This is kept as a literal object so it can be walked at build time\n// to generate a typed client and OpenAPI spec.\n\nexport type Endpoint<Req, Res> = { readonly __req?: Req\n readonly __res: Res }\n\nexport const endpoints = {\n 'GET /v1/apps/:appId/search': {} as Endpoint<\n Mcp.AppSearchQuery,\n Mcp.AppSearchResult\n >,\n 'POST /v1/apps/:appId/delivery-diagnostics': {} as Endpoint<\n Mcp.DeliveryDiagnosticInput,\n Mcp.DeliveryDiagnosticResult\n >,\n 'GET /v1/workspaces/:wid/portal': {} as Endpoint<void, Portal.PortalSettings>,\n 'PUT /v1/workspaces/:wid/portal': {} as Endpoint<\n Portal.UpdatePortalRequest,\n Portal.PortalSettings\n >,\n 'GET /v1/workspaces/:wid/portal/slug-available': {} as Endpoint<\n { slug: string },\n { available: boolean }\n >,\n 'PUT /v1/workspaces/:wid/portal/apps/:appId': {} as Endpoint<\n Portal.UpdatePortalAppRequest,\n Portal.PortalSettings\n >,\n 'POST /v1/workspaces/:wid/portal/publish': {} as Endpoint<\n void,\n Portal.PortalSettings\n >,\n 'POST /v1/workspaces/:wid/portal/unpublish': {} as Endpoint<\n void,\n Portal.PortalSettings\n >,\n 'GET /v1/workspaces/:wid/portal/preview/:appId': {} as Endpoint<\n Portal.PortalRequestQuery,\n Portal.PortalRequestList\n >,\n 'PATCH /v1/apps/:appId/requests/portal-visibility': {} as Endpoint<\n { ids: readonly string[]; visible: boolean },\n { updated: number }\n >,\n 'GET /v1/portal/:portalSlug': {} as Endpoint<void, Portal.PublicPortal>,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/requests': {} as Endpoint<\n Portal.PortalRequestQuery,\n Portal.PortalRequestList\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/requests/counts': {} as Endpoint<\n void,\n Portal.PortalRequestCounts\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId':\n {} as Endpoint<void, Portal.PortalRequest>,\n 'POST /v1/portal/:portalSlug/auth/start': {} as Endpoint<\n Portal.PortalAuthStart,\n { sent: true; retryAfter: number }\n >,\n 'POST /v1/portal/:portalSlug/auth/verify': {} as Endpoint<\n Portal.PortalAuthVerify,\n Portal.PortalSession & { sessionToken: string }\n >,\n 'GET /v1/portal/:portalSlug/session': {} as Endpoint<\n void,\n Portal.PortalSession | null\n >,\n 'DELETE /v1/portal/:portalSlug/session': {} as Endpoint<\n void,\n { signedOut: true }\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/votes': {} as Endpoint<\n { ids: string },\n { votedIds: string[] }\n >,\n 'POST /v1/portal/:portalSlug/apps/:appSlug/requests': {} as Endpoint<\n Portal.PortalSubmission,\n Portal.PortalRequest\n >,\n 'PUT /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId/vote':\n {} as Endpoint<\n Portal.PortalVote,\n { upvoted: boolean; upvoteCount: number }\n >,\n 'POST /v1/sdk/clients': {} as Endpoint<\n RegisterSdkClientRequest,\n { clientId: string; protocolVersion: 2 }\n >,\n 'POST /v1/sdk/clients/:id/end': {} as Endpoint<\n Record<string, never>,\n { ok: true }\n >,\n 'GET /v1/sdk/clients/:id/instructions': {} as Endpoint<\n void,\n { instructions: ReadonlyArray<SdkDeliveryInstruction> }\n >,\n 'POST /v1/sdk/presentations/authorize': {} as Endpoint<\n AuthorizePresentationRequest,\n AuthorizePresentationResponse\n >,\n 'POST /v1/sdk/presentations/:id/receipt': {} as Endpoint<\n {\n clientId: string\n event: 'shown' | 'dismissed' | 'completed' | 'cta_clicked'\n },\n { recorded: boolean }\n >,\n 'GET /v1/me': {} as Endpoint<\n void,\n { user: User; workspaces: ReadonlyArray<WorkspaceWithRole> }\n >,\n 'PATCH /v1/me': {} as Endpoint<UpdateCurrentUserRequest, User>,\n 'PATCH /v1/me/onboarding': {} as Endpoint<\n DeferCurrentUserOnboardingRequest,\n User\n >,\n 'GET /v1/features': {} as Endpoint<void, ProductFeatureFlags>,\n 'GET /v1/signup-status': {} as Endpoint<void, PublicSignupStatus>,\n\n 'GET /v1/workspaces': {} as Endpoint<void, ReadonlyArray<Workspace>>,\n 'POST /v1/workspaces': {} as Endpoint<CreateWorkspaceRequest, Workspace>,\n 'PATCH /v1/workspaces/:wid': {} as Endpoint<\n UpdateWorkspaceRequest,\n Workspace\n >,\n 'GET /v1/workspaces/:wid/members': {} as Endpoint<\n void,\n ReadonlyArray<WorkspaceMember>\n >,\n 'GET /v1/workspaces/:wid/invites': {} as Endpoint<\n void,\n ReadonlyArray<WorkspaceInvite>\n >,\n 'POST /v1/workspaces/:wid/invites': {} as Endpoint<\n InviteMemberRequest,\n { queued: true }\n >,\n 'DELETE /v1/workspaces/:wid/invites/:inviteId': {} as Endpoint<\n void,\n { revoked: true }\n >,\n 'POST /v1/invites/accept': {} as Endpoint<\n AcceptWorkspaceInviteRequest,\n AcceptWorkspaceInviteResponse\n >,\n\n 'GET /v1/workspaces/:wid/apps': {} as Endpoint<void, ReadonlyArray<App>>,\n 'POST /v1/workspaces/:wid/apps': {} as Endpoint<CreateAppRequest, CreatedApp>,\n 'GET /v1/workspaces/:wid/api-tokens': {} as Endpoint<\n void,\n ReadonlyArray<ApiToken>\n >,\n 'GET /v1/workspaces/:wid/ai-connections': {} as Endpoint<\n void,\n Mcp.McpConnectionSettings\n >,\n 'PATCH /v1/workspaces/:wid/ai-connections/:id': {} as Endpoint<\n Mcp.McpGrant & { policyVersion: number },\n Mcp.McpConnection\n >,\n 'POST /v1/workspaces/:wid/ai-connections/:id/revoke': {} as Endpoint<\n void,\n { revoked: boolean }\n >,\n 'GET /v1/workspaces/:wid/ai-connections/:id/activity': {} as Endpoint<\n void,\n { items: Mcp.McpActivity[]; limit: number }\n >,\n 'POST /v1/mcp/consent': {} as Endpoint<\n Mcp.McpGrant & { workspaceId: string; externalAuthId: string },\n { redirectUri: string }\n >,\n 'POST /v1/workspaces/:wid/api-tokens': {} as Endpoint<\n CreateApiTokenRequest,\n CreatedApiToken\n >,\n 'DELETE /v1/workspaces/:wid/api-tokens/:tokenId': {} as Endpoint<\n void,\n { revoked: true }\n >,\n 'GET /v1/apps/:appId': {} as Endpoint<void, App>,\n 'PATCH /v1/apps/:appId': {} as Endpoint<UpdateAppRequest, App>,\n 'DELETE /v1/apps/:appId': {} as Endpoint<void, { ok: true }>,\n 'GET /v1/apps/:appId/onboarding': {} as Endpoint<void, AppOnboardingStatus>,\n 'PATCH /v1/apps/:appId/onboarding': {} as Endpoint<\n UpdateAppOnboardingRequest,\n AppOnboardingStatus\n >,\n 'POST /v1/apps/:appId/sdk/subject-tokens': {} as Endpoint<\n { externalId: string },\n SdkSessionResponse\n >,\n\n // ---------- outbound analytics integrations ----------\n 'GET /v1/apps/:appId/integrations': {} as Endpoint<\n void,\n ReadonlyArray<IntegrationSummary>\n >,\n 'PUT /v1/apps/:appId/integrations/:provider': {} as Endpoint<\n ConnectIntegrationRequest,\n { integration: IntegrationSummary; test: IntegrationTestResult }\n >,\n 'PATCH /v1/apps/:appId/integrations/:provider': {} as Endpoint<\n UpdateIntegrationRequest,\n IntegrationSummary\n >,\n 'POST /v1/apps/:appId/integrations/:provider/test': {} as Endpoint<\n Record<string, never>,\n IntegrationTestResult\n >,\n 'POST /v1/apps/:appId/integrations/:provider/pause': {} as Endpoint<\n Record<string, never>,\n IntegrationSummary\n >,\n 'POST /v1/apps/:appId/integrations/:provider/resume': {} as Endpoint<\n Record<string, never>,\n IntegrationSummary\n >,\n 'DELETE /v1/apps/:appId/integrations/:provider': {} as Endpoint<\n void,\n { disconnected: true }\n >,\n 'GET /v1/apps/:appId/integrations/:provider/deliveries': {} as Endpoint<\n { cursor?: string; limit?: number },\n IntegrationDeliveriesResponse\n >,\n\n 'GET /v1/apps/:appId/brand-settings': {} as Endpoint<void, AppBrandSettings>,\n 'POST /v1/apps/:appId/brand-themes': {} as Endpoint<\n CreateBrandThemeRequest,\n BrandTheme\n >,\n 'PATCH /v1/apps/:appId/brand-themes/:themeId': {} as Endpoint<\n UpdateBrandThemeRequest,\n BrandTheme\n >,\n 'DELETE /v1/apps/:appId/brand-themes/:themeId': {} as Endpoint<\n void,\n { ok: true }\n >,\n 'PUT /v1/apps/:appId/brand-theme-defaults': {} as Endpoint<\n UpdateBrandThemeDefaultsRequest,\n AppBrandSettings\n >,\n\n 'GET /v1/apps/:appId/write-keys': {} as Endpoint<\n void,\n ReadonlyArray<WriteKey>\n >,\n 'POST /v1/apps/:appId/write-keys': {} as Endpoint<\n CreateWriteKeyRequest,\n CreatedWriteKey\n >,\n 'POST /v1/apps/:appId/write-keys/:keyId/rotate': {} as Endpoint<\n RotateWriteKeyRequest,\n RotateWriteKeyResponse\n >,\n 'DELETE /v1/apps/:appId/write-keys/:keyId': {} as Endpoint<\n void,\n { ok: true }\n >,\n\n 'GET /v1/apps/:appId/event-definitions': {} as Endpoint<\n void,\n ReadonlyArray<EventDefinition>\n >,\n 'POST /v1/apps/:appId/event-definitions': {} as Endpoint<\n RegisterEventDefinitionRequest,\n EventDefinition\n >,\n 'PATCH /v1/apps/:appId/event-definitions/:defId': {} as Endpoint<\n UpdateEventDefinitionRequest,\n EventDefinition\n >,\n\n 'GET /v1/apps/:appId/segments': {} as Endpoint<void, ReadonlyArray<Segment>>,\n 'POST /v1/apps/:appId/segments': {} as Endpoint<\n CreateSegmentRequest,\n Segment\n >,\n 'GET /v1/apps/:appId/segments/:segId': {} as Endpoint<void, Segment>,\n 'PATCH /v1/apps/:appId/segments/:segId': {} as Endpoint<\n Partial<CreateSegmentRequest>,\n Segment\n >,\n 'DELETE /v1/apps/:appId/segments/:segId': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/segments/:segId/preview': {} as Endpoint<\n void,\n SegmentPreview\n >,\n 'POST /v1/apps/:appId/segments/:segId/rebuild': {} as Endpoint<\n void,\n { scheduled: true }\n >,\n 'GET /v1/apps/:appId/users': {} as Endpoint<\n ListUsersQuery,\n PaginatedAppUsers\n >,\n 'GET /v1/apps/:appId/users/:anonymousId': {} as Endpoint<void, AppUserDetail>,\n 'GET /v1/apps/:appId/users/:anonymousId/events': {} as Endpoint<\n ListUserEventsQuery,\n PaginatedAppUserEvents\n >,\n 'GET /v1/apps/:appId/users/:anonymousId/push': {} as Endpoint<\n void,\n {\n consent: {\n push: boolean\n feedback: boolean\n analytics: boolean\n recordedAt: string | null\n }\n devices: ReadonlyArray<{\n id: string\n platform: 'ios' | 'android'\n environment: 'production' | 'sandbox'\n language: string | null\n timezone: string | null\n appVersion: string | null\n sdkVersion: string | null\n optIn: boolean\n lastSeenAt: string\n invalidatedAt: string | null\n createdAt: string\n }>\n }\n >,\n 'POST /v1/apps/:appId/users/:anonymousId/push/test-send': {} as Endpoint<\n { title: string; body: string; imageUrl?: string; deepLink?: string },\n {\n dispatched: number\n held: number\n dropped: number\n errors: ReadonlyArray<{ reason: string }>\n }\n >,\n\n 'POST /v1/apps/:appId/segments/ai-generate-rules': {} as Endpoint<\n GenerateSegmentRulesRequest,\n GenerateSegmentRulesResponse\n >,\n 'POST /v1/apps/:appId/segments/ai-generate-name': {} as Endpoint<\n GenerateSegmentNameRequest,\n GenerateSegmentNameResponse\n >,\n\n 'GET /v1/apps/:appId/prompts': {} as Endpoint<void, ReadonlyArray<Prompt>>,\n 'POST /v1/apps/:appId/prompts': {} as Endpoint<CreatePromptRequest, Prompt>,\n 'GET /v1/apps/:appId/prompts/:promptId': {} as Endpoint<void, Prompt>,\n 'PATCH /v1/apps/:appId/prompts/:promptId': {} as Endpoint<\n UpdatePromptRequest,\n Prompt\n >,\n 'DELETE /v1/apps/:appId/prompts/:promptId': {} as Endpoint<\n void,\n { ok: true }\n >,\n 'POST /v1/apps/:appId/prompts/:promptId/test-on-device': {} as Endpoint<\n TestPromptOnDeviceRequest,\n { dispatched: true }\n >,\n\n 'GET /v1/apps/:appId/prompts/:promptId/responses': {} as Endpoint<\n ListResponsesQuery,\n ReadonlyArray<PromptResponse>\n >,\n 'GET /v1/apps/:appId/prompts/:promptId/recipients': {} as Endpoint<\n RecipientPageQuery,\n RecipientList<FeedbackRecipient>\n >,\n 'GET /v1/apps/:appId/prompts/:promptId/analytics': {} as Endpoint<\n { from?: string; to?: string },\n PromptAnalytics\n >,\n\n // App-level analytics rollup — daily (or hourly for 24h) buckets across all\n // four pillars. Used by the dashboard overview to render \"last N days\"\n // performance charts without spamming per-resource analytics endpoints.\n 'GET /v1/apps/:appId/analytics/overview': {} as Endpoint<\n { range?: '24h' | '7d' | '30d' },\n {\n readonly range: '24h' | '7d' | '30d'\n readonly bucket: 'hour' | 'day'\n readonly buckets: ReadonlyArray<{\n readonly bucket: string\n readonly push: { sent: number; opened: number; clicked: number }\n readonly inapp: {\n impressions: number\n dismissed: number\n ctaClicked: number\n }\n readonly prompts: {\n shown: number\n responded: number\n dismissed: number\n }\n readonly surveys: { started: number; completed: number }\n }>\n readonly totals: {\n readonly push: { sent: number; opened: number; clicked: number }\n readonly inapp: {\n impressions: number\n dismissed: number\n ctaClicked: number\n }\n readonly prompts: {\n shown: number\n responded: number\n dismissed: number\n }\n readonly surveys: { started: number; completed: number }\n }\n }\n >,\n\n // Inline AudienceSpec preview — count of users matching the (unsaved) spec.\n // Used by the dashboard's TARGET step to power the live count badge.\n 'POST /v1/apps/:appId/audience/preview': {} as Endpoint<\n import('../types/targeting.js').AudienceSpec,\n { matching: number; sampleUsers: ReadonlyArray<AppUserSummary> }\n >,\n\n // SDK-facing (authenticated via write key)\n 'POST /v1/sdk/ingest': {} as Endpoint<SdkIngestRequest, SdkIngestResponse>,\n 'GET /v1/sdk/armed-triggers': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n SdkArmedTriggersResponse\n >,\n 'POST /v1/sdk/consent': {} as Endpoint<SdkConsentPayload, { ok: true }>,\n 'PATCH /v1/apps/:appId/users/properties': {} as Endpoint<\n {\n subject: import('../types/mcp.js').SubjectRef\n update: import('../types/personalization.js').UserPropertiesUpdate\n },\n { applied: boolean; filteredKeys: string[] }\n >,\n 'POST /v1/sdk/user-properties': {} as Endpoint<\n import('../types/personalization.js').UserPropertiesUpdate & {\n anonymousId: string\n },\n { applied: boolean; filteredKeys: string[] }\n >,\n 'GET /v1/apps/:appId/personalization/fields': {} as Endpoint<\n { q?: string; eventName?: string },\n {\n userProperties: ReadonlyArray<{\n key: string\n label: string\n type: string\n source: string\n available: boolean\n }>\n events: ReadonlyArray<{\n name: string\n description: string | null\n status: string\n properties: ReadonlyArray<{\n key: string\n label: string\n type: string\n source: string\n available: boolean\n }>\n }>\n retentionDays: number\n }\n >,\n 'POST /v1/apps/:appId/personalization/preview': {} as Endpoint<\n {\n surface: import('../types/personalization.js').PersonalizationSurface\n content: Record<string, unknown>\n subject?: import('../types/mcp.js').SubjectRef\n triggerEventId?: string\n examples?: Record<\n string,\n import('../types/personalization.js').PersonalizationSourceValue\n >\n data?: Record<\n string,\n import('../types/personalization.js').PersonalizationScalar\n >\n },\n {\n content: Record<string, unknown>\n resolution:\n | import('../types/personalization.js').PersonalizationResolution\n | null\n example: boolean\n previewId?: string\n subjectId?: string\n }\n >,\n 'POST /v1/sdk/identify': {} as Endpoint<SdkIdentifyPayload, { ok: true }>,\n 'POST /v1/sdk/responses': {} as Endpoint<SubmitResponsePayload, { ok: true }>,\n\n // GDPR\n 'POST /v1/apps/:appId/gdpr/delete': {} as Endpoint<\n GdprDeleteRequest,\n { scheduled: true }\n >,\n 'POST /v1/apps/:appId/gdpr/export': {} as Endpoint<\n GdprExportRequest,\n { scheduled: true; exportId: string }\n >,\n 'GET /v1/apps/:appId/gdpr/exports/:exportId': {} as Endpoint<\n void,\n {\n status: 'pending' | 'running' | 'completed' | 'failed'\n downloadUrl?: string\n }\n >,\n\n // Campaigns (push)\n 'GET /v1/apps/:appId/campaigns': {} as Endpoint<\n void,\n ReadonlyArray<Campaign>\n >,\n 'POST /v1/apps/:appId/campaigns': {} as Endpoint<\n CreateCampaignRequest,\n CampaignWithVariants\n >,\n 'GET /v1/apps/:appId/campaigns/:cid': {} as Endpoint<\n void,\n CampaignWithVariants\n >,\n 'PATCH /v1/apps/:appId/campaigns/:cid': {} as Endpoint<\n UpdateCampaignRequest,\n CampaignWithVariants\n >,\n 'DELETE /v1/apps/:appId/campaigns/:cid': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/campaigns/:cid/activate': {} as Endpoint<\n void,\n Campaign\n >,\n 'POST /v1/apps/:appId/campaigns/:cid/pause': {} as Endpoint<void, Campaign>,\n 'POST /v1/apps/:appId/campaigns/:cid/resend': {} as Endpoint<\n void,\n { queued: number }\n >,\n 'POST /v1/apps/:appId/campaigns/:cid/preview': {} as Endpoint<\n { anonymousId?: string; mergeTags?: Record<string, unknown> },\n ReadonlyArray<{\n variantId: string\n language: string | null\n title: string\n body: string\n }>\n >,\n 'POST /v1/apps/:appId/campaigns/:cid/test-send': {} as Endpoint<\n { anonymousId: string },\n { queued: true }\n >,\n 'GET /v1/apps/:appId/campaigns/:cid/analytics': {} as Endpoint<\n { from?: string; to?: string },\n CampaignAnalytics\n >,\n 'GET /v1/apps/:appId/campaigns/:cid/deliveries': {} as Endpoint<\n { limit?: number },\n ReadonlyArray<{\n delivery_id: string\n variant_id: string\n language: string | null\n anonymous_id: string\n external_id: string | null\n platform: string\n sent_at: string\n delivered_at: string | null\n displayed_at: string | null\n opened_at: string | null\n dismissed_at: string | null\n clicked_at: string | null\n error_code: string | null\n bounce_class: string\n provider_latency_ms: number\n }>\n >,\n\n // Push credentials\n 'GET /v1/apps/:appId/push/credentials': {} as Endpoint<\n void,\n ReadonlyArray<PushCredentialSummary>\n >,\n 'POST /v1/apps/:appId/push/credentials': {} as Endpoint<\n UploadCredentialRequest,\n PushCredentialSummary\n >,\n 'DELETE /v1/apps/:appId/push/credentials/:credId': {} as Endpoint<\n void,\n { ok: true }\n >,\n 'GET /v1/apps/:appId/push/stats': {} as Endpoint<\n void,\n {\n credentials: { ios: boolean; android: boolean }\n deviceTokens: { total: number; ios: number; android: number }\n campaignCount: number\n }\n >,\n 'GET /v1/apps/:appId/push/audience-estimate': {} as Endpoint<\n { segmentId?: string },\n {\n audienceSize: number\n withPush: number\n iosCount: number\n androidCount: number\n }\n >,\n 'GET /v1/apps/:appId/push/reachability': {} as Endpoint<\n void,\n {\n optedIn: number\n reachable: number\n unreachable: number\n bouncedToday: number\n pingedToday: number\n }\n >,\n\n // Push channels (per-app NotificationChannel registry / iOS category id)\n 'GET /v1/apps/:appId/push/channels': {} as Endpoint<\n void,\n {\n channels: ReadonlyArray<{\n readonly app_id: string\n readonly channel_id: string\n readonly display_name: string\n readonly description: string | null\n readonly importance: number\n readonly default_sound: string | null\n readonly default_vibrate: boolean\n readonly default_badge: boolean\n readonly category: string\n }>\n }\n >,\n 'PUT /v1/apps/:appId/push/channels': {} as Endpoint<\n {\n channelId: string\n displayName: string\n description?: string | null\n importance?: number\n defaultSound?: string | null\n defaultVibrate?: boolean\n defaultBadge?: boolean\n category?:\n | 'transactional' | 'marketing' | 'silent' | 'digest' | 'alert'\n },\n { saved: true }\n >,\n 'DELETE /v1/apps/:appId/push/channels/:channelId': {} as Endpoint<\n void,\n { archived: true }\n >,\n\n // Push outbound webhooks\n 'GET /v1/apps/:appId/push/webhooks': {} as Endpoint<\n void,\n {\n webhooks: ReadonlyArray<{\n id: string\n url: string\n event_types: ReadonlyArray<string>\n active: boolean\n description: string | null\n last_success_at: string | null\n last_failure_at: string | null\n last_failure_reason: string | null\n created_at: string\n updated_at: string\n }>\n }\n >,\n 'POST /v1/apps/:appId/push/webhooks': {} as Endpoint<\n {\n url: string\n eventTypes: ReadonlyArray<string>\n active?: boolean\n description?: string | null\n },\n { id: string; secret: string }\n >,\n 'PATCH /v1/apps/:appId/push/webhooks/:webhookId': {} as Endpoint<\n Partial<{\n url: string\n eventTypes: ReadonlyArray<string>\n active: boolean\n description: string | null\n }>,\n { saved: true }\n >,\n 'DELETE /v1/apps/:appId/push/webhooks/:webhookId': {} as Endpoint<\n void,\n { deleted: true }\n >,\n 'POST /v1/apps/:appId/push/webhooks/:webhookId/rotate': {} as Endpoint<\n void,\n { secret: string }\n >,\n 'POST /v1/apps/:appId/push/webhooks/:webhookId/test': {} as Endpoint<\n void,\n { success: boolean\n statusCode: number\n attempts: number\n error?: string }\n >,\n\n // Push device-token registration (SDK-facing, write-key auth)\n 'POST /v1/sdk/push/register-token': {} as Endpoint<\n RegisterDeviceTokenPayload,\n { registered: true } | { skipped: 'consent' }\n >,\n 'POST /v1/sdk/push/update-token': {} as Endpoint<\n UpdateDeviceTokenPayload,\n { updated: true }\n >,\n 'POST /v1/sdk/push/invalidate-token': {} as Endpoint<\n InvalidateDeviceTokenPayload,\n { invalidated: true }\n >,\n 'POST /v1/sdk/push/rebind': {} as Endpoint<\n { anonymousId: string; externalId: string; token: string },\n { rebound: boolean }\n >,\n 'POST /v1/sdk/push/app-open': {} as Endpoint<\n { anonymousId: string; occurredAt?: string },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/delivered': {} as Endpoint<\n {\n deliveryId: string\n occurredAt?: string\n attemptId?: string\n actionButton?: string\n },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/displayed': {} as Endpoint<\n {\n deliveryId: string\n occurredAt?: string\n attemptId?: string\n actionButton?: string\n },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/dismissed': {} as Endpoint<\n {\n deliveryId: string\n occurredAt?: string\n attemptId?: string\n actionButton?: string\n },\n { recorded: true }\n >,\n 'POST /v1/sdk/push/silent-ack': {} as Endpoint<\n { pingId: string; anonymousId: string; receivedAt?: string },\n { recorded: true; pingId: string }\n >,\n 'GET /v1/sdk/push/channels': {} as Endpoint<\n void,\n { channels: ReadonlyArray<unknown> }\n >,\n 'POST /v1/sdk/push/channels/subscription': {} as Endpoint<\n { anonymousId: string; channelId: string; subscribed: boolean },\n { saved: true }\n >,\n\n // Transactional push (server API token auth)\n 'POST /v1/apps/:appId/push/transactional': {} as Endpoint<\n PushTransactionalRequest,\n { queued: true; deliveryId: string; idempotent?: boolean }\n >,\n\n // Surveys — dashboard CRUD\n 'GET /v1/apps/:appId/surveys': {} as Endpoint<\n void,\n ReadonlyArray<SurveyCampaign>\n >,\n 'POST /v1/apps/:appId/surveys': {} as Endpoint<\n CreateSurveyRequest,\n SurveyCampaignWithFlow\n >,\n 'GET /v1/apps/:appId/surveys/:sid': {} as Endpoint<\n void,\n SurveyCampaignWithFlow\n >,\n 'PATCH /v1/apps/:appId/surveys/:sid': {} as Endpoint<\n UpdateSurveyRequest,\n SurveyCampaignWithFlow\n >,\n 'DELETE /v1/apps/:appId/surveys/:sid': {} as Endpoint<void, { ok: true }>,\n 'POST /v1/apps/:appId/surveys/:sid/activate': {} as Endpoint<\n void,\n SurveyCampaign\n >,\n 'POST /v1/apps/:appId/surveys/:sid/pause': {} as Endpoint<\n void,\n SurveyCampaign\n >,\n 'POST /v1/apps/:appId/surveys/:sid/archive': {} as Endpoint<\n void,\n SurveyCampaign\n >,\n 'POST /v1/apps/:appId/surveys/:sid/preview': {} as Endpoint<\n {\n anonymousId?: string\n mergeTags?: Record<string, unknown>\n language?: string\n },\n SurveyCampaignWithFlow\n >,\n 'POST /v1/apps/:appId/surveys/:sid/test-on-device': {} as Endpoint<\n { anonymousId: string },\n { dispatched: true }\n >,\n 'GET /v1/apps/:appId/surveys/:sid/analytics': {} as Endpoint<\n { from?: string; to?: string },\n SurveyAnalytics\n >,\n 'GET /v1/apps/:appId/surveys/:sid/responses': {} as Endpoint<\n {\n from?: string\n to?: string\n page?: number\n limit?: number\n segmentId?: string\n language?: string\n },\n ReadonlyArray<SurveyResponseRecord>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/recipients': {} as Endpoint<\n RecipientPageQuery,\n RecipientList<SurveyRecipient>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/attempts': {} as Endpoint<\n void,\n ReadonlyArray<{\n id: string\n campaignId: string\n anonymousId: string\n externalId: string | null\n startedAt: string\n completedAt: string | null\n abandonedAt: string | null\n currentQuestionId: string | null\n progressSnapshot: unknown\n source: string\n language: string | null\n }>\n >,\n 'GET /v1/apps/:appId/surveys/:sid/share-link': {} as Endpoint<\n void,\n SurveyShareLinkResponse\n >,\n 'GET /v1/apps/:appId/survey-templates': {} as Endpoint<\n void,\n ReadonlyArray<SurveyTemplate>\n >,\n 'POST /v1/apps/:appId/surveys/from-template/:slug': {} as Endpoint<\n CloneSurveyFromTemplateRequest,\n SurveyCampaignWithFlow\n >,\n\n // Surveys — SDK-facing (write-key auth)\n 'GET /v1/sdk/surveys/available': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n { surveys: ReadonlyArray<SurveySummary> }\n >,\n 'POST /v1/sdk/surveys/resolve-link': {} as Endpoint<\n ResolveSurveyLinkRequest,\n ResolveSurveyLinkResponse\n >,\n 'GET /v1/sdk/surveys/:sid': {} as Endpoint<\n { anonymousId: string; externalId?: string; language?: string },\n SurveyCampaignWithFlow\n >,\n 'POST /v1/sdk/surveys/:sid/attempts': {} as Endpoint<\n CreateSurveyAttemptRequest,\n CreateSurveyAttemptResponse\n >,\n 'PATCH /v1/sdk/surveys/attempts/:attemptId': {} as Endpoint<\n UpdateSurveyAttemptProgressRequest,\n { ok: true }\n >,\n 'POST /v1/sdk/surveys/attempts/:attemptId/responses': {} as Endpoint<\n SubmitSurveyAnswersRequest,\n { ok: true }\n >,\n 'POST /v1/sdk/surveys/attempts/:attemptId/complete': {} as Endpoint<\n CompleteSurveyAttemptRequest,\n { ok: true }\n >,\n 'POST /v1/sdk/surveys/attempts/:attemptId/abandon': {} as Endpoint<\n void,\n { ok: true }\n >,\n\n // ---------- in-app messages (4th pillar) ----------\n 'GET /v1/apps/:appId/inapp-messages': {} as Endpoint<\n void,\n ReadonlyArray<InAppMessage>\n >,\n 'POST /v1/apps/:appId/inapp-messages': {} as Endpoint<\n CreateInAppMessageRequest,\n InAppMessage\n >,\n 'GET /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<void, InAppMessage>,\n 'PATCH /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<\n UpdateInAppMessageRequest,\n InAppMessage\n >,\n 'DELETE /v1/apps/:appId/inapp-messages/:id': {} as Endpoint<\n void,\n { ok: true }\n >,\n 'POST /v1/apps/:appId/inapp-messages/:id/activate': {} as Endpoint<\n void,\n InAppMessage\n >,\n 'POST /v1/apps/:appId/inapp-messages/:id/pause': {} as Endpoint<\n void,\n InAppMessage\n >,\n 'GET /v1/apps/:appId/inapp-messages/:id/analytics': {} as Endpoint<\n { from?: string; to?: string },\n InAppMessageAnalytics\n >,\n 'GET /v1/apps/:appId/inapp-messages/:id/recipients': {} as Endpoint<\n RecipientPageQuery,\n RecipientList<InAppRecipient>\n >,\n 'GET /v1/sdk/armed-inapp-messages': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n SdkArmedInAppMessagesResponse\n >,\n\n // ---------- feature requests (5th pillar) — dashboard ----------\n 'GET /v1/apps/:appId/requests': {} as Endpoint<\n ListRequestsQuery,\n ReadonlyArray<RequestSummary>\n >,\n 'GET /v1/apps/:appId/requests/:requestId': {} as Endpoint<\n void,\n RequestDetail\n >,\n 'PATCH /v1/apps/:appId/requests/:requestId/status': {} as Endpoint<\n UpdateRequestStatusRequest,\n RequestDetail\n >,\n 'PUT /v1/apps/:appId/requests/:requestId/response': {} as Endpoint<\n UpdateRequestResponseRequest,\n RequestDetail\n >,\n 'PATCH /v1/apps/:appId/requests/:requestId/moderation': {} as Endpoint<\n UpdateRequestModerationRequest,\n RequestDetail\n >,\n 'POST /v1/apps/:appId/requests/merge': {} as Endpoint<\n MergeRequestsRequest,\n { canonicalId: string; mergedCount: number }\n >,\n 'POST /v1/apps/:appId/requests/bulk/status': {} as Endpoint<\n BulkUpdateStatusRequest,\n { updated: number }\n >,\n 'GET /v1/apps/:appId/requests/:requestId/upvoter-segments': {} as Endpoint<\n void,\n RequestUpvoterSegmentBreakdown\n >,\n 'GET /v1/apps/:appId/requests/:requestId/timeline': {} as Endpoint<\n void,\n ReadonlyArray<RequestTimelineEntry>\n >,\n 'GET /v1/apps/:appId/requests/:requestId/analytics': {} as Endpoint<\n { from?: string; to?: string },\n RequestAnalytics\n >,\n 'GET /v1/apps/:appId/requests/:requestId/audience-spec': {} as Endpoint<\n void,\n { audience: AudienceSpec }\n >,\n 'GET /v1/apps/:appId/request-settings': {} as Endpoint<void, RequestSettings>,\n 'PUT /v1/apps/:appId/request-settings': {} as Endpoint<\n UpdateRequestSettingsRequest,\n RequestSettings\n >,\n 'GET /v1/apps/:appId/request-settings/slug-available': {} as Endpoint<\n { slug: string },\n { available: boolean }\n >,\n /** Multipart `file` field; the processed logo URL is saved into branding.logoUrl. */\n 'POST /v1/apps/:appId/request-settings/logo': {} as Endpoint<\n { file: Blob },\n RequestSettings\n >,\n 'DELETE /v1/apps/:appId/request-settings/logo': {} as Endpoint<\n void,\n RequestSettings\n >,\n 'POST /v1/apps/:appId/requests/seed-segments': {} as Endpoint<\n void,\n { created: number }\n >,\n\n // ---------- feature requests — SDK (write-key) ----------\n 'GET /v1/sdk/requests': {} as Endpoint<\n GetRequestsOptions & { anonymousId: string; externalId?: string },\n GetRequestsResult\n >,\n 'GET /v1/sdk/request-branding': {} as Endpoint<\n void,\n {\n readonly entryLabel: string\n readonly accentColor: string | null\n readonly logoUrl: string | null\n readonly introCopy: string | null\n }\n >,\n 'GET /v1/sdk/requests/search': {} as Endpoint<\n { q: string; anonymousId: string; externalId?: string; limit?: number },\n { results: ReadonlyArray<RequestSearchResult> }\n >,\n 'GET /v1/sdk/requests/:requestId': {} as Endpoint<\n { anonymousId: string; externalId?: string },\n Request\n >,\n 'POST /v1/sdk/requests': {} as Endpoint<SubmitRequestPayload, Request>,\n 'POST /v1/sdk/requests/:requestId/vote': {} as Endpoint<\n { anonymousId: string; externalId?: string | null; vote: boolean },\n RequestVote\n >,\n 'POST /v1/sdk/requests/:requestId/follow': {} as Endpoint<\n { anonymousId: string; externalId?: string | null; follow: boolean },\n RequestFollow\n >,\n\n // ---------- feature requests — comments ----------\n // Dashboard (cookie auth)\n 'GET /v1/apps/:appId/requests/:requestId/comments': {} as Endpoint<\n void,\n { items: ReadonlyArray<RequestComment> }\n >,\n 'DELETE /v1/apps/:appId/requests/:requestId/comments/:commentId':\n {} as Endpoint<void, { ok: true }>,\n\n // SDK (write-key)\n 'GET /v1/sdk/requests/:requestId/comments': {} as Endpoint<\n { anonymousId: string; externalId?: string | null },\n { items: ReadonlyArray<RequestComment> }\n >,\n 'POST /v1/sdk/requests/:requestId/comments': {} as Endpoint<\n PostCommentPayload,\n RequestComment\n >,\n 'PATCH /v1/sdk/requests/:requestId/comments/:commentId': {} as Endpoint<\n EditCommentPayload,\n RequestComment\n >,\n 'DELETE /v1/sdk/requests/:requestId/comments/:commentId': {} as Endpoint<\n { anonymousId: string },\n { ok: true }\n >,\n\n // ---------- billing (Paddle) ----------\n 'GET /v1/workspaces/:wid/billing/plans': {} as Endpoint<\n void,\n {\n plans: ReadonlyArray<BillingPlan>\n foundingOffer: BillingOfferAvailability\n }\n >,\n 'GET /v1/workspaces/:wid/billing/subscription': {} as Endpoint<\n void,\n {\n subscription: Subscription | null\n plan: BillingPlan | null\n usage: BillingUsage\n access: EffectivePlanAccess\n trial: BillingTrial | null\n }\n >,\n 'POST /v1/workspaces/:wid/billing/checkout': {} as Endpoint<\n BillingCheckoutRequest,\n BillingCheckoutResponse\n >,\n 'POST /v1/workspaces/:wid/billing/portal': {} as Endpoint<\n void,\n { url: string }\n >,\n 'POST /v1/workspaces/:wid/billing/change-plan': {} as Endpoint<\n BillingChangePlanRequest,\n BillingChangePlanResponse\n >,\n 'GET /v1/workspaces/:wid/billing/periods': {} as Endpoint<\n void,\n { periods: ReadonlyArray<BillingPeriod> }\n >,\n\n // ---------- super admin ----------\n 'GET /v1/admin/session': {} as Endpoint<void, AdminSession>,\n 'GET /v1/admin/feature-flags': {} as Endpoint<\n void,\n ReadonlyArray<GlobalFeatureFlag>\n >,\n 'PATCH /v1/admin/feature-flags/:key': {} as Endpoint<\n UpdateGlobalFeatureFlagRequest,\n GlobalFeatureFlag\n >,\n 'GET /v1/admin/customers': {} as Endpoint<\n AdminCustomerListRequest,\n AdminCustomerListResponse\n >,\n 'GET /v1/admin/customers/:workspaceId': {} as Endpoint<\n void,\n AdminCustomerDetail\n >,\n 'POST /v1/admin/customers/:workspaceId/permanent-deletion': {} as Endpoint<\n DeleteAdminWorkspaceRequest,\n { job: AdminDeletionJob }\n >,\n 'GET /v1/admin/dashboard-users': {} as Endpoint<\n AdminDashboardUserListRequest,\n AdminDashboardUserListResponse\n >,\n 'POST /v1/admin/dashboard-users/:userId/permanent-deletion': {} as Endpoint<\n DeleteAdminDashboardUserRequest,\n { job: AdminDeletionJob }\n >,\n 'GET /v1/admin/deletion-jobs/:jobId': {} as Endpoint<\n void,\n { job: AdminDeletionJob }\n >,\n 'POST /v1/admin/deletion-jobs/:jobId/retry': {} as Endpoint<\n Record<string, never>,\n { job: AdminDeletionJob }\n >,\n 'POST /v1/admin/customers/:workspaceId/billing-events/:eventId/replay':\n {} as Endpoint<Record<string, never>, { replayed: true }>,\n 'POST /v1/admin/customers/:workspaceId/grants': {} as Endpoint<\n CreateWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'POST /v1/admin/customers/:workspaceId/grants/:grantId/extend':\n {} as Endpoint<\n ExtendWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'POST /v1/admin/customers/:workspaceId/grants/:grantId/revoke':\n {} as Endpoint<\n RevokeWorkspacePlanGrantRequest,\n { grant: WorkspacePlanGrant }\n >,\n 'GET /v1/admin/activity': {} as Endpoint<\n { workspaceId?: string\n action?: string\n cursor?: string\n limit?: number },\n { entries: ReadonlyArray<AdminActivityEntry>\n nextCursor: string | null }\n >,\n 'GET /v1/admin/workspaces': {} as Endpoint<\n void,\n { workspaces: ReadonlyArray<AdminWorkspaceSummary> }\n >,\n 'GET /v1/admin/plans': {} as Endpoint<\n { grantable?: boolean },\n {\n plans: ReadonlyArray<BillingPlan>\n foundingOffer: BillingOfferAvailability\n paddleEnvironment: 'sandbox' | 'production'\n configuration: {\n apiKeyConfigured: boolean\n clientTokenConfigured: boolean\n webhookSecretConfigured: boolean\n enforcementMode: 'observe' | 'warn' | 'enforce'\n overageMode: 'observe' | 'charge'\n }\n bindings: ReadonlyArray<{\n planId: string\n baseReady: boolean\n overageReady: boolean\n }>\n }\n >,\n 'GET /v1/admin/workspaces/:wid': {} as Endpoint<\n void,\n {\n workspace: { id: string; name: string; slug: string }\n subscription: Subscription | null\n plan: BillingPlan | null\n mau: number\n events: ReadonlyArray<{\n id: string\n event_type: string\n received_at: string\n processed_at: string | null\n processing_error: string | null\n }>\n }\n >,\n 'POST /v1/admin/workspaces/:wid/plan': {} as Endpoint<\n { planId: string },\n { subscription: Subscription }\n >,\n\n // ---------- feature requests — public web roadmap (no auth) ----------\n 'GET /v1/public/roadmap/:slug': {} as Endpoint<\n {\n status?: RequestStatus | ReadonlyArray<RequestStatus>\n sort?: 'top' | 'newest' | 'recently_updated'\n page?: number\n limit?: number\n },\n { items: ReadonlyArray<RequestPublicSummary>; total: number }\n >,\n 'GET /v1/public/roadmap/:slug/r/:requestId': {} as Endpoint<\n void,\n RequestPublicDetail\n >,\n 'GET /v1/public/roadmap/:slug/branding': {} as Endpoint<\n void,\n RequestPublicBranding\n >,\n\n 'GET /v1/apps/:appId/help/articles': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.PortalDocument>\n >,\n 'POST /v1/apps/:appId/help/articles': {} as Endpoint<\n Content.CreateDocument,\n Content.PortalDocument\n >,\n 'GET /v1/apps/:appId/help/articles/:documentId': {} as Endpoint<\n void,\n Content.PortalDocument\n >,\n 'PUT /v1/apps/:appId/help/articles/:documentId': {} as Endpoint<\n Content.SaveDocument,\n Content.PortalDocument\n >,\n 'POST /v1/apps/:appId/help/articles/:documentId/lifecycle': {} as Endpoint<\n Content.ContentAction,\n Content.PortalDocument\n >,\n 'GET /v1/apps/:appId/changelog': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.PortalDocument>\n >,\n 'POST /v1/apps/:appId/changelog': {} as Endpoint<\n Content.CreateDocument,\n Content.PortalDocument\n >,\n 'GET /v1/apps/:appId/changelog/:documentId': {} as Endpoint<\n void,\n Content.PortalDocument\n >,\n 'PUT /v1/apps/:appId/changelog/:documentId': {} as Endpoint<\n Content.SaveDocument,\n Content.PortalDocument\n >,\n 'POST /v1/apps/:appId/changelog/:documentId/lifecycle': {} as Endpoint<\n Content.ContentAction,\n Content.PortalDocument\n >,\n 'GET /v1/apps/:appId/help/collections': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.HelpCollection>\n >,\n 'POST /v1/apps/:appId/help/collections': {} as Endpoint<\n Content.CreateCollection,\n Content.HelpCollection\n >,\n 'PATCH /v1/apps/:appId/help/collections/:collectionId': {} as Endpoint<\n Content.UpdateCollection,\n Content.HelpCollection\n >,\n 'POST /v1/apps/:appId/help/collections/:collectionId/position':\n {} as Endpoint<Content.ReorderContent, { updated: boolean }>,\n 'POST /v1/apps/:appId/help/articles/:documentId/position': {} as Endpoint<\n Content.ReorderContent,\n { updated: boolean }\n >,\n 'GET /v1/apps/:appId/roadmap': {} as Endpoint<\n Content.RoadmapQuery,\n Content.ContentPage<Content.RoadmapCard>\n >,\n 'POST /v1/apps/:appId/roadmap': {} as Endpoint<\n Content.CreateRoadmapItem,\n Content.RoadmapItem\n >,\n 'GET /v1/apps/:appId/roadmap/:itemId': {} as Endpoint<\n void,\n Content.RoadmapItem\n >,\n 'PUT /v1/apps/:appId/roadmap/:itemId': {} as Endpoint<\n Content.SaveRoadmapItem,\n Content.RoadmapItem\n >,\n 'POST /v1/apps/:appId/roadmap/:itemId/status': {} as Endpoint<\n Content.MoveRoadmapItem,\n Content.RoadmapItem\n >,\n 'POST /v1/apps/:appId/roadmap/:itemId/lifecycle': {} as Endpoint<\n Content.ContentAction,\n Content.RoadmapItem\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/help/collections': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.HelpCollection>\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/help/collections/:collectionId':\n {} as Endpoint<void, Content.HelpCollection>,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/help/articles': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.PublicDocumentSummary>\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/help/articles/:documentId':\n {} as Endpoint<void, Content.PublicPortalDocument>,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/changelog': {} as Endpoint<\n Content.ContentQuery,\n Content.ContentPage<Content.PublicDocumentSummary>\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/changelog/:documentId':\n {} as Endpoint<void, Content.PublicPortalDocument>,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/roadmap': {} as Endpoint<\n Content.RoadmapQuery,\n Content.ContentPage<Content.RoadmapCard>\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/roadmap/:itemId': {} as Endpoint<\n void,\n Content.PublicRoadmapItem\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId/changelog':\n {} as Endpoint<\n Content.ContentPageQuery,\n Content.ContentPage<Content.PublicDocumentSummary>\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/roadmap/:itemId/changelog':\n {} as Endpoint<\n Content.ContentPageQuery,\n Content.ContentPage<Content.PublicDocumentSummary>\n >,\n 'GET /v1/apps/:appId/portal-content/link-targets': {} as Endpoint<\n Content.ContentLinkQuery,\n Content.ContentPage<Content.ContentLinkTarget>\n >,\n // Binary routes use multipart/stream transports, not the JSON client helper.\n 'POST /v1/apps/:appId/portal-content/assets/:kind/:documentId':\n {} as Endpoint<Content.PortalAssetUpload, Content.PortalAsset>,\n 'GET /v1/apps/:appId/portal-content/assets/:assetId': {} as Endpoint<\n void,\n Blob\n >,\n 'GET /v1/portal/:portalSlug/apps/:appSlug/assets/:assetId': {} as Endpoint<\n void,\n Blob\n >,\n} as const\n\nexport type EndpointKey = keyof typeof endpoints\n","/**\n * Shared Zod schemas — single source of truth for request/response validation.\n *\n * Both the API (Fastify route handlers) and the dashboard (react-hook-form +\n * runtime response validation) import from here. If you change a schema,\n * every consumer sees the new constraint at compile time.\n *\n * Migration is incremental — pillars are landing here pillar-by-pillar. The\n * API still has duplicate schemas under `apps/api/src/schemas/` for the ones\n * not yet moved; those re-export from here to keep import paths stable.\n */\nexport * from './auth.js'\nexport * from './apps.js'\nexport * from './primitives.js'\n\nexport * from './web.js'\nexport * from './portal.js'\nexport * from './portal-content.js'\nexport * from './mcp.js'\n","import { z } from 'zod'\n\n/** Lowercase + digits + dashes; URL-safe slug. */\nexport const slugSchema = z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9-]+$/, 'Must be lowercase, digits, and dashes only')\n\n/** RFC 5321 max email length. */\nexport const emailSchema = z.string().email().max(320)\n\nexport const uuidSchema = z.string().uuid()\n\nexport const isoDateTimeSchema = z.string().datetime({ offset: true })\n\n/** Workspace role hierarchy used by tenant middleware. */\nexport const workspaceRoleSchema = z.enum(['owner', 'admin', 'editor', 'viewer'])\n\nexport type WorkspaceRoleInput = z.infer<typeof workspaceRoleSchema>\n","import { z } from 'zod'\nimport { emailSchema } from './primitives.js'\n\n/**\n * Password policy. Tightening this here flows to: API signup route, dashboard\n * SignupForm, password-reset flow, future SSO bridge. Don't fork it in a form.\n */\nexport const passwordSchema = z.string().min(8).max(256)\n\nexport const signupRequestSchema = z.object({\n email: emailSchema,\n password: passwordSchema,\n name: z.string().min(1).max(120).optional(),\n workspaceName: z.string().min(1).max(120),\n})\n\nexport const loginPasswordRequestSchema = z.object({\n email: emailSchema,\n password: z.string().min(1).max(256),\n})\n\nexport const loginMagicLinkRequestSchema = z.object({\n email: emailSchema,\n})\n\nexport const loginMagicLinkConsumeRequestSchema = z.object({\n token: z.string().min(16).max(512),\n})\n\nexport const updateCurrentUserSchema = z\n .object({\n name: z.string().trim().min(1).max(120).optional(),\n })\n .strict()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'At least one field is required',\n })\n\nexport type SignupBody = z.infer<typeof signupRequestSchema>\nexport type LoginPasswordBody = z.infer<typeof loginPasswordRequestSchema>\nexport type LoginMagicLinkBody = z.infer<typeof loginMagicLinkRequestSchema>\nexport type LoginMagicLinkConsumeBody = z.infer<typeof loginMagicLinkConsumeRequestSchema>\nexport type UpdateCurrentUserBody = z.infer<typeof updateCurrentUserSchema>\n","import { z } from 'zod'\n\nexport const deliveryPlatformsSchema = z.array(z.enum(['ios', 'android', 'web'])).min(1).max(3)\n .transform((values) => [...new Set(values)])\nexport const webPresentationSchema = z.object({\n layout: z.enum(['modal', 'card', 'panel']).optional(),\n size: z.enum(['compact', 'standard', 'wide']).optional(),\n position: z.enum(['left', 'right']).optional(),\n backdrop: z.boolean().optional(),\n}).strict()\nexport const webOriginSchema = z.string().max(2048).refine((value) => {\n try {\n const url = new URL(value)\n return url.origin === value && !url.username && !url.password &&\n (url.protocol === 'https:' || (url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)))\n } catch { return false }\n}, 'Use an exact HTTPS origin, or an HTTP localhost origin for development')\nexport const webAppConfigSchema = z.object({\n allowedOrigins: z.array(webOriginSchema).max(30).transform((values) => [...new Set(values)]),\n}).strict()\n","import type { PortalSection } from './portal-content.js'\nimport type { RequestStatus } from './request.js'\n\nexport interface PortalApp {\n appId: string\n name: string\n slug: string\n enabled: boolean\n firstPublishedAt: string | null\n url: string | null\n branding: { accentColor: string; logoUrl: string | null; introCopy: string | null }\n}\nexport interface PortalSettings {\n baseDomain: string\n workspaceId: string\n displayName: string\n slug: string | null\n published: boolean\n firstPublishedAt: string | null\n url: string | null\n hostingReady: boolean\n setupDismissed: boolean\n apps: PortalApp[]\n}\nexport interface PublicPortal {\n contentEnabled?: boolean\n slug: string\n displayName: string\n url: string\n apps: (Pick<PortalApp, 'name' | 'slug' | 'url' | 'branding'> & { sections?: PortalSection[]; urls?: Record<PortalSection, string> })[]\n}\nexport interface PortalRequest {\n id: string\n title: string\n description: string\n status: RequestStatus\n upvoteCount: number\n createdAt: string\n statusChangedAt: string\n devResponse: string | null\n mergedIntoId: string | null\n}\nexport interface PortalRequestList {\n items: PortalRequest[]\n total: number\n page: number\n hasMore: boolean\n}\nexport type PortalRequestCounts = { all: number } & Partial<Record<RequestStatus, number>>\nexport interface PortalRequestQuery {\n q?: string\n status?: RequestStatus\n sort?: 'top' | 'newest' | 'status_changed'\n page?: number\n limit?: number\n}\nexport interface PortalSession { email: string; expiresAt: string }\nexport interface UpdatePortalRequest { displayName?: string; slug?: string; setupDismissed?: boolean }\nexport interface UpdatePortalAppRequest { slug: string; enabled: boolean }\n/** Reserve an app's public address as part of app creation, without publishing it. */\nexport interface CreateAppPortal {\n appSlug: string\n company?: { displayName: string; slug: string }\n}\nexport interface PortalAuthStart { email: string }\nexport interface PortalAuthVerify { email: string; code: string }\nexport interface PortalSubmission { title: string; description: string; idempotencyKey: string; feedbackConsent: true }\nexport interface PortalVote { vote: boolean; feedbackConsent: true }\n\nexport const PORTAL_RESERVED_SLUGS: readonly string[] = [\n 'www', 'app', 'api', 'admin', 'auth', 'portal', 'docs', 'status', 'mail',\n 'support', 'login', 'logout', 'signup', 'billing', 'dashboard', 'cdn',\n 'assets', 'static', 'smtp', 'ftp', 'help', 'account', 'accounts', 'developer',\n]\nexport const PORTAL_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,46})[a-z0-9]$/\nexport function validPortalSlug(slug: string): boolean {\n return PORTAL_SLUG_PATTERN.test(slug) && !PORTAL_RESERVED_SLUGS.includes(slug)\n}\nexport function suggestPortalSlug(name: string): string {\n const value = name.toLowerCase().normalize('NFKD').replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 48).replace(/-$/, '')\n return validPortalSlug(value) ? value : value.length >= 3 ? `${value.slice(0, 40)}-team` : ''\n}\nexport function buildPortalUrl(slug: string, baseDomain = 'usergist.com', appSlug?: string): string {\n if (!validPortalSlug(slug) || !/^[a-z0-9.-]+$/i.test(baseDomain)) throw new Error('Invalid portal address')\n const base = `https://${slug}.${baseDomain}`\n return appSlug ? `${base}/${encodeURIComponent(appSlug)}/requests` : base\n}\n","import { z } from 'zod'\nimport { validPortalSlug } from '../types/portal.js'\n\nexport const portalSlugSchema = z.string().refine(validPortalSlug,\n 'Use 3–48 lowercase letters, numbers, or interior hyphens. This name must not be reserved.')\nexport const updatePortalSchema = z.object({\n displayName: z.string().trim().min(1).max(100).optional(),\n slug: portalSlugSchema.optional(),\n setupDismissed: z.boolean().optional(),\n}).strict()\nexport const updatePortalAppSchema = z.object({ slug: portalSlugSchema, enabled: z.boolean() }).strict()\nexport const portalVisibilitySchema = z.object({ ids: z.array(z.string().uuid()).min(1).max(100), visible: z.boolean() }).strict()\nexport const portalEmailSchema = z.string().trim().email().max(254).transform((value) => value.toLowerCase())\nexport const portalAuthStartSchema = z.object({ email: portalEmailSchema }).strict()\nexport const portalAuthVerifySchema = z.object({ email: portalEmailSchema, code: z.string().regex(/^\\d{6}$/) }).strict()\nexport const portalSubmissionSchema = z.object({\n title: z.string().trim().min(1).max(120), description: z.string().trim().min(1).max(1500),\n idempotencyKey: z.string().uuid(), feedbackConsent: z.literal(true),\n}).strict()\nexport const portalVoteSchema = z.object({ vote: z.boolean(), feedbackConsent: z.literal(true) }).strict()\nexport const portalRequestQuerySchema = z.object({\n q: z.string().trim().max(200).optional(),\n status: z.enum(['under_review', 'planned', 'in_progress', 'shipped', 'declined']).optional(),\n sort: z.enum(['top', 'newest', 'status_changed']).default('top'),\n page: z.coerce.number().int().min(1).max(100000).default(1),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n}).strict()\n","import { z } from 'zod'\nimport { webAppConfigSchema } from './web.js'\nimport { emailSchema, slugSchema } from './primitives.js'\nimport { isValidIanaTimeZone } from '../timezone.js'\nimport { portalSlugSchema } from './portal.js'\n\nexport const workspaceTimezoneSchema = z\n .string()\n .trim()\n .min(1)\n .max(64)\n .refine(isValidIanaTimeZone, 'Enter a valid IANA timezone')\n\nexport const platformSchema = z.enum([\n 'ios',\n 'android',\n 'react-native',\n 'expo',\n 'flutter',\n 'web',\n])\n\nexport const writeKeyEnvironmentSchema = z.enum([\n 'production',\n 'staging',\n 'development',\n])\n\nexport const onboardingGoalSchema = z.enum([\n 'feedback',\n 'survey',\n 'inapp',\n 'push',\n 'requests',\n])\nexport const onboardingStatusSchema = z.enum([\n 'in_progress',\n 'deferred',\n 'completed',\n])\nexport const onboardingStepSchema = z.enum([\n 'connect',\n 'verify',\n 'experience',\n 'push',\n 'launch',\n])\nexport const onboardingPushChoiceSchema = z.enum([\n 'pending',\n 'configured',\n 'skipped',\n])\n\nexport const apiTokenScopeSchema = z.enum([\n 'sdk:subjects',\n 'push.transactional',\n 'users.properties.write',\n])\n\nexport const createAppSchema = z.object({\n name: z.string().min(1).max(120),\n slug: slugSchema.optional(),\n platforms: z.array(platformSchema).min(1).max(8),\n environment: writeKeyEnvironmentSchema.default('production'),\n onboardingGoal: onboardingGoalSchema.optional(),\n setupMode: z.enum(['sdk', 'portal']).optional(),\n portal: z\n .object({\n appSlug: portalSlugSchema,\n company: z\n .object({\n displayName: z.string().trim().min(1).max(100),\n slug: portalSlugSchema,\n })\n .strict()\n .optional(),\n })\n .strict()\n .optional(),\n webConfig: webAppConfigSchema.optional(),\n})\n\nexport const updateOnboardingSchema = z\n .object({\n action: z\n .enum([\n 'resume',\n 'defer',\n 'create_first_inapp',\n 'first_inapp_completed',\n 'create_first_feedback',\n 'first_feedback_completed',\n 'push_configured',\n 'push_skipped',\n 'complete',\n ])\n .optional(),\n step: onboardingStepSchema.optional(),\n question: z.string().trim().min(1).max(500).optional(),\n message: z.object({\n title: z.string().trim().min(1).max(200),\n body: z.string().trim().min(1).max(500),\n buttonLabel: z.string().trim().min(1).max(40),\n format: z.enum(['modal', 'slideup']),\n }).strict().optional(),\n })\n .refine((value) => Boolean(value.action || value.step), {\n message: 'Provide an onboarding action or step',\n })\n .refine(\n (value) =>\n value.action !== 'create_first_feedback' || Boolean(value.question),\n { message: 'Provide a question for the first feedback experience' },\n )\n\nexport const deferCurrentUserOnboardingSchema = z.object({\n action: z.literal('defer'),\n})\n\nexport const updateAppSchema = z\n .object({\n name: z.string().min(1).max(120).optional(),\n platforms: z.array(platformSchema).min(1).max(8).optional(),\n piiAllowList: z.array(z.string().min(1).max(120)).max(128).optional(),\n lifecycleEventsEnabled: z.boolean().optional(),\n webConfig: webAppConfigSchema.optional(),\n })\n .refine((v) => Object.keys(v).length > 0, {\n message: 'At least one field is required',\n })\n\nexport const createWriteKeySchema = z.object({\n label: z.string().min(1).max(120).optional(),\n environment: writeKeyEnvironmentSchema.default('production'),\n})\n\nexport const rotateWriteKeySchema = z.object({\n // Default 5 minutes; ceiling 24h to bound risk of forgotten old keys.\n graceSeconds: z.number().int().min(0).max(86_400).default(300),\n})\n\nexport const createApiTokenSchema = z.object({\n name: z.string().trim().min(1).max(120),\n scopes: z\n .array(apiTokenScopeSchema)\n .min(1)\n .max(8)\n .transform((scopes) => [...new Set(scopes)]),\n expiresInDays: z.number().int().min(1).max(365).default(90),\n})\n\nexport const createWorkspaceSchema = z.object({\n name: z.string().trim().min(1).max(120),\n slug: slugSchema.optional(),\n timezone: workspaceTimezoneSchema.default('UTC'),\n})\n\nexport const updateWorkspaceSchema = z\n .object({\n name: z.string().trim().min(1).max(120).optional(),\n timezone: workspaceTimezoneSchema.optional(),\n })\n .strict()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'At least one field is required',\n })\n\nexport const inviteMemberSchema = z.object({\n email: emailSchema,\n role: z.enum(['admin', 'editor', 'viewer']),\n})\n\nexport const acceptWorkspaceInviteSchema = z.object({\n token: z.string().regex(/^[a-f0-9]{64}$/i, 'Invalid invitation token'),\n})\n\nexport type CreateAppBody = z.infer<typeof createAppSchema>\nexport type UpdateOnboardingBody = z.infer<typeof updateOnboardingSchema>\nexport type UpdateAppBody = z.infer<typeof updateAppSchema>\nexport type CreateWriteKeyBody = z.infer<typeof createWriteKeySchema>\nexport type RotateWriteKeyBody = z.infer<typeof rotateWriteKeySchema>\nexport type CreateApiTokenBody = z.infer<typeof createApiTokenSchema>\nexport type CreateWorkspaceBody = z.infer<typeof createWorkspaceSchema>\nexport type UpdateWorkspaceBody = z.infer<typeof updateWorkspaceSchema>\nexport type InviteMemberBody = z.infer<typeof inviteMemberSchema>\nexport type AcceptWorkspaceInviteBody = z.infer<\n typeof acceptWorkspaceInviteSchema\n>\n","export type PortalSection = 'requests' | 'roadmap' | 'help' | 'changelog'\nexport type DocumentKind = 'article' | 'changelog'\nexport type ContentState = 'draft' | 'published' | 'archived'\nexport type RoadmapStatus = 'planned' | 'in_progress' | 'shipped'\nexport type ChangelogCategory = 'new' | 'improved' | 'fixed'\nexport interface ContentMark {\n type: 'bold' | 'italic' | 'code' | 'link'\n attrs?: { href: string }\n}\nexport interface ContentNode {\n type:\n | 'doc'\n | 'paragraph'\n | 'heading'\n | 'text'\n | 'bulletList'\n | 'orderedList'\n | 'listItem'\n | 'blockquote'\n | 'codeBlock'\n | 'hardBreak'\n | 'image'\n text?: string\n attrs?: { level?: number; start?: number; language?: string | null; assetId?: string; alt?: string }\n marks?: ContentMark[]\n content?: ContentNode[]\n}\nexport interface ContentLink {\n kind: 'request' | 'roadmap'\n id: string\n}\nexport interface PublicContentLink extends ContentLink {\n title: string\n url: string\n}\nexport interface DocumentDraft {\n title: string\n summary: string\n body: ContentNode\n collectionId: string | null\n category: ChangelogCategory\n releaseDate: string\n version: string\n links: ContentLink[]\n}\nexport interface PortalDocument {\n id: string\n kind: DocumentKind\n draft: DocumentDraft\n state: ContentState\n revision: number\n slug: string | null\n publishedAt: string | null\n firstPublishedAt: string | null\n updatedAt: string\n hasChanges: boolean\n url: string | null\n canPublish: boolean\n position: number\n}\nexport interface PublicPortalDocument {\n id: string\n title: string\n summary: string\n body: ContentNode\n slug: string\n url: string\n updatedAt: string\n category: ChangelogCategory\n releaseDate: string\n version: string\n collection: HelpCollection | null\n links: PublicContentLink[]\n}\nexport interface PublicDocumentSummary {\n id: string\n title: string\n summary: string\n slug: string\n url: string\n updatedAt: string\n category: ChangelogCategory\n releaseDate: string\n version: string\n /** Full published body; present for changelog entries so the portal can show release notes inline. */\n body?: ContentNode\n}\nexport interface HelpCollection {\n id: string\n title: string\n description: string\n slug: string\n position: number\n revision: number\n archived: boolean\n articleCount: number\n}\nexport interface ContentPage<T> {\n items: T[]\n nextCursor: string | null\n}\nexport interface ContentQuery {\n q?: string\n state?: ContentState\n collectionId?: string\n category?: ChangelogCategory\n cursor?: string\n limit?: number\n}\nexport interface CreateDocument {\n idempotencyKey: string\n title?: string\n collectionId?: string | null\n links?: ContentLink[]\n}\nexport type ContentPageQuery = Pick<ContentQuery, 'cursor' | 'limit'>\nexport interface SaveDocument {\n revision: number\n draft: DocumentDraft\n}\nexport interface ContentAction {\n revision: number\n action: 'publish' | 'unpublish' | 'archive' | 'restore'\n}\nexport interface CreateCollection {\n title: string\n description: string\n idempotencyKey: string\n}\nexport interface UpdateCollection {\n revision: number\n title?: string\n description?: string\n archived?: boolean\n}\nexport interface ReorderContent {\n revision: number\n direction: 'up' | 'down'\n}\nexport interface RoadmapRequestLink {\n id: string\n title: string\n status: string\n updatedAt: string\n hidden: boolean\n portalVisible: boolean\n}\nexport interface RoadmapItem {\n id: string\n title: string\n description: string\n status: RoadmapStatus\n state: ContentState\n revision: number\n statusChangedAt: string\n updatedAt: string\n requests: RoadmapRequestLink[]\n url: string | null\n canPublish: boolean\n}\nexport interface RoadmapCard {\n id: string\n kind: 'request' | 'item'\n title: string\n description: string\n status: RoadmapStatus\n statusChangedAt: string\n published: boolean\n url: string | null\n upvoteCount?: number\n}\nexport interface PublicRoadmapItem {\n id: string\n title: string\n description: string\n status: RoadmapStatus\n statusChangedAt: string\n links: PublicContentLink[]\n changelog: ContentPage<PublicDocumentSummary>\n}\nexport interface RoadmapQuery {\n status: RoadmapStatus\n cursor?: string\n limit?: number\n archived?: boolean\n}\nexport interface CreateRoadmapItem {\n idempotencyKey: string\n title: string\n description: string\n status: RoadmapStatus\n requestIds: string[]\n}\nexport interface SaveRoadmapItem {\n revision: number\n title: string\n description: string\n requestIds: string[]\n}\nexport interface MoveRoadmapItem {\n revision: number\n status: RoadmapStatus\n requests: { id: string; updatedAt: string }[]\n}\nexport interface PortalAsset {\n id: string\n width: number\n height: number\n bytes: number\n}\n/** Multipart file body with idempotencyKey sent in the Idempotency-Key header. */\nexport interface PortalAssetUpload {\n file: Blob\n idempotencyKey: string\n}\nexport function emptyDocumentDraft(): DocumentDraft {\n return {\n title: '',\n summary: '',\n body: { type: 'doc', content: [{ type: 'paragraph' }] },\n collectionId: null,\n category: 'improved',\n releaseDate: new Date().toISOString().slice(0, 10),\n version: '',\n links: [],\n }\n}\nexport function contentText(node: ContentNode): string {\n return (\n node.text ??\n (node.content ?? [])\n .map(contentText)\n .join(node.type === 'paragraph' || node.type === 'heading' ? '' : '\\n')\n )\n}\nexport function contentAssetIds(node: ContentNode): string[] {\n return [\n ...new Set([\n ...(node.type === 'image' && node.attrs?.assetId ? [node.attrs.assetId] : []),\n ...(node.content ?? []).flatMap(contentAssetIds),\n ]),\n ]\n}\nexport function contentSlug(title: string): string {\n return (\n title\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 96)\n .replace(/-$/, '') || 'article'\n )\n}\nexport function safeContentHref(href: string): boolean {\n return /^(https?:\\/\\/|mailto:|\\/[^/]|#[a-zA-Z0-9_-])/.test(href) && !/[\\u0000-\\u0020\\\\]/.test(href)\n}\n\nexport interface ContentLinkTarget extends ContentLink {\n title: string\n status: string\n}\nexport interface ContentLinkQuery {\n kind: 'request' | 'roadmap'\n q?: string\n cursor?: string\n limit?: number\n ids?: string\n}\n","import { z } from 'zod'\nimport { contentText, safeContentHref, type ContentNode } from '../types/portal-content.js'\n\nconst uuid = z.string().uuid()\nexport const contentKindSchema = z.enum(['article', 'changelog'])\nexport const contentStateSchema = z.enum(['draft', 'published', 'archived'])\nexport const roadmapStatusSchema = z.enum(['planned', 'in_progress', 'shipped'])\nexport const contentLinkSchema = z.object({ kind: z.enum(['request', 'roadmap']), id: uuid }).strict()\nconst mark = z\n .object({\n type: z.enum(['bold', 'italic', 'code', 'link']),\n attrs: z\n .object({ href: z.string().max(2048).refine(safeContentHref, 'Use a safe link URL') })\n .strict()\n .optional(),\n })\n .strict()\n .refine((m) => (m.type === 'link' ? Boolean(m.attrs) : !m.attrs))\nconst node: z.ZodType<ContentNode> = z.lazy(() =>\n z\n .object({\n type: z.enum([\n 'doc',\n 'paragraph',\n 'heading',\n 'text',\n 'bulletList',\n 'orderedList',\n 'listItem',\n 'blockquote',\n 'codeBlock',\n 'hardBreak',\n 'image',\n ]),\n text: z.string().max(100000).optional(),\n attrs: z\n .object({\n level: z.number().int().min(2).max(3).optional(),\n start: z.number().int().min(1).max(10000).optional(),\n language: z.string().max(40).nullable().optional(),\n assetId: uuid.optional(),\n alt: z.string().max(500).optional(),\n })\n .strict()\n .optional(),\n marks: z.array(mark).max(4).optional(),\n content: z.array(node).max(5000).optional(),\n })\n .strict(),\n)\nexport const contentBodySchema = z\n .unknown()\n .superRefine((value, ctx) => {\n let count = 0,\n invalid = false\n const walk = (v: unknown, depth: number) => {\n if (depth > 20 || ++count > 5000) {\n invalid = true\n return\n }\n if (v && typeof v === 'object' && 'content' in v && Array.isArray(v.content))\n for (const child of v.content) {\n if (invalid) break\n walk(child, depth + 1)\n }\n }\n walk(value, 0)\n if (invalid)\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Document is too deeply nested or contains too many blocks',\n })\n })\n .pipe(node)\n .superRefine((value, ctx) => {\n if (value.type !== 'doc' || contentText(value).length > 100000)\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid document or body exceeds 100,000 characters',\n })\n const walk = (v: ContentNode, root = false) => {\n const blocks = ['paragraph', 'heading', 'bulletList', 'orderedList', 'blockquote', 'codeBlock', 'image']\n const children = v.content ?? []\n const allowed =\n v.type === 'doc' || v.type === 'blockquote'\n ? blocks\n : v.type === 'listItem'\n ? blocks.filter((t) => t !== 'heading')\n : v.type === 'bulletList' || v.type === 'orderedList'\n ? ['listItem']\n : v.type === 'paragraph' || v.type === 'heading'\n ? ['text', 'hardBreak']\n : v.type === 'codeBlock'\n ? ['text']\n : []\n const attrs = Object.keys(v.attrs ?? {})\n const allowedAttrs =\n v.type === 'heading'\n ? ['level']\n : v.type === 'orderedList'\n ? ['start']\n : v.type === 'codeBlock'\n ? ['language']\n : v.type === 'image'\n ? ['assetId', 'alt']\n : []\n if (\n (!root && v.type === 'doc') ||\n (v.type === 'text' && (!v.text || v.content)) ||\n (v.type !== 'text' && (v.text !== undefined || Boolean(v.marks?.length))) ||\n (v.type === 'image' && (!v.attrs?.assetId || v.content)) ||\n (v.type === 'heading' && !v.attrs?.level) ||\n attrs.some((a) => !allowedAttrs.includes(a)) ||\n children.some((c) => !allowed.includes(c.type)) ||\n (v.type === 'listItem' && children[0]?.type !== 'paragraph') ||\n (['bulletList', 'orderedList', 'blockquote', 'doc'].includes(v.type) && !children.length) ||\n (v.type === 'codeBlock' && children.some((c) => c.marks?.length))\n )\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Invalid content block' })\n v.content?.forEach((c) => walk(c))\n }\n walk(value, true)\n })\nexport const documentDraftSchema = z\n .object({\n title: z.string().trim().max(160),\n summary: z.string().max(280),\n body: contentBodySchema,\n collectionId: uuid.nullable(),\n category: z.enum(['new', 'improved', 'fixed']),\n releaseDate: z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/)\n .refine(\n (v) => !Number.isNaN(Date.parse(v)) && new Date(v).toISOString().slice(0, 10) === v,\n 'Choose a valid date',\n ),\n version: z.string().max(40),\n links: z.array(contentLinkSchema).max(100),\n })\n .strict()\nexport const createDocumentSchema = z\n .object({\n idempotencyKey: uuid,\n title: z.string().trim().max(160).optional(),\n collectionId: uuid.nullable().optional(),\n links: z.array(contentLinkSchema).max(100).optional(),\n })\n .strict()\nexport const saveDocumentSchema = z\n .object({ revision: z.number().int().positive(), draft: documentDraftSchema })\n .strict()\nexport const contentActionSchema = z\n .object({\n revision: z.number().int().positive(),\n action: z.enum(['publish', 'unpublish', 'archive', 'restore']),\n })\n .strict()\nexport const contentQuerySchema = z\n .object({\n q: z.string().trim().max(200).optional(),\n state: contentStateSchema.optional(),\n collectionId: uuid.optional(),\n category: z.enum(['new', 'improved', 'fixed']).optional(),\n cursor: z.string().max(2000).optional(),\n limit: z.coerce.number().int().min(1).max(50).default(20),\n })\n .strict()\nexport const createCollectionSchema = z\n .object({\n title: z.string().trim().min(1).max(160),\n description: z.string().max(280),\n idempotencyKey: uuid,\n })\n .strict()\nexport const contentPageQuerySchema = contentQuerySchema.pick({ cursor: true, limit: true })\nexport const portalAssetUploadKeySchema = uuid\nexport const updateCollectionSchema = z\n .object({\n revision: z.number().int().positive(),\n title: z.string().trim().min(1).max(160).optional(),\n description: z.string().max(280).optional(),\n archived: z.boolean().optional(),\n })\n .strict()\nexport const reorderContentSchema = z\n .object({ revision: z.number().int().positive(), direction: z.enum(['up', 'down']) })\n .strict()\nexport const roadmapQuerySchema = z\n .object({\n status: roadmapStatusSchema,\n cursor: z.string().max(2000).optional(),\n limit: z.coerce.number().int().min(1).max(50).default(20),\n archived: z\n .enum(['true', 'false'])\n .transform((v) => v === 'true')\n .optional(),\n })\n .strict()\nconst roadmapFields = {\n title: z.string().trim().min(1).max(120),\n description: z.string().max(1500),\n requestIds: z\n .array(uuid)\n .max(100)\n .refine((v) => new Set(v).size === v.length),\n}\nexport const createRoadmapSchema = z\n .object({ ...roadmapFields, idempotencyKey: uuid, status: roadmapStatusSchema })\n .strict()\nexport const saveRoadmapSchema = z\n .object({ ...roadmapFields, revision: z.number().int().positive() })\n .strict()\nexport const moveRoadmapSchema = z\n .object({\n revision: z.number().int().positive(),\n status: roadmapStatusSchema,\n requests: z\n .array(z.object({ id: uuid, updatedAt: z.string().datetime() }).strict())\n .max(100)\n .refine((v) => new Set(v.map((r) => r.id)).size === v.length),\n })\n .strict()\n\nexport const contentLinkQuerySchema = z\n .object({\n kind: z.enum(['request', 'roadmap']),\n q: z.string().trim().max(200).optional(),\n cursor: z.string().max(2000).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n ids: z\n .string()\n .max(4000)\n .optional()\n .refine((v) => !v || v.split(',').every((id) => uuid.safeParse(id).success), 'Invalid linked IDs'),\n })\n .strict()\n","/** Workspace-member MCP grants. These never replace workspace role checks. */\nexport const MCP_DOMAINS = ['context', 'users', 'analytics', 'requests', 'roadmap', 'content', 'experiences', 'segments', 'brand', 'portal', 'push', 'integrations', 'sdk', 'apps'] as const\nexport type McpDomain = typeof MCP_DOMAINS[number]\nexport const MCP_ACCESS_MODES = ['read_only', 'approve_changes', 'automatic'] as const\nexport type McpAccessMode = typeof MCP_ACCESS_MODES[number]\nexport type McpCapability = `${McpDomain}:${'read' | 'manage' | 'publish' | 'send'}`\nexport const MCP_CAPABILITIES: readonly McpCapability[] = [\n 'context:read', 'users:read', 'analytics:read', 'requests:read', 'requests:manage', 'requests:publish',\n 'roadmap:read', 'roadmap:manage', 'roadmap:publish', 'content:read', 'content:manage', 'content:publish',\n 'experiences:read', 'experiences:manage', 'experiences:publish', 'segments:read', 'segments:manage',\n 'brand:read', 'brand:manage', 'portal:read', 'portal:manage', 'portal:publish', 'push:read', 'push:manage', 'push:send',\n 'integrations:read', 'integrations:manage', 'integrations:send', 'sdk:read', 'sdk:manage', 'apps:read', 'apps:manage',\n]\nexport const MCP_DEFAULT_CAPABILITIES: readonly McpCapability[] = [\n 'context:read', 'users:read', 'analytics:read', 'requests:read', 'roadmap:read', 'content:read',\n 'experiences:read', 'segments:read', 'brand:read', 'portal:read', 'push:read', 'sdk:read', 'apps:read',\n 'requests:manage', 'roadmap:manage', 'content:manage', 'experiences:manage', 'segments:manage',\n]\nexport type SubjectRef = { subjectId: string; externalId?: never; anonymousId?: never }\n | { externalId: string; subjectId?: never; anonymousId?: never }\n | { anonymousId: string; subjectId?: never; externalId?: never }\nexport interface McpConnection {\n id: string\n workspaceId: string\n userId: string\n name: string\n appIds: string[]\n capabilities: McpCapability[]\n mode: McpAccessMode\n policyVersion: number\n createdAt: string\n lastUsedAt: string | null\n revokedAt: string | null\n connected: boolean\n}\nexport type McpOperationStatus = 'needs_approval' | 'queued' | 'running' | 'succeeded' | 'failed' | 'indeterminate' | 'cancelled' | 'expired'\nexport interface McpOperationResult {\n operationId: string\n status: McpOperationStatus\n proposalId?: string\n expiresAt?: string\n preview?: { action: string; arguments: unknown; effects: string[]; asOf: string; impact?: unknown }\n approvalSource?: 'mcp_form' | 'client_managed' | 'automatic' | null\n result?: unknown\n targets?: { kind: string; id: string; appId?: string }[]\n error?: { code: string; message: string }\n}\nexport interface McpPage<T> {\n items: T[]\n nextCursor: string | null\n asOf: string\n total?: number\n totalKind?: 'exact' | 'estimate'\n}\nexport interface McpGrant { name: string; appIds: string[]; capabilities: McpCapability[]; mode: McpAccessMode }\nexport interface McpConnectionSettings { enabled: boolean; resourceUrl: string | null; mutationsEnabled?: boolean; connections: McpConnection[] }\nexport interface McpActivity { id: string; app_id: string | null; tool: string; status: McpOperationStatus;\n approval_source: McpOperationResult['approvalSource']; error_code: string | null; created_at: string; updated_at: string }\nexport type McpSearchSource = 'request' | 'feedback_answer' | 'survey_answer' | 'roadmap' | 'article' | 'changelog'\nexport interface AppSearchQuery { query: string; types?: McpSearchSource[]; variant?: 'draft' | 'published' | 'record'; cursor?: string; limit?: number }\nexport interface AppSearchResult extends McpPage<{ type: string; id: string; variant: string; title: string; excerpt: string;\n updatedAt: string; indexedAt: string; reference: { appId: string; type: string; id: string; variant: string }; url: string }> {\n index: { ready: boolean; updatedAt: string | null }; warnings: string[]\n}\nexport interface DeliveryDiagnosticInput { kind: 'feedback' | 'survey' | 'inapp' | 'push'; entityId: string;\n subject: SubjectRef; platform: 'ios' | 'android' | 'web'; eventName?: string }\nexport interface DeliveryDiagnosticResult { appId: string; entityId: string; kind: DeliveryDiagnosticInput['kind']; subject: unknown; asOf: string;\n checks: { check: string; status: 'pass' | 'fail' | 'unknown' | 'not_applicable'; evidence: unknown }[]; warnings: string[] }\n","import { z } from 'zod'\nimport { MCP_ACCESS_MODES, MCP_CAPABILITIES, MCP_DEFAULT_CAPABILITIES } from '../types/mcp.js'\n\nexport const mcpCapabilitySchema = z.string().refine((value) => MCP_CAPABILITIES.includes(value as never), 'Unknown MCP capability')\nexport const mcpGrantSchema = z.object({\n name: z.string().trim().min(1).max(100).default('AI connection'),\n appIds: z.array(z.string().uuid()).min(1).max(100).refine(v => new Set(v).size === v.length, 'Duplicate app IDs'),\n capabilities: z.array(mcpCapabilitySchema).max(56).default([...MCP_DEFAULT_CAPABILITIES]),\n mode: z.enum(MCP_ACCESS_MODES).default('approve_changes'),\n}).strict()\nexport const mcpConsentSchema = mcpGrantSchema.extend({\n workspaceId: z.string().uuid(),\n externalAuthId: z.string().min(10).max(256).regex(/^[a-zA-Z0-9_-]+$/),\n})\nexport const mcpUpdateConnectionSchema = mcpGrantSchema.extend({ policyVersion: z.number().int().positive() })\nexport const subjectRefSchema = z.union([\n z.object({ subjectId: z.string().uuid() }).strict(),\n z.object({ externalId: z.string().min(1).max(256) }).strict(),\n z.object({ anonymousId: z.string().min(1).max(256) }).strict(),\n])\nexport const mcpPageSchema = z.object({ cursor: z.string().max(4096).optional(), limit: z.number().int().min(1).max(100).default(25) })\nexport const mcpSearchSchema = mcpPageSchema.extend({\n query: z.string().trim().min(1).max(500),\n types: z.array(z.enum(['request', 'feedback_answer', 'survey_answer', 'roadmap', 'article', 'changelog'])).max(6).optional(),\n variant: z.enum(['draft', 'published', 'record']).optional(),\n})\n","/** Delivery platform is independent of the customer's integration framework. */\nexport type DeliveryPlatform = 'ios' | 'android' | 'web'\nexport type WebLayout = 'modal' | 'card' | 'panel'\nexport interface WebPresentation {\n readonly layout?: WebLayout\n readonly size?: 'compact' | 'standard' | 'wide'\n readonly position?: 'left' | 'right'\n readonly backdrop?: boolean\n}\nexport interface CampaignDeliveryOptions {\n readonly deliveryPlatforms?: ReadonlyArray<DeliveryPlatform>\n readonly webPresentation?: WebPresentation | null\n}\nexport interface WebAppConfig {\n /** Exact origins, including scheme and non-default port. */\n readonly allowedOrigins: ReadonlyArray<string>\n}\nexport const DELIVERY_PROTOCOL_VERSION = 2 as const\nexport function deliveryPlatformsForApp(platforms: ReadonlyArray<string>): DeliveryPlatform[] {\n const values = new Set<DeliveryPlatform>()\n for (const platform of platforms) {\n if (platform === 'web' || platform === 'ios' || platform === 'android') values.add(platform)\n if (platform === 'expo' || platform === 'react-native' || platform === 'flutter') {\n values.add('ios'); values.add('android')\n }\n }\n return [...values]\n}\nexport function resolveWebPresentation(pillar: 'feedback' | 'survey' | 'inapp' | 'requests', override?: WebPresentation | null) {\n return {\n layout: override?.layout ?? 'modal',\n size: override?.size ?? (pillar === 'requests' ? 'wide' : 'standard'),\n position: override?.position ?? 'right',\n backdrop: override?.backdrop ?? override?.layout !== 'card',\n } as const\n}\n","import { z } from 'zod'\nimport type {\n PersonalizationBinding,\n PersonalizationIssue,\n PersonalizationResolution,\n PersonalizationScalar,\n PersonalizationSourceValue,\n PersonalizationSpec,\n} from './types/personalization.js'\n\nconst id = z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/)\nconst key = z\n .string()\n .min(1)\n .max(120)\n .refine(\n (v) => !['__proto__', 'prototype', 'constructor'].includes(v),\n 'Reserved property key',\n )\nconst scalar = z.union([\n z.string().max(8192),\n z.number().finite(),\n z.boolean(),\n z.null(),\n])\nconst baseSource = { id, label: z.string().min(1).max(120) }\nconst filterSchema = z.object({\n key,\n op: z.enum([\n 'eq',\n 'neq',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'in',\n 'nin',\n 'contains',\n 'starts_with',\n 'exists',\n 'not_exists',\n ]),\n value: z\n .union([\n z.string(),\n z.number().finite(),\n z.boolean(),\n z.array(z.union([z.string(), z.number().finite()])).max(100),\n ])\n .optional(),\n})\n\nexport const personalizationSpecSchema = z\n .object({\n version: z.literal(1),\n sources: z\n .array(\n z.discriminatedUnion('kind', [\n z.object({ ...baseSource, kind: z.literal('user_property') }),\n z.object({ ...baseSource, kind: z.literal('trigger_event') }),\n z.object({ ...baseSource, kind: z.literal('send_data') }),\n z.object({ ...baseSource, kind: z.literal('app') }),\n z.object({ ...baseSource, kind: z.literal('now') }),\n z.object({\n ...baseSource,\n kind: z.literal('latest_event'),\n eventName: z.string().min(1).max(120),\n lookbackDays: z.number().int().min(1).max(90),\n filters: z.array(filterSchema).max(8).optional(),\n }),\n ]),\n )\n .max(16),\n bindings: z\n .array(\n z.object({\n id,\n label: z.string().min(1).max(120),\n sourceId: id,\n key,\n type: z.enum(['string', 'number', 'boolean', 'date']),\n fallback: scalar.optional(),\n }),\n )\n .max(64),\n missingData: z.literal('skip'),\n })\n .superRefine((spec, ctx) => {\n const sources = new Set(spec.sources.map((source) => source.id))\n if (sources.size !== spec.sources.length)\n ctx.addIssue({\n code: 'custom',\n path: ['sources'],\n message: 'Source IDs must be unique',\n })\n if (\n spec.sources.filter((source) => source.kind === 'latest_event').length > 4\n )\n ctx.addIssue({\n code: 'custom',\n path: ['sources'],\n message: 'Use at most four activity sources',\n })\n const bindings = new Set<string>()\n spec.bindings.forEach((binding, index) => {\n if (bindings.has(binding.id))\n ctx.addIssue({\n code: 'custom',\n path: ['bindings', index, 'id'],\n message: 'Field IDs must be unique',\n })\n bindings.add(binding.id)\n if (!sources.has(binding.sourceId))\n ctx.addIssue({\n code: 'custom',\n path: ['bindings', index, 'sourceId'],\n message: 'Choose an existing source',\n })\n if (\n binding.fallback !== undefined &&\n (isMissing(binding.fallback) ||\n !matchesType(binding.fallback, binding.type))\n )\n ctx.addIssue({\n code: 'custom',\n path: ['bindings', index, 'fallback'],\n message: 'Fallback must be a non-empty value of the selected type',\n })\n })\n })\n\nexport const userPropertiesUpdateSchema = z\n .object({\n mutationId: z.string().uuid(),\n set: z\n .record(key, scalar)\n .refine(\n (v) => Object.keys(v).length <= 64,\n 'Update at most 64 properties',\n )\n .optional(),\n unset: z.array(key).max(64).optional(),\n })\n .superRefine((update, ctx) => {\n if (!Object.keys(update.set ?? {}).length && !update.unset?.length)\n ctx.addIssue({\n code: 'custom',\n message: 'Supply properties to set or remove',\n })\n if (update.unset?.some((name) => Object.hasOwn(update.set ?? {}, name)))\n ctx.addIssue({\n code: 'custom',\n message: 'A property cannot be set and removed in the same update',\n })\n })\n\nfunction isMissing(value: unknown): boolean {\n return value == null || (typeof value === 'string' && !value.trim())\n}\n\nfunction matchesType(\n value: unknown,\n type: PersonalizationBinding['type'],\n): boolean {\n if (type === 'date')\n return typeof value === 'string' && !Number.isNaN(Date.parse(value))\n return (\n typeof value === type &&\n (typeof value !== 'number' || Number.isFinite(value))\n )\n}\n\nexport function resolvePersonalizationBindings(\n spec: PersonalizationSpec,\n sources: Readonly<Record<string, PersonalizationSourceValue>>,\n): PersonalizationResolution {\n const values: Record<string, PersonalizationScalar> = Object.create(null)\n const issues: PersonalizationIssue[] = []\n const fallbackBindingIds: string[] = []\n for (const binding of spec.bindings) {\n const source = sources[binding.sourceId]?.values\n const value =\n source && Object.hasOwn(source, binding.key)\n ? source[binding.key]\n : undefined\n const missing = isMissing(value)\n if (!missing && matchesType(value, binding.type))\n values[binding.id] = value!\n else if (missing && binding.fallback !== undefined) {\n values[binding.id] = binding.fallback\n fallbackBindingIds.push(binding.id)\n } else\n issues.push({\n code: missing ? 'missing' : 'type_mismatch',\n bindingId: binding.id,\n message: missing\n ? `${binding.label} is missing`\n : `${binding.label} must be ${binding.type}`,\n })\n }\n return {\n status: issues.length\n ? 'skipped'\n : fallbackBindingIds.length\n ? 'using_fallback'\n : 'ready',\n values,\n fallbackBindingIds,\n issues,\n sources,\n }\n}\n\nconst TOKEN = /\\{\\{\\s*p\\.([A-Za-z][A-Za-z0-9_]*)\\s*\\}\\}/g\nconst WHOLE_TOKEN = /^\\{\\{\\s*p\\.([A-Za-z][A-Za-z0-9_]*)\\s*\\}\\}$/\n\nexport function personalizationToken(bindingId: string): string {\n return `{{p.${bindingId}}}`\n}\n\n/** Resolve only explicit template values. JSON keys and substituted values are never evaluated. */\nexport function renderPersonalizedValue(\n input: unknown,\n values: Readonly<Record<string, PersonalizationScalar>>,\n issues: PersonalizationIssue[],\n path = '',\n mode: 'text' | 'json' | 'url' = 'text',\n): unknown {\n if (typeof input === 'string') {\n const whole = WHOLE_TOKEN.exec(input)\n const lookup = (bindingId: string): PersonalizationScalar => {\n if (Object.hasOwn(values, bindingId)) return values[bindingId]!\n issues.push({\n code: 'unknown_binding',\n bindingId,\n path,\n message: `No value is available for ${bindingId}`,\n })\n return null\n }\n if (mode === 'json' && whole) return lookup(whole[1]!)\n // Inspect the template before replacing: a supplied value may legitimately contain braces.\n if (/\\{\\{|\\}\\}/.test(input.replace(TOKEN, '')))\n issues.push({\n code: 'invalid_template',\n path,\n message: 'Insert a valid dynamic field',\n })\n const result = input.replace(TOKEN, (_, bindingId: string) => {\n const value = lookup(bindingId)\n return mode === 'url' && !whole\n ? encodeURIComponent(String(value ?? ''))\n : String(value ?? '')\n })\n if (mode === 'url' && result) {\n try {\n const url = new URL(result)\n if (\n ['javascript:', 'data:', 'file:', 'vbscript:'].includes(url.protocol)\n )\n throw new Error('unsafe')\n // The origin/scheme must be static unless the entire field is a URL binding.\n if (!whole && /\\{\\{/.test(input.split(/:\\/\\//)[0] ?? ''))\n throw new Error('dynamic scheme')\n if (\n !whole &&\n /\\{\\{/.test(\n input.match(/^[a-z][a-z0-9+.-]*:\\/\\/([^/?#]*)/i)?.[1] ?? '',\n )\n )\n throw new Error('dynamic authority')\n } catch {\n issues.push({\n code: 'invalid_destination',\n path,\n message:\n 'The resolved destination must be a valid app link or web URL',\n })\n }\n }\n return result\n }\n if (Array.isArray(input))\n return input.map((item, index) =>\n renderPersonalizedValue(item, values, issues, `${path}/${index}`, mode),\n )\n if (input && typeof input === 'object') {\n const result: Record<string, unknown> = Object.create(null)\n for (const [name, value] of Object.entries(input)) {\n if (['__proto__', 'constructor', 'prototype'].includes(name)) {\n issues.push({\n code: 'invalid_template',\n path,\n message: 'Reserved object key',\n })\n continue\n }\n result[name] = renderPersonalizedValue(\n value,\n values,\n issues,\n `${path}/${name}`,\n mode,\n )\n }\n return result\n }\n return input\n}\n\n/** Display-only keys: identifiers, scores, branching and targeting are always kept verbatim. */\nconst TEXT_KEYS = new Set([\n 'title',\n 'body',\n 'subtitle',\n 'headline',\n 'label',\n 'placeholder',\n 'followUp',\n 'lowLabel',\n 'highLabel',\n 'description',\n 'buttonText',\n 'submitLabel',\n 'nextLabel',\n 'backLabel',\n 'text',\n])\nconst URL_KEYS = new Set(['imageUrl', 'deepLink', 'target'])\nconst CONTENT_KEYS = new Set([\n 'questions',\n 'options',\n 'ctas',\n 'cta',\n 'actionButtons',\n 'flow',\n 'welcome',\n 'thankYou',\n 'completion',\n 'endScreen',\n 'openAction',\n])\n\n/** Records where a field is used, excluding campaign metadata and targeting. */\nexport function personalizationUsage(\n content: unknown,\n): Map<string, Set<string>> {\n const usage = new Map<string, Set<string>>()\n const scan = (value: unknown, field: string) => {\n if (typeof value === 'string') {\n for (const match of value.matchAll(TOKEN)) {\n const fields = usage.get(match[1]!) ?? new Set<string>()\n fields.add(field)\n usage.set(match[1]!, fields)\n }\n } else if (Array.isArray(value)) value.forEach((item) => scan(item, field))\n else if (value && typeof value === 'object')\n Object.values(value).forEach((item) => scan(item, field))\n }\n const walk = (value: unknown) => {\n if (Array.isArray(value)) {\n value.forEach(walk)\n return\n }\n if (!value || typeof value !== 'object') return\n for (const [key, item] of Object.entries(value)) {\n if (\n TEXT_KEYS.has(key) ||\n URL_KEYS.has(key) ||\n key === 'actionJson' ||\n key === 'payloadExtras'\n )\n scan(item, key)\n else if (CONTENT_KEYS.has(key)) walk(item)\n }\n }\n walk(content)\n return usage\n}\n\nexport function renderPersonalizedContent<T>(\n content: T,\n resolution: PersonalizationResolution,\n): {\n content: T\n resolution: PersonalizationResolution\n} {\n const usage = personalizationUsage(content)\n const onlyOptionalImage = (id: string) =>\n usage.get(id)?.size === 1 && usage.get(id)?.has('imageUrl')\n const issues = resolution.issues.filter(\n (issue) =>\n !issue.bindingId ||\n (usage.has(issue.bindingId) &&\n !(issue.code === 'missing' && onlyOptionalImage(issue.bindingId))),\n )\n const fallbacks = resolution.fallbackBindingIds.filter((id) => usage.has(id))\n const walk = (value: unknown, path = ''): unknown => {\n if (Array.isArray(value))\n return value.map((item, index) => walk(item, `${path}/${index}`))\n if (!value || typeof value !== 'object') return value\n return Object.fromEntries(\n Object.entries(value).map(([name, item]) => {\n const childPath = `${path}/${name}`\n if (TEXT_KEYS.has(name) && typeof item === 'string')\n return [\n name,\n renderPersonalizedValue(item, resolution.values, issues, childPath),\n ]\n if (URL_KEYS.has(name) && typeof item === 'string') {\n if (\n name === 'imageUrl' &&\n [...item.matchAll(TOKEN)].some((match) =>\n resolution.issues.some(\n (issue) =>\n issue.bindingId === match[1] && issue.code === 'missing',\n ),\n )\n )\n return [name, null]\n // custom_event targets are event identifiers, not destinations.\n const isEvent =\n name === 'target' &&\n (value as { action?: string }).action === 'custom_event'\n const rendered = renderPersonalizedValue(\n item,\n resolution.values,\n issues,\n childPath,\n isEvent ? 'text' : 'url',\n )\n if (\n name === 'imageUrl' &&\n rendered &&\n !String(rendered).startsWith('https://')\n )\n issues.push({\n code: 'invalid_destination',\n path: childPath,\n message: 'Image URLs must use HTTPS',\n })\n return [name, rendered]\n }\n if (name === 'actionJson' || name === 'payloadExtras')\n return [\n name,\n renderPersonalizedValue(\n item,\n resolution.values,\n issues,\n childPath,\n 'json',\n ),\n ]\n if (CONTENT_KEYS.has(name)) return [name, walk(item, childPath)]\n return [name, item]\n }),\n )\n }\n const rendered = walk(content) as T\n return {\n content: rendered,\n resolution: {\n ...resolution,\n fallbackBindingIds: fallbacks,\n status: issues.length\n ? 'skipped'\n : fallbacks.length\n ? 'using_fallback'\n : 'ready',\n issues,\n },\n }\n}\n","/** Runtime-only readiness state. Pausing never stops analytics or dismisses active UI. */\nexport class PresentationGate {\n private paused: boolean\n private identity = 0\n private revisions = { feedback: 0, survey: 0 }\n private readonly listeners = new Set<() => void>()\n\n constructor(paused = false) { this.paused = paused }\n get isPaused(): boolean { return this.paused }\n setPaused(paused: boolean): void {\n this.paused = paused\n this.notify()\n }\n invalidate(purpose?: 'feedback' | 'survey'): void {\n if (purpose) this.revisions[purpose]++\n else this.identity++\n this.notify()\n }\n validator(purpose: 'feedback' | 'survey'): () => boolean {\n const identity = this.identity\n const revision = this.revisions[purpose]\n return () => identity === this.identity && revision === this.revisions[purpose]\n }\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n runWhenReady(run: () => void, valid: () => boolean, cancel: () => void = () => {}): void {\n if (!valid()) { cancel(); return }\n if (!this.paused) { run(); return }\n const stop = this.subscribe(() => {\n if (valid() && this.paused) return\n stop()\n if (valid()) run()\n else cancel()\n })\n }\n waitUntilReady(valid: () => boolean): Promise<boolean> {\n if (!valid()) return Promise.resolve(false)\n if (!this.paused) return Promise.resolve(true)\n return new Promise((resolve) => {\n const stop = this.subscribe(() => {\n if (valid() && this.paused) return\n stop()\n resolve(valid())\n })\n })\n }\n private notify(): void {\n for (const listener of [...this.listeners]) listener()\n }\n}\n"]}