@dataferry/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -0
- package/dist/index.cjs +464 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +534 -0
- package/dist/index.d.ts +534 -0
- package/dist/index.js +433 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/resources/portalSessions.ts","../src/resources/exports.ts","../src/resources/connections.ts","../src/client.ts"],"sourcesContent":["// Primary exports\nexport {\n Ferry,\n FerryError,\n type FerryConfig,\n type CreatePortalSessionParams,\n type PortalSessionResult,\n} from './client.js';\n\n// Resource classes for advanced usage\nexport { PortalSessions } from './resources/portalSessions.js';\nexport { Exports } from './resources/exports.js';\nexport { Connections } from './resources/connections.js';\n\n// Re-export common types\nexport type {\n ExportJob,\n ExportStatus,\n ExportFormat,\n CreateExportRequest,\n CreatePortalSessionRequest,\n CreatePortalSessionResponse,\n SchemaConfig,\n WebhookEndpoint,\n WebhookEvent,\n DatabaseConnection,\n CreateConnectionRequest,\n UpdateConnectionRequest,\n TestConnectionResult,\n} from './types.js';\n","/**\n * Portal Sessions resource\n */\n\nimport type { Ferry } from '../client.js';\nimport type {\n CreatePortalSessionRequest,\n CreatePortalSessionResponse,\n PortalSession,\n} from '../types.js';\n\nexport class PortalSessions {\n constructor(private readonly client: Ferry) {}\n\n /**\n * Create a new portal session for an end user\n *\n * @example\n * ```ts\n * const session = await ferry.portalSessions.create({\n * profile: 'default',\n * scopeId: 'user_123',\n * expiresIn: 3600,\n * returnUrl: 'https://yourapp.com/settings',\n * });\n *\n * // Redirect user to session.url\n * ```\n */\n async create(\n params: CreatePortalSessionRequest\n ): Promise<CreatePortalSessionResponse> {\n return this.client.request<CreatePortalSessionResponse>(\n 'POST',\n '/api/v1/portal-sessions',\n params\n );\n }\n\n /**\n * Get portal session details\n *\n * @example\n * ```ts\n * const session = await ferry.portalSessions.retrieve('ps_abc123');\n * console.log(session.scopeId, session.expiresAt);\n * ```\n */\n async retrieve(\n sessionId: string\n ): Promise<PortalSession & { isExpired: boolean }> {\n return this.client.request<PortalSession & { isExpired: boolean }>(\n 'GET',\n `/api/v1/portal-sessions/${sessionId}`\n );\n }\n\n /**\n * Revoke a portal session\n *\n * @example\n * ```ts\n * await ferry.portalSessions.revoke('ps_abc123');\n * ```\n */\n async revoke(sessionId: string): Promise<{ id: string }> {\n return this.client.request<{ id: string }>(\n 'DELETE',\n `/api/v1/portal-sessions/${sessionId}`\n );\n }\n}\n","/**\n * Exports resource\n */\n\nimport type { Ferry } from '../client.js';\nimport type {\n CreateExportRequest,\n ExportStatus,\n} from '../types.js';\n\ninterface ExportResponse {\n id: string;\n status: ExportStatus;\n scopeId: string;\n /** Database connection ID used for this export */\n connectionId?: string;\n /** Database connection name (if connection still exists) */\n connectionName?: string;\n format: string;\n tables: string[];\n downloadUrl?: string;\n downloadUrlExpiresAt?: string;\n fileSizeBytes?: number;\n totalRows?: number;\n errorMessage?: string;\n errorCode?: string;\n createdAt: string;\n startedAt?: string;\n completedAt?: string;\n}\n\ninterface ListExportsParams extends Record<string, string | number | undefined> {\n scopeId?: string;\n /** Filter by database connection ID */\n connectionId?: string;\n status?: ExportStatus;\n page?: number;\n limit?: number;\n}\n\nexport class Exports {\n constructor(private readonly client: Ferry) {}\n\n /**\n * Create a new export job\n *\n * @example\n * ```ts\n * // Create export using primary connection\n * const exportJob = await ferry.exports.create({\n * scopeId: 'user_123',\n * format: 'csv',\n * tables: ['users', 'posts', 'comments'],\n * });\n *\n * // Create export using specific connection\n * const exportJob = await ferry.exports.create({\n * scopeId: 'user_123',\n * connectionId: 'conn_abc123',\n * format: 'csv',\n * tables: ['users', 'posts'],\n * });\n *\n * console.log(exportJob.id, exportJob.status);\n * ```\n */\n async create(params: CreateExportRequest): Promise<ExportResponse> {\n return this.client.request<ExportResponse>(\n 'POST',\n '/api/v1/exports',\n params\n );\n }\n\n /**\n * Get export job details\n *\n * @example\n * ```ts\n * const exportJob = await ferry.exports.retrieve('exp_abc123');\n *\n * if (exportJob.status === 'completed') {\n * console.log('Download:', exportJob.downloadUrl);\n * }\n * ```\n */\n async retrieve(exportId: string): Promise<ExportResponse> {\n return this.client.request<ExportResponse>(\n 'GET',\n `/api/v1/exports/${exportId}`\n );\n }\n\n /**\n * List exports\n *\n * @example\n * ```ts\n * // List all exports\n * const { data, meta } = await ferry.exports.list();\n *\n * // Filter by scope\n * const { data } = await ferry.exports.list({ scopeId: 'user_123' });\n *\n * // Filter by status\n * const { data } = await ferry.exports.list({ status: 'completed' });\n *\n * // Filter by connection\n * const { data } = await ferry.exports.list({ connectionId: 'conn_abc123' });\n * ```\n */\n async list(params?: ListExportsParams): Promise<{\n data: ExportResponse[];\n meta: { page: number; limit: number; total: number; totalPages: number } | undefined;\n }> {\n return this.client.requestPaginated<ExportResponse>(\n '/api/v1/exports',\n params\n );\n }\n\n /**\n * Wait for an export to complete\n *\n * @example\n * ```ts\n * const exportJob = await ferry.exports.create({ scopeId: 'user_123' });\n * const completed = await ferry.exports.poll(exportJob.id, { maxWait: 300000 });\n *\n * if (completed.status === 'completed') {\n * console.log('Download:', completed.downloadUrl);\n * }\n * ```\n */\n async poll(\n exportId: string,\n options: { maxWait?: number; interval?: number } = {}\n ): Promise<ExportResponse> {\n const maxWait = options.maxWait ?? 300000; // 5 minutes\n const interval = options.interval ?? 2000; // 2 seconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < maxWait) {\n const exportJob = await this.retrieve(exportId);\n\n if (\n exportJob.status === 'completed' ||\n exportJob.status === 'failed' ||\n exportJob.status === 'expired'\n ) {\n return exportJob;\n }\n\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n throw new Error(`Export ${exportId} did not complete within ${maxWait}ms`);\n }\n}\n","/**\n * Database Connections resource\n */\n\nimport type { Ferry } from '../client.js';\nimport type {\n DatabaseConnection,\n CreateConnectionRequest,\n UpdateConnectionRequest,\n TestConnectionResult,\n} from '../types.js';\n\nexport class Connections {\n constructor(private readonly client: Ferry) {}\n\n /**\n * List all database connections for the organization\n *\n * @example\n * ```ts\n * const connections = await ferry.connections.list();\n * for (const conn of connections) {\n * console.log(conn.name);\n * }\n * ```\n */\n async list(): Promise<DatabaseConnection[]> {\n const result = await this.client.requestPaginated<DatabaseConnection>(\n '/api/v1/connections'\n );\n return result.data;\n }\n\n /**\n * Create a new database connection\n *\n * @example\n * ```ts\n * const connection = await ferry.connections.create({\n * name: 'Production DB',\n * host: 'db.example.com',\n * port: '5432',\n * database: 'myapp',\n * user: 'ferry_readonly',\n * password: 'secret',\n * ssl: true,\n * });\n * ```\n */\n async create(params: CreateConnectionRequest): Promise<DatabaseConnection> {\n return this.client.request<DatabaseConnection>(\n 'POST',\n '/api/v1/connections',\n params\n );\n }\n\n /**\n * Get a database connection by ID\n *\n * @example\n * ```ts\n * const connection = await ferry.connections.retrieve('conn_abc123');\n * console.log(connection.host, connection.database);\n * ```\n */\n async retrieve(connectionId: string): Promise<DatabaseConnection> {\n return this.client.request<DatabaseConnection>(\n 'GET',\n `/api/v1/connections/${connectionId}`\n );\n }\n\n /**\n * Update a database connection\n *\n * @example\n * ```ts\n * const connection = await ferry.connections.update('conn_abc123', {\n * name: 'Production DB (Updated)',\n * });\n * ```\n */\n async update(\n connectionId: string,\n params: UpdateConnectionRequest\n ): Promise<DatabaseConnection> {\n return this.client.request<DatabaseConnection>(\n 'PUT',\n `/api/v1/connections/${connectionId}`,\n params\n );\n }\n\n /**\n * Delete a database connection\n *\n * @example\n * ```ts\n * const result = await ferry.connections.delete('conn_abc123');\n * console.log(result.deleted); // true\n * ```\n */\n async delete(connectionId: string): Promise<{ id: string; deleted: boolean }> {\n return this.client.request<{ id: string; deleted: boolean }>(\n 'DELETE',\n `/api/v1/connections/${connectionId}`\n );\n }\n\n /**\n * Test a database connection\n *\n * @example\n * ```ts\n * const result = await ferry.connections.test('conn_abc123');\n * if (result.connected) {\n * console.log(`Connected to ${result.database} as ${result.user}`);\n * } else {\n * console.error(`Connection failed: ${result.error}`);\n * }\n * ```\n */\n async test(connectionId: string): Promise<TestConnectionResult> {\n return this.client.request<TestConnectionResult>(\n 'POST',\n `/api/v1/connections/${connectionId}/test`\n );\n }\n\n}\n","/**\n * DataFerry SDK client\n */\n\nimport { PortalSessions } from './resources/portalSessions.js';\nimport { Exports } from './resources/exports.js';\nimport { Connections } from './resources/connections.js';\n\nexport interface FerryConfig {\n /** API key for authentication */\n apiKey: string;\n /** Base URL for the DataFerry API (default: https://api.dataferry.dev) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\ninterface ApiResponse<T> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n };\n meta?: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\n/**\n * Parameters for creating a portal session\n */\nexport interface CreatePortalSessionParams {\n /** Export profile name (required) */\n profile: string;\n /** The scope ID for data filtering (optional for single-tenant mode) */\n scopeId?: string;\n /** Return URL after export completes */\n returnUrl?: string;\n /** Custom session duration in seconds (default: 3600) */\n expiresIn?: number;\n /** End-user email for export completion notifications */\n email?: string;\n /** Custom metadata to attach to the session */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Portal session response\n */\nexport interface PortalSessionResult {\n /** Session ID */\n id: string;\n /** URL to redirect the user to */\n url: string;\n /** When the session expires */\n expiresAt: Date;\n}\n\nexport class Ferry {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n\n /** Portal session management */\n public readonly portalSessions: PortalSessions;\n\n /** Export management */\n public readonly exports: Exports;\n\n /** Database connection management */\n public readonly connections: Connections;\n\n constructor(config: FerryConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl ?? 'https://api.dataferry.dev';\n this.timeout = config.timeout ?? 30000;\n\n // Initialize resources\n this.portalSessions = new PortalSessions(this);\n this.exports = new Exports(this);\n this.connections = new Connections(this);\n }\n\n /**\n * Create a portal session for an end user to export their data.\n *\n * This is the primary method for initiating a data export. It creates a\n * secure session and returns a URL where the user can select and download\n * their data.\n *\n * @example\n * ```typescript\n * const ferry = new Ferry({ apiKey: 'your-api-key' });\n *\n * // Create a session for a specific user\n * const session = await ferry.createPortalSession({\n * profile: 'default',\n * scopeId: 'user_123',\n * returnUrl: 'https://app.example.com/settings',\n * });\n *\n * // Redirect the user to the portal\n * res.redirect(session.url);\n * ```\n *\n * @example\n * ```typescript\n * // Single-tenant mode (no scopeId required)\n * const session = await ferry.createPortalSession({\n * profile: 'default',\n * returnUrl: 'https://app.example.com/settings',\n * });\n * ```\n */\n async createPortalSession(\n params: CreatePortalSessionParams\n ): Promise<PortalSessionResult> {\n // Build request object, only including defined properties\n // (required by exactOptionalPropertyTypes)\n const request: {\n profile: string;\n scopeId?: string;\n returnUrl?: string;\n expiresIn?: number;\n email?: string;\n metadata?: Record<string, unknown>;\n } = { profile: params.profile };\n\n if (params.scopeId !== undefined) {\n request.scopeId = params.scopeId;\n }\n if (params.returnUrl !== undefined) {\n request.returnUrl = params.returnUrl;\n }\n if (params.expiresIn !== undefined) {\n request.expiresIn = params.expiresIn;\n }\n if (params.email !== undefined) {\n request.email = params.email;\n }\n if (params.metadata !== undefined) {\n request.metadata = params.metadata;\n }\n\n const response = await this.portalSessions.create(request);\n\n return {\n id: response.id,\n url: response.url,\n expiresAt: response.expiresAt,\n };\n }\n\n /**\n * Make an authenticated API request\n */\n async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Basic ${Buffer.from(this.apiKey + ':').toString('base64')}`,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: controller.signal,\n };\n if (body) {\n fetchOptions.body = JSON.stringify(body);\n }\n const response = await fetch(url, fetchOptions);\n\n const data = (await response.json()) as ApiResponse<T>;\n\n if (!response.ok || !data.success) {\n const error = new FerryError(\n data.error?.message ?? 'An error occurred',\n data.error?.code ?? 'UNKNOWN_ERROR',\n response.status\n );\n throw error;\n }\n\n return data.data!;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Make a paginated API request\n */\n async requestPaginated<T>(\n path: string,\n params?: Record<string, string | number | undefined>\n ): Promise<{ data: T[]; meta: ApiResponse<T>['meta'] }> {\n const searchParams = new URLSearchParams();\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n }\n\n const url = searchParams.toString() ? `${path}?${searchParams}` : path;\n\n const response = await fetch(`${this.baseUrl}${url}`, {\n headers: {\n Authorization: `Basic ${Buffer.from(this.apiKey + ':').toString('base64')}`,\n },\n });\n\n const result = (await response.json()) as ApiResponse<T[]>;\n\n if (!response.ok || !result.success) {\n throw new FerryError(\n result.error?.message ?? 'An error occurred',\n result.error?.code ?? 'UNKNOWN_ERROR',\n response.status\n );\n }\n\n return {\n data: result.data!,\n meta: result.meta,\n };\n }\n}\n\n/**\n * DataFerry SDK error\n */\nexport class FerryError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status: number\n ) {\n super(message);\n this.name = 'FerryError';\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataFerry SDK types
|
|
3
|
+
*
|
|
4
|
+
* These types are inlined from @dataferry/common so the SDK
|
|
5
|
+
* has zero runtime and type-level dependencies.
|
|
6
|
+
*/
|
|
7
|
+
type ExportStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'expired';
|
|
8
|
+
type ExportFormat = 'csv';
|
|
9
|
+
interface ExportMetadata {
|
|
10
|
+
requestIp?: string;
|
|
11
|
+
userAgent?: string;
|
|
12
|
+
portalSessionId?: string;
|
|
13
|
+
custom?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
interface ExportJob {
|
|
16
|
+
id: string;
|
|
17
|
+
organizationId: string;
|
|
18
|
+
scopeId: string;
|
|
19
|
+
connectionId?: string;
|
|
20
|
+
status: ExportStatus;
|
|
21
|
+
format: ExportFormat;
|
|
22
|
+
selectedTables: string[];
|
|
23
|
+
storageKey: string | null;
|
|
24
|
+
downloadUrl: string | null;
|
|
25
|
+
downloadUrlExpiresAt: Date | null;
|
|
26
|
+
fileSizeBytes: number | null;
|
|
27
|
+
totalRows: number | null;
|
|
28
|
+
errorMessage: string | null;
|
|
29
|
+
errorCode: string | null;
|
|
30
|
+
createdAt: Date;
|
|
31
|
+
startedAt: Date | null;
|
|
32
|
+
completedAt: Date | null;
|
|
33
|
+
metadata: ExportMetadata;
|
|
34
|
+
}
|
|
35
|
+
interface CreateExportRequest {
|
|
36
|
+
scopeId: string;
|
|
37
|
+
connectionId?: string;
|
|
38
|
+
format?: ExportFormat;
|
|
39
|
+
tables?: string[];
|
|
40
|
+
webhookUrl?: string;
|
|
41
|
+
metadata?: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
interface PortalSession {
|
|
44
|
+
id: string;
|
|
45
|
+
organizationId: string;
|
|
46
|
+
scopeId: string;
|
|
47
|
+
profileId: string;
|
|
48
|
+
token: string;
|
|
49
|
+
expiresAt: Date;
|
|
50
|
+
createdAt: Date;
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
interface CreatePortalSessionRequest {
|
|
54
|
+
profile: string;
|
|
55
|
+
scopeId?: string;
|
|
56
|
+
expiresIn?: number;
|
|
57
|
+
returnUrl?: string;
|
|
58
|
+
email?: string;
|
|
59
|
+
metadata?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
interface CreatePortalSessionResponse {
|
|
62
|
+
id: string;
|
|
63
|
+
url: string;
|
|
64
|
+
expiresAt: Date;
|
|
65
|
+
}
|
|
66
|
+
interface DatabaseConnection {
|
|
67
|
+
id: string;
|
|
68
|
+
organizationId: string;
|
|
69
|
+
name: string;
|
|
70
|
+
host: string;
|
|
71
|
+
port: string;
|
|
72
|
+
database: string;
|
|
73
|
+
user: string;
|
|
74
|
+
ssl: boolean;
|
|
75
|
+
lastTestedAt: Date | null;
|
|
76
|
+
lastTestSuccess: boolean | null;
|
|
77
|
+
createdAt: Date;
|
|
78
|
+
updatedAt: Date;
|
|
79
|
+
}
|
|
80
|
+
interface CreateConnectionRequest {
|
|
81
|
+
name: string;
|
|
82
|
+
host: string;
|
|
83
|
+
port?: string;
|
|
84
|
+
database: string;
|
|
85
|
+
user: string;
|
|
86
|
+
password: string;
|
|
87
|
+
ssl?: boolean;
|
|
88
|
+
}
|
|
89
|
+
interface UpdateConnectionRequest {
|
|
90
|
+
name?: string;
|
|
91
|
+
host?: string;
|
|
92
|
+
port?: string;
|
|
93
|
+
database?: string;
|
|
94
|
+
user?: string;
|
|
95
|
+
password?: string;
|
|
96
|
+
ssl?: boolean;
|
|
97
|
+
}
|
|
98
|
+
interface TestConnectionResult {
|
|
99
|
+
connected: boolean;
|
|
100
|
+
database?: string;
|
|
101
|
+
user?: string;
|
|
102
|
+
error?: string;
|
|
103
|
+
responseTimeMs?: number;
|
|
104
|
+
}
|
|
105
|
+
type OwnershipMode = 'direct_column' | 'fk_chain';
|
|
106
|
+
interface OwnershipEdge {
|
|
107
|
+
fromTable: string;
|
|
108
|
+
fromColumn: string;
|
|
109
|
+
toTable: string;
|
|
110
|
+
toColumn: string;
|
|
111
|
+
direction: 'direct' | 'inverse';
|
|
112
|
+
}
|
|
113
|
+
interface IncludedTable {
|
|
114
|
+
tableName: string;
|
|
115
|
+
label: string;
|
|
116
|
+
ownershipMode: OwnershipMode | null;
|
|
117
|
+
userColumn?: string;
|
|
118
|
+
ownershipPath?: OwnershipEdge[];
|
|
119
|
+
depth: number;
|
|
120
|
+
confidence: number;
|
|
121
|
+
includedColumns: string[] | null;
|
|
122
|
+
excludedColumns: string[];
|
|
123
|
+
}
|
|
124
|
+
interface TableGroup {
|
|
125
|
+
id: string;
|
|
126
|
+
label: string;
|
|
127
|
+
tableNames: string[];
|
|
128
|
+
}
|
|
129
|
+
interface SchemaConfig {
|
|
130
|
+
id: string;
|
|
131
|
+
organizationId: string;
|
|
132
|
+
anchorTable?: string;
|
|
133
|
+
anchorColumn?: string;
|
|
134
|
+
includedTables: IncludedTable[];
|
|
135
|
+
excludedTables: string[];
|
|
136
|
+
maxDepth: number;
|
|
137
|
+
createdAt: Date;
|
|
138
|
+
updatedAt: Date;
|
|
139
|
+
version: number;
|
|
140
|
+
groups?: TableGroup[];
|
|
141
|
+
}
|
|
142
|
+
type WebhookEvent = 'export.completed' | 'export.failed' | 'schema.updated';
|
|
143
|
+
interface WebhookStats {
|
|
144
|
+
totalDeliveries: number;
|
|
145
|
+
successfulDeliveries: number;
|
|
146
|
+
failedDeliveries: number;
|
|
147
|
+
lastDeliveryAt: Date | null;
|
|
148
|
+
lastSuccessAt: Date | null;
|
|
149
|
+
lastFailureReason: string | null;
|
|
150
|
+
}
|
|
151
|
+
interface WebhookEndpoint {
|
|
152
|
+
id: string;
|
|
153
|
+
organizationId: string;
|
|
154
|
+
url: string;
|
|
155
|
+
events: WebhookEvent[];
|
|
156
|
+
secret: string;
|
|
157
|
+
active: boolean;
|
|
158
|
+
createdAt: Date;
|
|
159
|
+
updatedAt: Date;
|
|
160
|
+
stats: WebhookStats;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Portal Sessions resource
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
declare class PortalSessions {
|
|
168
|
+
private readonly client;
|
|
169
|
+
constructor(client: Ferry);
|
|
170
|
+
/**
|
|
171
|
+
* Create a new portal session for an end user
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const session = await ferry.portalSessions.create({
|
|
176
|
+
* profile: 'default',
|
|
177
|
+
* scopeId: 'user_123',
|
|
178
|
+
* expiresIn: 3600,
|
|
179
|
+
* returnUrl: 'https://yourapp.com/settings',
|
|
180
|
+
* });
|
|
181
|
+
*
|
|
182
|
+
* // Redirect user to session.url
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
create(params: CreatePortalSessionRequest): Promise<CreatePortalSessionResponse>;
|
|
186
|
+
/**
|
|
187
|
+
* Get portal session details
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* const session = await ferry.portalSessions.retrieve('ps_abc123');
|
|
192
|
+
* console.log(session.scopeId, session.expiresAt);
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
retrieve(sessionId: string): Promise<PortalSession & {
|
|
196
|
+
isExpired: boolean;
|
|
197
|
+
}>;
|
|
198
|
+
/**
|
|
199
|
+
* Revoke a portal session
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* await ferry.portalSessions.revoke('ps_abc123');
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
revoke(sessionId: string): Promise<{
|
|
207
|
+
id: string;
|
|
208
|
+
}>;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Exports resource
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
interface ExportResponse {
|
|
216
|
+
id: string;
|
|
217
|
+
status: ExportStatus;
|
|
218
|
+
scopeId: string;
|
|
219
|
+
/** Database connection ID used for this export */
|
|
220
|
+
connectionId?: string;
|
|
221
|
+
/** Database connection name (if connection still exists) */
|
|
222
|
+
connectionName?: string;
|
|
223
|
+
format: string;
|
|
224
|
+
tables: string[];
|
|
225
|
+
downloadUrl?: string;
|
|
226
|
+
downloadUrlExpiresAt?: string;
|
|
227
|
+
fileSizeBytes?: number;
|
|
228
|
+
totalRows?: number;
|
|
229
|
+
errorMessage?: string;
|
|
230
|
+
errorCode?: string;
|
|
231
|
+
createdAt: string;
|
|
232
|
+
startedAt?: string;
|
|
233
|
+
completedAt?: string;
|
|
234
|
+
}
|
|
235
|
+
interface ListExportsParams extends Record<string, string | number | undefined> {
|
|
236
|
+
scopeId?: string;
|
|
237
|
+
/** Filter by database connection ID */
|
|
238
|
+
connectionId?: string;
|
|
239
|
+
status?: ExportStatus;
|
|
240
|
+
page?: number;
|
|
241
|
+
limit?: number;
|
|
242
|
+
}
|
|
243
|
+
declare class Exports {
|
|
244
|
+
private readonly client;
|
|
245
|
+
constructor(client: Ferry);
|
|
246
|
+
/**
|
|
247
|
+
* Create a new export job
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* // Create export using primary connection
|
|
252
|
+
* const exportJob = await ferry.exports.create({
|
|
253
|
+
* scopeId: 'user_123',
|
|
254
|
+
* format: 'csv',
|
|
255
|
+
* tables: ['users', 'posts', 'comments'],
|
|
256
|
+
* });
|
|
257
|
+
*
|
|
258
|
+
* // Create export using specific connection
|
|
259
|
+
* const exportJob = await ferry.exports.create({
|
|
260
|
+
* scopeId: 'user_123',
|
|
261
|
+
* connectionId: 'conn_abc123',
|
|
262
|
+
* format: 'csv',
|
|
263
|
+
* tables: ['users', 'posts'],
|
|
264
|
+
* });
|
|
265
|
+
*
|
|
266
|
+
* console.log(exportJob.id, exportJob.status);
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
create(params: CreateExportRequest): Promise<ExportResponse>;
|
|
270
|
+
/**
|
|
271
|
+
* Get export job details
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* const exportJob = await ferry.exports.retrieve('exp_abc123');
|
|
276
|
+
*
|
|
277
|
+
* if (exportJob.status === 'completed') {
|
|
278
|
+
* console.log('Download:', exportJob.downloadUrl);
|
|
279
|
+
* }
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
retrieve(exportId: string): Promise<ExportResponse>;
|
|
283
|
+
/**
|
|
284
|
+
* List exports
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* // List all exports
|
|
289
|
+
* const { data, meta } = await ferry.exports.list();
|
|
290
|
+
*
|
|
291
|
+
* // Filter by scope
|
|
292
|
+
* const { data } = await ferry.exports.list({ scopeId: 'user_123' });
|
|
293
|
+
*
|
|
294
|
+
* // Filter by status
|
|
295
|
+
* const { data } = await ferry.exports.list({ status: 'completed' });
|
|
296
|
+
*
|
|
297
|
+
* // Filter by connection
|
|
298
|
+
* const { data } = await ferry.exports.list({ connectionId: 'conn_abc123' });
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
list(params?: ListExportsParams): Promise<{
|
|
302
|
+
data: ExportResponse[];
|
|
303
|
+
meta: {
|
|
304
|
+
page: number;
|
|
305
|
+
limit: number;
|
|
306
|
+
total: number;
|
|
307
|
+
totalPages: number;
|
|
308
|
+
} | undefined;
|
|
309
|
+
}>;
|
|
310
|
+
/**
|
|
311
|
+
* Wait for an export to complete
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```ts
|
|
315
|
+
* const exportJob = await ferry.exports.create({ scopeId: 'user_123' });
|
|
316
|
+
* const completed = await ferry.exports.poll(exportJob.id, { maxWait: 300000 });
|
|
317
|
+
*
|
|
318
|
+
* if (completed.status === 'completed') {
|
|
319
|
+
* console.log('Download:', completed.downloadUrl);
|
|
320
|
+
* }
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
poll(exportId: string, options?: {
|
|
324
|
+
maxWait?: number;
|
|
325
|
+
interval?: number;
|
|
326
|
+
}): Promise<ExportResponse>;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Database Connections resource
|
|
331
|
+
*/
|
|
332
|
+
|
|
333
|
+
declare class Connections {
|
|
334
|
+
private readonly client;
|
|
335
|
+
constructor(client: Ferry);
|
|
336
|
+
/**
|
|
337
|
+
* List all database connections for the organization
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* const connections = await ferry.connections.list();
|
|
342
|
+
* for (const conn of connections) {
|
|
343
|
+
* console.log(conn.name);
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
list(): Promise<DatabaseConnection[]>;
|
|
348
|
+
/**
|
|
349
|
+
* Create a new database connection
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```ts
|
|
353
|
+
* const connection = await ferry.connections.create({
|
|
354
|
+
* name: 'Production DB',
|
|
355
|
+
* host: 'db.example.com',
|
|
356
|
+
* port: '5432',
|
|
357
|
+
* database: 'myapp',
|
|
358
|
+
* user: 'ferry_readonly',
|
|
359
|
+
* password: 'secret',
|
|
360
|
+
* ssl: true,
|
|
361
|
+
* });
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
create(params: CreateConnectionRequest): Promise<DatabaseConnection>;
|
|
365
|
+
/**
|
|
366
|
+
* Get a database connection by ID
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```ts
|
|
370
|
+
* const connection = await ferry.connections.retrieve('conn_abc123');
|
|
371
|
+
* console.log(connection.host, connection.database);
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
retrieve(connectionId: string): Promise<DatabaseConnection>;
|
|
375
|
+
/**
|
|
376
|
+
* Update a database connection
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```ts
|
|
380
|
+
* const connection = await ferry.connections.update('conn_abc123', {
|
|
381
|
+
* name: 'Production DB (Updated)',
|
|
382
|
+
* });
|
|
383
|
+
* ```
|
|
384
|
+
*/
|
|
385
|
+
update(connectionId: string, params: UpdateConnectionRequest): Promise<DatabaseConnection>;
|
|
386
|
+
/**
|
|
387
|
+
* Delete a database connection
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```ts
|
|
391
|
+
* const result = await ferry.connections.delete('conn_abc123');
|
|
392
|
+
* console.log(result.deleted); // true
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
395
|
+
delete(connectionId: string): Promise<{
|
|
396
|
+
id: string;
|
|
397
|
+
deleted: boolean;
|
|
398
|
+
}>;
|
|
399
|
+
/**
|
|
400
|
+
* Test a database connection
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```ts
|
|
404
|
+
* const result = await ferry.connections.test('conn_abc123');
|
|
405
|
+
* if (result.connected) {
|
|
406
|
+
* console.log(`Connected to ${result.database} as ${result.user}`);
|
|
407
|
+
* } else {
|
|
408
|
+
* console.error(`Connection failed: ${result.error}`);
|
|
409
|
+
* }
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
test(connectionId: string): Promise<TestConnectionResult>;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* DataFerry SDK client
|
|
417
|
+
*/
|
|
418
|
+
|
|
419
|
+
interface FerryConfig {
|
|
420
|
+
/** API key for authentication */
|
|
421
|
+
apiKey: string;
|
|
422
|
+
/** Base URL for the DataFerry API (default: https://api.dataferry.dev) */
|
|
423
|
+
baseUrl?: string;
|
|
424
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
425
|
+
timeout?: number;
|
|
426
|
+
}
|
|
427
|
+
interface ApiResponse<T> {
|
|
428
|
+
success: boolean;
|
|
429
|
+
data?: T;
|
|
430
|
+
error?: {
|
|
431
|
+
code: string;
|
|
432
|
+
message: string;
|
|
433
|
+
details?: Record<string, unknown>;
|
|
434
|
+
};
|
|
435
|
+
meta?: {
|
|
436
|
+
page: number;
|
|
437
|
+
limit: number;
|
|
438
|
+
total: number;
|
|
439
|
+
totalPages: number;
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Parameters for creating a portal session
|
|
444
|
+
*/
|
|
445
|
+
interface CreatePortalSessionParams {
|
|
446
|
+
/** Export profile name (required) */
|
|
447
|
+
profile: string;
|
|
448
|
+
/** The scope ID for data filtering (optional for single-tenant mode) */
|
|
449
|
+
scopeId?: string;
|
|
450
|
+
/** Return URL after export completes */
|
|
451
|
+
returnUrl?: string;
|
|
452
|
+
/** Custom session duration in seconds (default: 3600) */
|
|
453
|
+
expiresIn?: number;
|
|
454
|
+
/** End-user email for export completion notifications */
|
|
455
|
+
email?: string;
|
|
456
|
+
/** Custom metadata to attach to the session */
|
|
457
|
+
metadata?: Record<string, unknown>;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Portal session response
|
|
461
|
+
*/
|
|
462
|
+
interface PortalSessionResult {
|
|
463
|
+
/** Session ID */
|
|
464
|
+
id: string;
|
|
465
|
+
/** URL to redirect the user to */
|
|
466
|
+
url: string;
|
|
467
|
+
/** When the session expires */
|
|
468
|
+
expiresAt: Date;
|
|
469
|
+
}
|
|
470
|
+
declare class Ferry {
|
|
471
|
+
private readonly apiKey;
|
|
472
|
+
private readonly baseUrl;
|
|
473
|
+
private readonly timeout;
|
|
474
|
+
/** Portal session management */
|
|
475
|
+
readonly portalSessions: PortalSessions;
|
|
476
|
+
/** Export management */
|
|
477
|
+
readonly exports: Exports;
|
|
478
|
+
/** Database connection management */
|
|
479
|
+
readonly connections: Connections;
|
|
480
|
+
constructor(config: FerryConfig);
|
|
481
|
+
/**
|
|
482
|
+
* Create a portal session for an end user to export their data.
|
|
483
|
+
*
|
|
484
|
+
* This is the primary method for initiating a data export. It creates a
|
|
485
|
+
* secure session and returns a URL where the user can select and download
|
|
486
|
+
* their data.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript
|
|
490
|
+
* const ferry = new Ferry({ apiKey: 'your-api-key' });
|
|
491
|
+
*
|
|
492
|
+
* // Create a session for a specific user
|
|
493
|
+
* const session = await ferry.createPortalSession({
|
|
494
|
+
* profile: 'default',
|
|
495
|
+
* scopeId: 'user_123',
|
|
496
|
+
* returnUrl: 'https://app.example.com/settings',
|
|
497
|
+
* });
|
|
498
|
+
*
|
|
499
|
+
* // Redirect the user to the portal
|
|
500
|
+
* res.redirect(session.url);
|
|
501
|
+
* ```
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* // Single-tenant mode (no scopeId required)
|
|
506
|
+
* const session = await ferry.createPortalSession({
|
|
507
|
+
* profile: 'default',
|
|
508
|
+
* returnUrl: 'https://app.example.com/settings',
|
|
509
|
+
* });
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
createPortalSession(params: CreatePortalSessionParams): Promise<PortalSessionResult>;
|
|
513
|
+
/**
|
|
514
|
+
* Make an authenticated API request
|
|
515
|
+
*/
|
|
516
|
+
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
517
|
+
/**
|
|
518
|
+
* Make a paginated API request
|
|
519
|
+
*/
|
|
520
|
+
requestPaginated<T>(path: string, params?: Record<string, string | number | undefined>): Promise<{
|
|
521
|
+
data: T[];
|
|
522
|
+
meta: ApiResponse<T>['meta'];
|
|
523
|
+
}>;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* DataFerry SDK error
|
|
527
|
+
*/
|
|
528
|
+
declare class FerryError extends Error {
|
|
529
|
+
readonly code: string;
|
|
530
|
+
readonly status: number;
|
|
531
|
+
constructor(message: string, code: string, status: number);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export { Connections, type CreateConnectionRequest, type CreateExportRequest, type CreatePortalSessionParams, type CreatePortalSessionRequest, type CreatePortalSessionResponse, type DatabaseConnection, type ExportFormat, type ExportJob, type ExportStatus, Exports, Ferry, type FerryConfig, FerryError, type PortalSessionResult, PortalSessions, type SchemaConfig, type TestConnectionResult, type UpdateConnectionRequest, type WebhookEndpoint, type WebhookEvent };
|