@scarletdb/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 ADDED
@@ -0,0 +1,184 @@
1
+ # @scarlet/sdk
2
+
3
+ Official TypeScript SDK for [Scarlet DB](https://scarletdb.space) - The modern Backend-as-a-Service platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @scarlet/sdk
9
+ # or
10
+ pnpm add @scarlet/sdk
11
+ # or
12
+ yarn add @scarlet/sdk
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Scarlet } from '@scarlet/sdk';
19
+
20
+ // Initialize with your project API key
21
+ const db = new Scarlet({
22
+ apiKey: 'sk_live_your_api_key',
23
+ });
24
+
25
+ // Query data
26
+ const users = await db.from('users').select().limit(10);
27
+
28
+ // Insert data
29
+ await db.from('users').insert({
30
+ name: 'John Doe',
31
+ email: 'john@example.com',
32
+ });
33
+
34
+ // Update data
35
+ await db.from('users').update({ active: true }).where({ id: 1 });
36
+
37
+ // Delete data
38
+ await db.from('users').delete().where({ id: 1 });
39
+ ```
40
+
41
+ ## Features
42
+
43
+ ### 📊 Data API
44
+
45
+ Fluent query builder for CRUD operations on your database tables.
46
+
47
+ ```typescript
48
+ // Select with filters
49
+ const activeUsers = await db
50
+ .from('users')
51
+ .select('id', 'name', 'email')
52
+ .where({ active: true })
53
+ .orderBy('created_at', 'desc')
54
+ .limit(20);
55
+
56
+ // Insert single row
57
+ const newUser = await db.from('users').insert({
58
+ name: 'Jane',
59
+ email: 'jane@example.com',
60
+ }).single();
61
+
62
+ // Update with filters
63
+ await db.from('users')
64
+ .update({ last_login: new Date() })
65
+ .where({ id: userId });
66
+
67
+ // Delete with filters
68
+ await db.from('users').delete().where({ id: userId });
69
+ ```
70
+
71
+ ### 📁 Storage
72
+
73
+ Upload, download, and manage files in cloud storage.
74
+
75
+ ```typescript
76
+ // Upload a file
77
+ await db.storage.upload('avatars', file);
78
+
79
+ // Get public URL
80
+ const url = db.storage.getPublicUrl('avatars', 'avatar.png');
81
+
82
+ // List files in bucket
83
+ const files = await db.storage.list('avatars');
84
+
85
+ // Delete a file
86
+ await db.storage.delete('avatars', 'old-avatar.png');
87
+ ```
88
+
89
+ ### 📧 Email
90
+
91
+ Send transactional emails with custom domains.
92
+
93
+ ```typescript
94
+ // Send an email
95
+ await db.email.send({
96
+ from: 'hello@myapp.com',
97
+ to: 'user@email.com',
98
+ subject: 'Welcome to MyApp!',
99
+ html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
100
+ });
101
+
102
+ // List configured domains
103
+ const domains = await db.email.listDomains();
104
+ ```
105
+
106
+ ### 🤖 AI Queries
107
+
108
+ Natural language to SQL conversion powered by AI.
109
+
110
+ ```typescript
111
+ // Query with natural language
112
+ const result = await db.ai.query('Show me all users who signed up last week');
113
+
114
+ console.log(result.sql); // Generated SQL
115
+ console.log(result.rows); // Query results
116
+ ```
117
+
118
+ ### 🔧 Raw SQL
119
+
120
+ Execute raw SQL queries when you need full control.
121
+
122
+ ```typescript
123
+ // Parameterized query (safe)
124
+ const result = await db.sql(
125
+ 'SELECT * FROM users WHERE created_at > $1 AND status = $2',
126
+ [lastWeek, 'active']
127
+ );
128
+
129
+ // Access results
130
+ console.log(result.rows);
131
+ console.log(result.rowCount);
132
+ ```
133
+
134
+ ## Configuration
135
+
136
+ ```typescript
137
+ const db = new Scarlet({
138
+ // Required: Your project API key
139
+ apiKey: 'sk_live_...',
140
+
141
+ // Optional: Custom API URL (defaults to production)
142
+ baseUrl: 'https://api.scarletdb.space',
143
+
144
+ // Optional: Request timeout in ms (default: 30000)
145
+ timeout: 30000,
146
+ });
147
+ ```
148
+
149
+ ## Error Handling
150
+
151
+ ```typescript
152
+ import { Scarlet, ScarletError } from '@scarlet/sdk';
153
+
154
+ try {
155
+ await db.from('users').insert({ email: 'invalid' });
156
+ } catch (error) {
157
+ if (error instanceof ScarletError) {
158
+ console.error('Scarlet Error:', error.message);
159
+ console.error('Status:', error.status);
160
+ console.error('Code:', error.code);
161
+ }
162
+ }
163
+ ```
164
+
165
+ ## TypeScript Support
166
+
167
+ Full TypeScript support with generics for type-safe queries:
168
+
169
+ ```typescript
170
+ interface User {
171
+ id: number;
172
+ name: string;
173
+ email: string;
174
+ created_at: Date;
175
+ }
176
+
177
+ // Type-safe queries
178
+ const users = await db.from<User>('users').select();
179
+ // users is typed as User[]
180
+ ```
181
+
182
+ ## License
183
+
184
+ MIT
@@ -0,0 +1,459 @@
1
+ /**
2
+ * Scarlet SDK - Type Definitions
3
+ */
4
+ interface ScarletConfig {
5
+ /** Project API key (required) */
6
+ apiKey: string;
7
+ /** Base URL for the API (defaults to production) */
8
+ baseUrl?: string;
9
+ /** Request timeout in milliseconds (default: 30000) */
10
+ timeout?: number;
11
+ }
12
+ type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'in' | 'nin' | 'is' | 'isnot';
13
+ type FilterValue = string | number | boolean | null | (string | number)[];
14
+ interface WhereCondition {
15
+ [column: string]: FilterValue | {
16
+ [op in FilterOperator]?: FilterValue;
17
+ };
18
+ }
19
+ type OrderDirection = 'asc' | 'desc';
20
+ interface QueryResult<T = Record<string, unknown>> {
21
+ rows: T[];
22
+ total?: number;
23
+ limit?: number;
24
+ offset?: number;
25
+ hasMore?: boolean;
26
+ }
27
+ interface InsertResult<T = Record<string, unknown>> {
28
+ success: boolean;
29
+ row?: T;
30
+ rows?: T[];
31
+ }
32
+ interface UpdateResult {
33
+ success: boolean;
34
+ count: number;
35
+ }
36
+ interface DeleteResult {
37
+ success: boolean;
38
+ count: number;
39
+ }
40
+ interface StorageBucket {
41
+ id: string;
42
+ name: string;
43
+ publicAccess: boolean;
44
+ createdAt: string;
45
+ }
46
+ interface StorageFile {
47
+ id: string;
48
+ name: string;
49
+ size: number;
50
+ mimeType: string;
51
+ url?: string;
52
+ createdAt: string;
53
+ }
54
+ interface UploadOptions {
55
+ /** Custom file name (defaults to original) */
56
+ fileName?: string;
57
+ /** Content type override */
58
+ contentType?: string;
59
+ /** Make file publicly accessible */
60
+ public?: boolean;
61
+ }
62
+ interface ListFilesOptions {
63
+ /** Maximum files to return */
64
+ limit?: number;
65
+ /** Pagination offset */
66
+ offset?: number;
67
+ /** Filter by prefix/folder */
68
+ prefix?: string;
69
+ }
70
+ interface SendEmailOptions {
71
+ /** Sender email address */
72
+ from: string;
73
+ /** Recipient email address */
74
+ to: string;
75
+ /** Email subject */
76
+ subject: string;
77
+ /** HTML content */
78
+ html: string;
79
+ /** Plain text content (optional) */
80
+ text?: string;
81
+ /** Reply-to address */
82
+ replyTo?: string;
83
+ }
84
+ interface EmailDomain {
85
+ id: string;
86
+ domain: string;
87
+ status: 'pending' | 'verified' | 'failed';
88
+ dkimSelector: string;
89
+ dkimPublicKey: string;
90
+ verifiedAt?: string;
91
+ }
92
+ interface EmailLog {
93
+ id: string;
94
+ from: string;
95
+ to: string;
96
+ subject: string;
97
+ status: 'sent' | 'failed' | 'bounced';
98
+ sentAt: string;
99
+ error?: string;
100
+ }
101
+ interface AIQueryResult {
102
+ /** Generated SQL query */
103
+ sql: string;
104
+ /** Natural language explanation */
105
+ explanation: string;
106
+ /** Query execution results */
107
+ result: {
108
+ rows: Record<string, unknown>[];
109
+ fields: {
110
+ name: string;
111
+ dataType: number;
112
+ }[];
113
+ };
114
+ /** Error if query failed */
115
+ error?: string;
116
+ details?: string;
117
+ }
118
+ interface SQLResult<T = Record<string, unknown>> {
119
+ rows: T[];
120
+ rowCount: number;
121
+ fields: {
122
+ name: string;
123
+ dataType: number;
124
+ }[];
125
+ command?: string;
126
+ executionTime?: number;
127
+ }
128
+ interface RequestOptions {
129
+ method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
130
+ path: string;
131
+ body?: unknown;
132
+ headers?: Record<string, string>;
133
+ params?: Record<string, string | number | boolean | undefined>;
134
+ }
135
+ interface APIResponse<T> {
136
+ data: T;
137
+ status: number;
138
+ headers: Headers;
139
+ }
140
+
141
+ /**
142
+ * Scarlet SDK - HTTP Client
143
+ * Fetch-based HTTP client with error handling
144
+ */
145
+
146
+ interface ClientConfig {
147
+ apiKey: string;
148
+ baseUrl: string;
149
+ timeout: number;
150
+ }
151
+ declare class HttpClient {
152
+ private readonly config;
153
+ constructor(config: ClientConfig);
154
+ request<T>(options: RequestOptions): Promise<APIResponse<T>>;
155
+ private handleErrorResponse;
156
+ get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
157
+ post<T>(path: string, body?: unknown): Promise<T>;
158
+ patch<T>(path: string, body?: unknown): Promise<T>;
159
+ put<T>(path: string, body?: unknown): Promise<T>;
160
+ delete<T>(path: string, body?: unknown): Promise<T>;
161
+ /**
162
+ * Upload file using multipart/form-data
163
+ */
164
+ upload<T>(path: string, file: Blob, fileName?: string): Promise<T>;
165
+ }
166
+
167
+ /**
168
+ * Scarlet SDK - Data API Module
169
+ * Fluent query builder for CRUD operations
170
+ */
171
+
172
+ declare class QueryBuilder<T = Record<string, unknown>> {
173
+ private readonly client;
174
+ private readonly table;
175
+ private _columns;
176
+ private _where;
177
+ private _orderBy?;
178
+ private _limit?;
179
+ private _offset?;
180
+ constructor(client: HttpClient, table: string);
181
+ /**
182
+ * Select specific columns (default: all)
183
+ */
184
+ select(...columns: (keyof T & string)[]): this;
185
+ /**
186
+ * Add where conditions
187
+ */
188
+ where(conditions: Partial<{
189
+ [K in keyof T]: T[K] | WhereCondition[string];
190
+ }>): this;
191
+ /**
192
+ * Add equality condition
193
+ */
194
+ eq<K extends keyof T & string>(column: K, value: T[K]): this;
195
+ /**
196
+ * Order results
197
+ */
198
+ orderBy(column: keyof T & string, direction?: OrderDirection): this;
199
+ /**
200
+ * Limit results
201
+ */
202
+ limit(count: number): this;
203
+ /**
204
+ * Offset results (for pagination)
205
+ */
206
+ offset(count: number): this;
207
+ /**
208
+ * Execute SELECT query
209
+ */
210
+ execute(): Promise<QueryResult<T>>;
211
+ /**
212
+ * Execute and return all rows
213
+ */
214
+ then<TResult = T[]>(resolve?: (value: T[]) => TResult | PromiseLike<TResult>): Promise<TResult>;
215
+ /**
216
+ * Get single result (or null)
217
+ */
218
+ single(): Promise<T | null>;
219
+ /**
220
+ * Insert data
221
+ */
222
+ insert(data: Partial<T> | Partial<T>[]): Promise<InsertResult<T>>;
223
+ /**
224
+ * Update data (requires where clause)
225
+ */
226
+ update(data: Partial<T>): Promise<UpdateResult>;
227
+ /**
228
+ * Delete data (requires where clause)
229
+ */
230
+ delete(): Promise<DeleteResult>;
231
+ }
232
+
233
+ /**
234
+ * Scarlet SDK - Storage Module
235
+ * File storage operations
236
+ */
237
+
238
+ declare class StorageModule {
239
+ private readonly client;
240
+ private readonly baseUrl;
241
+ constructor(client: HttpClient, baseUrl: string);
242
+ /**
243
+ * Create a new storage bucket
244
+ */
245
+ createBucket(name: string, options?: {
246
+ publicAccess?: boolean;
247
+ }): Promise<StorageBucket>;
248
+ /**
249
+ * List all buckets
250
+ */
251
+ listBuckets(): Promise<StorageBucket[]>;
252
+ /**
253
+ * Upload a file to a bucket
254
+ */
255
+ upload(bucket: string, file: Blob | File, options?: UploadOptions): Promise<StorageFile>;
256
+ /**
257
+ * List files in a bucket
258
+ */
259
+ list(bucket: string, options?: ListFilesOptions): Promise<StorageFile[]>;
260
+ /**
261
+ * Get a signed URL for private file access
262
+ */
263
+ getSignedUrl(bucket: string, fileName: string): Promise<string>;
264
+ /**
265
+ * Get public URL for a file (bucket must be public)
266
+ */
267
+ getPublicUrl(bucket: string, fileName: string): string;
268
+ /**
269
+ * Delete a file
270
+ */
271
+ delete(bucket: string, fileName: string): Promise<{
272
+ success: boolean;
273
+ }>;
274
+ /**
275
+ * Get storage statistics
276
+ */
277
+ getStats(): Promise<{
278
+ size_bytes: number;
279
+ object_count: number;
280
+ }>;
281
+ }
282
+
283
+ /**
284
+ * Scarlet SDK - Email Module
285
+ * Transactional email sending
286
+ */
287
+
288
+ declare class EmailModule {
289
+ private readonly client;
290
+ constructor(client: HttpClient);
291
+ /**
292
+ * Send a transactional email
293
+ */
294
+ send(options: SendEmailOptions): Promise<{
295
+ success: boolean;
296
+ messageId?: string;
297
+ }>;
298
+ /**
299
+ * Add a custom email domain
300
+ */
301
+ addDomain(domain: string): Promise<EmailDomain>;
302
+ /**
303
+ * List configured email domains
304
+ */
305
+ listDomains(): Promise<EmailDomain[]>;
306
+ /**
307
+ * Verify domain DNS records
308
+ */
309
+ verifyDomain(domainId: string): Promise<{
310
+ verified: boolean;
311
+ error?: string;
312
+ }>;
313
+ /**
314
+ * Get email send logs
315
+ */
316
+ getLogs(options?: {
317
+ limit?: number;
318
+ }): Promise<EmailLog[]>;
319
+ }
320
+
321
+ /**
322
+ * Scarlet SDK - AI Module
323
+ * Natural language query processing
324
+ */
325
+
326
+ declare class AIModule {
327
+ private readonly client;
328
+ constructor(client: HttpClient);
329
+ /**
330
+ * Execute a natural language query
331
+ * Converts natural language to SQL and executes it
332
+ *
333
+ * @example
334
+ * const result = await db.ai.query('Show me all users who signed up last week');
335
+ * console.log(result.sql); // Generated SQL
336
+ * console.log(result.rows); // Query results
337
+ */
338
+ query(prompt: string): Promise<AIQueryResult>;
339
+ /**
340
+ * Generate SQL from natural language without executing
341
+ */
342
+ generateSQL(prompt: string): Promise<{
343
+ sql: string;
344
+ explanation: string;
345
+ }>;
346
+ }
347
+
348
+ /**
349
+ * Scarlet SDK - SQL Module
350
+ * Raw SQL query execution
351
+ */
352
+
353
+ declare class SQLModule {
354
+ private readonly client;
355
+ constructor(client: HttpClient);
356
+ /**
357
+ * Execute a parameterized SQL query
358
+ *
359
+ * @example
360
+ * const result = await db.sql.query(
361
+ * 'SELECT * FROM users WHERE created_at > $1',
362
+ * [new Date('2024-01-01')]
363
+ * );
364
+ */
365
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<SQLResult<T>>;
366
+ /**
367
+ * Execute raw SQL without parameter binding
368
+ * ⚠️ Use with caution - ensure input is sanitized
369
+ */
370
+ unsafe<T = Record<string, unknown>>(sql: string): Promise<SQLResult<T>>;
371
+ }
372
+
373
+ /**
374
+ * Scarlet SDK - Error Classes
375
+ */
376
+ declare class ScarletError extends Error {
377
+ readonly status: number;
378
+ readonly code: string;
379
+ readonly details?: unknown;
380
+ constructor(message: string, status: number, code: string, details?: unknown);
381
+ toJSON(): {
382
+ name: string;
383
+ message: string;
384
+ status: number;
385
+ code: string;
386
+ details: unknown;
387
+ };
388
+ }
389
+ declare class NetworkError extends ScarletError {
390
+ constructor(message: string, details?: unknown);
391
+ }
392
+ declare class AuthenticationError extends ScarletError {
393
+ constructor(message?: string);
394
+ }
395
+ declare class NotFoundError extends ScarletError {
396
+ constructor(resource: string);
397
+ }
398
+ declare class ValidationError extends ScarletError {
399
+ constructor(message: string, details?: unknown);
400
+ }
401
+ declare class RateLimitError extends ScarletError {
402
+ readonly retryAfter?: number;
403
+ constructor(retryAfter?: number);
404
+ }
405
+
406
+ /**
407
+ * @scarlet/sdk
408
+ * Official TypeScript SDK for Scarlet DB
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * import { Scarlet } from '@scarlet/sdk';
413
+ *
414
+ * const db = new Scarlet({ apiKey: 'sk_live_...' });
415
+ *
416
+ * // Query data
417
+ * const users = await db.from('users').select().limit(10);
418
+ *
419
+ * // Storage
420
+ * await db.storage.upload('avatars', file);
421
+ *
422
+ * // Email
423
+ * await db.email.send({ from: '...', to: '...', subject: '...', html: '...' });
424
+ *
425
+ * // AI Query
426
+ * const result = await db.ai.query('Show me active users');
427
+ *
428
+ * // Raw SQL
429
+ * const result = await db.sql.query('SELECT * FROM users WHERE id = $1', [1]);
430
+ * ```
431
+ */
432
+
433
+ /**
434
+ * Main Scarlet SDK client
435
+ */
436
+ declare class Scarlet {
437
+ private readonly client;
438
+ private readonly _data;
439
+ /** Storage module for file operations */
440
+ readonly storage: StorageModule;
441
+ /** Email module for sending transactional emails */
442
+ readonly email: EmailModule;
443
+ /** AI module for natural language queries */
444
+ readonly ai: AIModule;
445
+ /** SQL module for raw queries */
446
+ readonly sql: SQLModule & {
447
+ <T = Record<string, unknown>>(strings: TemplateStringsArray, ...values: unknown[]): Promise<SQLResult<T>>;
448
+ };
449
+ constructor(config: ScarletConfig);
450
+ /**
451
+ * Start a query on a table
452
+ *
453
+ * @example
454
+ * const users = await db.from('users').select().where({ active: true }).limit(10);
455
+ */
456
+ from<T = Record<string, unknown>>(table: string): QueryBuilder<T>;
457
+ }
458
+
459
+ export { type AIQueryResult, type APIResponse, AuthenticationError, type DeleteResult, type EmailDomain, type EmailLog, type FilterOperator, type FilterValue, type InsertResult, type ListFilesOptions, NetworkError, NotFoundError, type OrderDirection, QueryBuilder, type QueryResult, RateLimitError, type RequestOptions, type SQLResult, Scarlet, type ScarletConfig, ScarletError, type SendEmailOptions, type StorageBucket, type StorageFile, type UpdateResult, type UploadOptions, ValidationError, type WhereCondition };