@smallwebco/tinypivot-server 1.0.57

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.
@@ -0,0 +1,180 @@
1
+ export { AIColumnSchema, AIProxyRequest, AIProxyResponse, AITableSchema, QueryRequest, QueryResponse, SchemaRequest, SchemaResponse } from '@smallwebco/tinypivot-core';
2
+
3
+ /**
4
+ * TinyPivot Server - Type Definitions
5
+ */
6
+
7
+ /**
8
+ * Generic request handler type
9
+ * Compatible with Express, Fastify, Next.js API routes, etc.
10
+ */
11
+ type RequestHandler = (req: Request) => Promise<Response>;
12
+
13
+ /**
14
+ * Table filtering options for controlling which tables are exposed
15
+ */
16
+ interface TableFilterOptions {
17
+ /**
18
+ * Only include tables matching these patterns (exact string or regex)
19
+ * If not provided, all tables in the specified schemas are included.
20
+ *
21
+ * Example: `['sales', 'customers', /^app_.+/]`
22
+ */
23
+ include?: (string | RegExp)[];
24
+ /**
25
+ * Exclude tables matching these patterns (applied after include)
26
+ *
27
+ * Example: `[/^_/, 'migrations', 'sessions']`
28
+ */
29
+ exclude?: (string | RegExp)[];
30
+ /**
31
+ * Only include tables from these schemas (default: ['public'])
32
+ *
33
+ * Example: `['public', 'analytics']`
34
+ */
35
+ schemas?: string[];
36
+ /**
37
+ * Descriptions to show to the AI for context
38
+ * Keys are table names, values are human-readable descriptions
39
+ */
40
+ descriptions?: Record<string, string>;
41
+ }
42
+ /**
43
+ * Options for creating the unified TinyPivot handler
44
+ */
45
+ interface TinyPivotHandlerOptions {
46
+ /**
47
+ * PostgreSQL connection string
48
+ * @default process.env.DATABASE_URL
49
+ */
50
+ connectionString?: string;
51
+ /**
52
+ * AI API key - auto-detects provider from key format:
53
+ * - `sk-ant-...` → Anthropic
54
+ * - `sk-or-...` → OpenRouter
55
+ * - `sk-...` → OpenAI
56
+ * @default process.env.AI_API_KEY
57
+ */
58
+ apiKey?: string;
59
+ /**
60
+ * Table filtering options
61
+ * By default, all tables in the 'public' schema are exposed.
62
+ */
63
+ tables?: TableFilterOptions;
64
+ /**
65
+ * Maximum rows to return from queries.
66
+ * If not set, no limit is enforced (queries may return large result sets).
67
+ */
68
+ maxRows?: number;
69
+ /**
70
+ * Query timeout in milliseconds.
71
+ * If not set, uses PostgreSQL default (no timeout).
72
+ */
73
+ timeout?: number;
74
+ /**
75
+ * Override the AI model.
76
+ *
77
+ * Priority: options.model > AI_MODEL env var > cheap default per provider
78
+ *
79
+ * Defaults (cheap/fast):
80
+ * - Anthropic: claude-3-haiku-20240307
81
+ * - OpenAI: gpt-4o-mini
82
+ * - OpenRouter: anthropic/claude-3-haiku
83
+ *
84
+ * @example 'claude-sonnet-4-20250514', 'gpt-4o'
85
+ */
86
+ model?: string;
87
+ /**
88
+ * Maximum tokens for AI responses
89
+ * @default 2048
90
+ */
91
+ maxTokens?: number;
92
+ /**
93
+ * Custom error handler
94
+ */
95
+ onError?: (error: Error) => void;
96
+ }
97
+ /**
98
+ * Request body for the unified endpoint
99
+ */
100
+ interface TinyPivotRequest {
101
+ /** Action to perform */
102
+ action: 'list-tables' | 'get-schema' | 'query' | 'chat';
103
+ tables?: string[];
104
+ sql?: string;
105
+ table?: string;
106
+ messages?: Array<{
107
+ role: 'user' | 'assistant' | 'system';
108
+ content: string;
109
+ }>;
110
+ }
111
+ /**
112
+ * Response for list-tables action
113
+ */
114
+ interface ListTablesResponse {
115
+ tables: Array<{
116
+ name: string;
117
+ description?: string;
118
+ }>;
119
+ error?: string;
120
+ }
121
+ /**
122
+ * Create a unified TinyPivot handler
123
+ *
124
+ * This single endpoint handles:
125
+ * - `action: 'list-tables'` - Auto-discover tables from PostgreSQL
126
+ * - `action: 'get-schema'` - Get column schema for tables
127
+ * - `action: 'query'` - Execute validated SELECT queries
128
+ * - `action: 'chat'` - Proxy to AI provider
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * // Next.js App Router - app/api/tinypivot/route.ts
133
+ * import { createTinyPivotHandler } from '@smallwebco/tinypivot-server'
134
+ *
135
+ * export const POST = createTinyPivotHandler()
136
+ * ```
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // With options
141
+ * const handler = createTinyPivotHandler({
142
+ * tables: {
143
+ * include: ['sales', 'customers', 'products'],
144
+ * exclude: [/^_/, 'migrations'],
145
+ * descriptions: {
146
+ * sales: 'Sales transactions with revenue data',
147
+ * }
148
+ * }
149
+ * })
150
+ * ```
151
+ */
152
+ declare function createTinyPivotHandler(options?: TinyPivotHandlerOptions): RequestHandler;
153
+
154
+ /**
155
+ * TinyPivot Server - SQL Validation
156
+ * Ensures queries are safe and read-only
157
+ */
158
+ interface ValidationResult {
159
+ valid: boolean;
160
+ error?: string;
161
+ }
162
+ /**
163
+ * Validate that a SQL query is safe to execute
164
+ */
165
+ declare function validateSQL(sql: string, allowedTables: string[]): ValidationResult;
166
+ /**
167
+ * Extract table names from a SELECT query
168
+ * This is a simplified parser - for production, consider using a proper SQL parser
169
+ */
170
+ declare function extractTableNames(sql: string): string[];
171
+ /**
172
+ * Sanitize a table name to prevent SQL injection
173
+ */
174
+ declare function sanitizeTableName(name: string): string;
175
+ /**
176
+ * Add LIMIT clause if not present
177
+ */
178
+ declare function ensureLimit(sql: string, maxRows: number): string;
179
+
180
+ export { type ListTablesResponse, type RequestHandler, type TableFilterOptions, type TinyPivotHandlerOptions, type TinyPivotRequest, type ValidationResult, createTinyPivotHandler, ensureLimit, extractTableNames, sanitizeTableName, validateSQL };
@@ -0,0 +1,180 @@
1
+ export { AIColumnSchema, AIProxyRequest, AIProxyResponse, AITableSchema, QueryRequest, QueryResponse, SchemaRequest, SchemaResponse } from '@smallwebco/tinypivot-core';
2
+
3
+ /**
4
+ * TinyPivot Server - Type Definitions
5
+ */
6
+
7
+ /**
8
+ * Generic request handler type
9
+ * Compatible with Express, Fastify, Next.js API routes, etc.
10
+ */
11
+ type RequestHandler = (req: Request) => Promise<Response>;
12
+
13
+ /**
14
+ * Table filtering options for controlling which tables are exposed
15
+ */
16
+ interface TableFilterOptions {
17
+ /**
18
+ * Only include tables matching these patterns (exact string or regex)
19
+ * If not provided, all tables in the specified schemas are included.
20
+ *
21
+ * Example: `['sales', 'customers', /^app_.+/]`
22
+ */
23
+ include?: (string | RegExp)[];
24
+ /**
25
+ * Exclude tables matching these patterns (applied after include)
26
+ *
27
+ * Example: `[/^_/, 'migrations', 'sessions']`
28
+ */
29
+ exclude?: (string | RegExp)[];
30
+ /**
31
+ * Only include tables from these schemas (default: ['public'])
32
+ *
33
+ * Example: `['public', 'analytics']`
34
+ */
35
+ schemas?: string[];
36
+ /**
37
+ * Descriptions to show to the AI for context
38
+ * Keys are table names, values are human-readable descriptions
39
+ */
40
+ descriptions?: Record<string, string>;
41
+ }
42
+ /**
43
+ * Options for creating the unified TinyPivot handler
44
+ */
45
+ interface TinyPivotHandlerOptions {
46
+ /**
47
+ * PostgreSQL connection string
48
+ * @default process.env.DATABASE_URL
49
+ */
50
+ connectionString?: string;
51
+ /**
52
+ * AI API key - auto-detects provider from key format:
53
+ * - `sk-ant-...` → Anthropic
54
+ * - `sk-or-...` → OpenRouter
55
+ * - `sk-...` → OpenAI
56
+ * @default process.env.AI_API_KEY
57
+ */
58
+ apiKey?: string;
59
+ /**
60
+ * Table filtering options
61
+ * By default, all tables in the 'public' schema are exposed.
62
+ */
63
+ tables?: TableFilterOptions;
64
+ /**
65
+ * Maximum rows to return from queries.
66
+ * If not set, no limit is enforced (queries may return large result sets).
67
+ */
68
+ maxRows?: number;
69
+ /**
70
+ * Query timeout in milliseconds.
71
+ * If not set, uses PostgreSQL default (no timeout).
72
+ */
73
+ timeout?: number;
74
+ /**
75
+ * Override the AI model.
76
+ *
77
+ * Priority: options.model > AI_MODEL env var > cheap default per provider
78
+ *
79
+ * Defaults (cheap/fast):
80
+ * - Anthropic: claude-3-haiku-20240307
81
+ * - OpenAI: gpt-4o-mini
82
+ * - OpenRouter: anthropic/claude-3-haiku
83
+ *
84
+ * @example 'claude-sonnet-4-20250514', 'gpt-4o'
85
+ */
86
+ model?: string;
87
+ /**
88
+ * Maximum tokens for AI responses
89
+ * @default 2048
90
+ */
91
+ maxTokens?: number;
92
+ /**
93
+ * Custom error handler
94
+ */
95
+ onError?: (error: Error) => void;
96
+ }
97
+ /**
98
+ * Request body for the unified endpoint
99
+ */
100
+ interface TinyPivotRequest {
101
+ /** Action to perform */
102
+ action: 'list-tables' | 'get-schema' | 'query' | 'chat';
103
+ tables?: string[];
104
+ sql?: string;
105
+ table?: string;
106
+ messages?: Array<{
107
+ role: 'user' | 'assistant' | 'system';
108
+ content: string;
109
+ }>;
110
+ }
111
+ /**
112
+ * Response for list-tables action
113
+ */
114
+ interface ListTablesResponse {
115
+ tables: Array<{
116
+ name: string;
117
+ description?: string;
118
+ }>;
119
+ error?: string;
120
+ }
121
+ /**
122
+ * Create a unified TinyPivot handler
123
+ *
124
+ * This single endpoint handles:
125
+ * - `action: 'list-tables'` - Auto-discover tables from PostgreSQL
126
+ * - `action: 'get-schema'` - Get column schema for tables
127
+ * - `action: 'query'` - Execute validated SELECT queries
128
+ * - `action: 'chat'` - Proxy to AI provider
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * // Next.js App Router - app/api/tinypivot/route.ts
133
+ * import { createTinyPivotHandler } from '@smallwebco/tinypivot-server'
134
+ *
135
+ * export const POST = createTinyPivotHandler()
136
+ * ```
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // With options
141
+ * const handler = createTinyPivotHandler({
142
+ * tables: {
143
+ * include: ['sales', 'customers', 'products'],
144
+ * exclude: [/^_/, 'migrations'],
145
+ * descriptions: {
146
+ * sales: 'Sales transactions with revenue data',
147
+ * }
148
+ * }
149
+ * })
150
+ * ```
151
+ */
152
+ declare function createTinyPivotHandler(options?: TinyPivotHandlerOptions): RequestHandler;
153
+
154
+ /**
155
+ * TinyPivot Server - SQL Validation
156
+ * Ensures queries are safe and read-only
157
+ */
158
+ interface ValidationResult {
159
+ valid: boolean;
160
+ error?: string;
161
+ }
162
+ /**
163
+ * Validate that a SQL query is safe to execute
164
+ */
165
+ declare function validateSQL(sql: string, allowedTables: string[]): ValidationResult;
166
+ /**
167
+ * Extract table names from a SELECT query
168
+ * This is a simplified parser - for production, consider using a proper SQL parser
169
+ */
170
+ declare function extractTableNames(sql: string): string[];
171
+ /**
172
+ * Sanitize a table name to prevent SQL injection
173
+ */
174
+ declare function sanitizeTableName(name: string): string;
175
+ /**
176
+ * Add LIMIT clause if not present
177
+ */
178
+ declare function ensureLimit(sql: string, maxRows: number): string;
179
+
180
+ export { type ListTablesResponse, type RequestHandler, type TableFilterOptions, type TinyPivotHandlerOptions, type TinyPivotRequest, type ValidationResult, createTinyPivotHandler, ensureLimit, extractTableNames, sanitizeTableName, validateSQL };