@villagehq/extension-sdk
Version:
Village Chrome Extension SDK for Partner Integrations
310 lines (281 loc) • 9.35 kB
TypeScript
/**
* Result of a `checkPaths` lookup. Either a relationship payload (with token
* and userReference attached) or a redirect prompt when the user isn't
* signed in to Village.
*/
export declare type CheckPathsResult = {
relationship?: {
warmth_score?: number;
paths?: {
count?: number;
avatars?: string[];
};
[key: string]: unknown;
};
token?: string | false;
userReference?: string;
[key: string]: unknown;
} | {
message: string;
redirect: true;
} | null;
export declare const EXTERNAL_COMMANDS: readonly ["getExtensionStatus", "livelinessCheck", "fillUpEmail", "GET_MUTUAL_CONNECTIONS"];
export declare type ExternalCommand = ExternalRequest['message'];
export declare type ExternalRequest = {
message: 'getExtensionStatus';
shouldTriggerReset?: boolean;
} | {
message: 'livelinessCheck';
} | {
message: 'fillUpEmail';
email: string;
} | {
message: 'GET_MUTUAL_CONNECTIONS';
profileSlug: string;
};
export declare type ExternalResponse = ExternalResponseMap[ExternalCommand];
export declare type ExternalResponseMap = {
getExtensionStatus: UiSettings;
livelinessCheck: {
getProfileUserDetails: boolean;
getContactInfo: boolean;
getLinkedinLoggedinUserInfo: boolean;
getProfileConnections: boolean;
};
fillUpEmail: {
success: true;
};
GET_MUTUAL_CONNECTIONS: MutualConnectionsResult | {
error: true;
message: string;
};
};
export declare const INTERNAL_COMMANDS: readonly ["village:bind:extension", "saveUISettings", "getUserIntegration", "getSettings", "checkPaths", "tracking", "bridge:relay"];
export declare type InternalCommand = InternalRequest['command'];
export declare type InternalRequest = {
command: 'village:bind:extension';
data: VillageBindSettings;
} | {
command: 'saveUISettings';
data: UserLoggedObj;
} | {
command: 'getUserIntegration';
} | {
command: 'getSettings';
} | {
command: 'checkPaths';
url: string;
} | {
command: 'tracking';
eventName: string;
properties?: Record<string, unknown>;
/**
* @deprecated Ignored since anonymous capture was removed — events
* without a logged-in user id are always dropped. Kept so pre-existing
* hosts sending `force` still typecheck against this wire format.
*/
force?: boolean;
} | {
command: 'bridge:relay';
payload: ExternalRequest;
};
export declare type InternalResponseMap = {
'village:bind:extension': {
success: true;
} | {
error: string;
};
saveUISettings: {
success: true;
} | {
error: string;
};
getUserIntegration: {
success: true;
} | {
error: string;
};
getSettings: {
uiSettings: UiSettings;
};
checkPaths: CheckPathsResult;
tracking: {
success: true;
} | {
error: string;
};
'bridge:relay': ExternalResponse | {
error: string;
} | undefined;
};
export declare function isExternalRequest(m: unknown): m is ExternalRequest;
export declare function isInternalRequest(m: unknown): m is InternalRequest;
export declare type LocalKey = keyof LocalSchema;
/**
* Local-storage keys the SDK reads or writes. Backed by `browser.storage.local`
* — larger quota, never syncs. Use for per-device state and debug toggles.
*
* `sdk_debug_mode` is an internal SDK toggle controlled via the
* `self.villageExtension.enableDebug()` console API. Partner code should not
* read or write it.
*/
export declare interface LocalSchema {
sdk_debug_mode: boolean;
}
/**
* Result of `GET_MUTUAL_CONNECTIONS` — array of normalized connection objects
* pulled from LinkedIn voyager. Order and field availability depend on the
* endpoint variant (current vs legacy) — fields are best-effort.
*/
export declare type MutualConnection = {
name?: string;
slug?: string;
headline?: string;
location?: string;
profileUrl?: string;
distance?: string;
};
export declare type MutualConnectionsResult = MutualConnection[];
export declare type RequestFor<C extends InternalCommand> = Extract<InternalRequest, {
command: C;
}>;
export declare type ResponseFor<C extends InternalCommand> = InternalResponseMap[C];
/**
* @deprecated since 0.3.0 — use `SyncSchema` instead. Kept as an alias for the
* one-release soak so partner code that imports `StorageSchema` from
* `@villagehq/extension-sdk/messages` keeps compiling. Removed in a future
* release once partner repos have updated.
*/
export declare type StorageSchema = SyncSchema;
export declare type SwToContentMessage = {
type: 'pathsEverywhere';
} | {
type: 'fillUpEmail';
email: string;
} | {
type: 'bridge:push';
event: string;
data: unknown;
};
export declare type SyncKey = keyof SyncSchema;
/**
* Sync-storage keys the SDK reads or writes. Frozen public contract: partner
* extensions may read these directly via `chrome.storage.sync.get`.
*
* Backed by `browser.storage.sync` — small per-key quota, syncs across
* Chrome profile signed-in devices. Use for cross-device user state.
*/
export declare interface SyncSchema {
linkedin_login: boolean;
frontend_login: boolean;
linkedin_loggedin_email: string | null;
user_logged_obj: UserLoggedObj;
user_integration: UserIntegration;
saved_profile: boolean;
fetched_connections: boolean;
/**
* @deprecated since 0.3.0 — superseded by
* `'village.paths-everywhere.is-active'` (`'ENABLED' | 'DISABLED'` shape).
* `paths-trigger.ts` opportunistically migrates this key to the new one and
* deletes the legacy entry. Will be removed in a future Phase C release once
* Sentry breadcrumbs confirm zero in-the-wild migrations remain.
*/
isPathsEverywhereActive: boolean;
'village.paths-everywhere.is-active': 'ENABLED' | 'DISABLED';
VILLAGE_TOKEN: string;
'village:bind:extension': VillageBindSettings;
}
/**
* Snapshot of login + manifest state returned by `getSettings` / the
* `getExtensionStatus` external command. Boolean-ish because the underlying
* storage values may be `null` when never written.
*/
export declare interface UiSettings {
linkedin_login: boolean | null;
linkedin_loggedin_email: string | null;
frontend_login: boolean | null;
user_logged_obj: UserLoggedObj | null;
version: string;
}
/**
* Backend integration record for the current user — describes which sync
* pipelines have completed (profile, connection IDs, etc.). Persisted under
* the `user_integration` storage key.
*/
export declare interface UserIntegration {
sync_data?: {
user_profile?: unknown;
connection_ids?: {
is_finished?: boolean;
start_from?: number;
};
delta_sync?: {
cursor_ms?: number | null;
[key: string]: unknown;
};
[key: string]: unknown;
};
[key: string]: unknown;
}
/**
* Domain object shapes used by the message map.
*
* These are the runtime shapes the SDK observes from the Village backend and
* LinkedIn voyager API. They're intentionally permissive: most are partial
* snapshots of opaque server responses. Phase B will tighten these once the
* backend ships proper schemas.
*/
/**
* Authenticated Village user, persisted under the `user_logged_obj` storage
* key. The SDK reads `id`, `name`, and `app.config.*` for paths-everywhere
* branding; everything else is forwarded to partner code as-is.
*/
export declare interface UserLoggedObj {
id?: string;
name?: string;
email?: string;
app?: Record<string, unknown>;
cacheDate?: string;
[key: string]: unknown;
}
/**
* Payload carried by `village:bind:extension`. Opaque from the SDK's
* perspective — the host extension sets it, partner extensions read it back.
*
* @deprecated since 0.3.0 — use `VillageBindSettings` (`{ enabled: boolean }`)
* from `@villagehq/extension-sdk/messages`. Pre-0.3.0 hosts that send a
* JSON-stringified boolean still work via the one-release `bindExtension`
* shim and will be dropped in 0.4.0.
*/
export declare interface VillageBindData {
[key: string]: unknown;
}
/**
* Settings stored under the `village:bind:extension` sync-storage key.
* Re-declared (instead of imported from `messages.ts`) to keep this module
* free of cross-imports from the message map.
*/
export declare interface VillageBindSettings {
enabled: boolean;
}
export declare type VillageBridgeMessage = {
source: 'VillageBridge';
type: 'announce';
} | {
source: 'VillageBridge';
type: 'request';
correlationId: string;
payload: ExternalRequest;
} | {
source: 'VillageBridge';
type: 'response';
correlationId: string;
payload: ExternalResponse | null;
error?: string;
} | {
source: 'VillageBridge';
type: 'push';
event: string;
data: unknown;
};
export { }