@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/dist/index.mjs ADDED
@@ -0,0 +1,553 @@
1
+ // src/errors.ts
2
+ var ScarletError = class _ScarletError extends Error {
3
+ status;
4
+ code;
5
+ details;
6
+ constructor(message, status, code, details) {
7
+ super(message);
8
+ this.name = "ScarletError";
9
+ this.status = status;
10
+ this.code = code;
11
+ this.details = details;
12
+ if (Error.captureStackTrace) {
13
+ Error.captureStackTrace(this, _ScarletError);
14
+ }
15
+ }
16
+ toJSON() {
17
+ return {
18
+ name: this.name,
19
+ message: this.message,
20
+ status: this.status,
21
+ code: this.code,
22
+ details: this.details
23
+ };
24
+ }
25
+ };
26
+ var NetworkError = class extends ScarletError {
27
+ constructor(message, details) {
28
+ super(message, 0, "NETWORK_ERROR", details);
29
+ this.name = "NetworkError";
30
+ }
31
+ };
32
+ var AuthenticationError = class extends ScarletError {
33
+ constructor(message = "Invalid or missing API key") {
34
+ super(message, 401, "AUTHENTICATION_ERROR");
35
+ this.name = "AuthenticationError";
36
+ }
37
+ };
38
+ var NotFoundError = class extends ScarletError {
39
+ constructor(resource) {
40
+ super(`${resource} not found`, 404, "NOT_FOUND");
41
+ this.name = "NotFoundError";
42
+ }
43
+ };
44
+ var ValidationError = class extends ScarletError {
45
+ constructor(message, details) {
46
+ super(message, 400, "VALIDATION_ERROR", details);
47
+ this.name = "ValidationError";
48
+ }
49
+ };
50
+ var RateLimitError = class extends ScarletError {
51
+ retryAfter;
52
+ constructor(retryAfter) {
53
+ super("Rate limit exceeded", 429, "RATE_LIMIT");
54
+ this.name = "RateLimitError";
55
+ this.retryAfter = retryAfter;
56
+ }
57
+ };
58
+
59
+ // src/client.ts
60
+ var HttpClient = class {
61
+ config;
62
+ constructor(config) {
63
+ this.config = config;
64
+ }
65
+ async request(options) {
66
+ const { method, path, body, headers = {}, params } = options;
67
+ let url = `${this.config.baseUrl}${path}`;
68
+ if (params) {
69
+ const searchParams = new URLSearchParams();
70
+ Object.entries(params).forEach(([key, value]) => {
71
+ if (value !== void 0) {
72
+ searchParams.set(key, String(value));
73
+ }
74
+ });
75
+ const queryString = searchParams.toString();
76
+ if (queryString) {
77
+ url += `?${queryString}`;
78
+ }
79
+ }
80
+ const requestHeaders = {
81
+ "Authorization": `Bearer ${this.config.apiKey}`,
82
+ "Content-Type": "application/json",
83
+ "Accept": "application/json",
84
+ ...headers
85
+ };
86
+ const controller = new AbortController();
87
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
88
+ try {
89
+ const response = await fetch(url, {
90
+ method,
91
+ headers: requestHeaders,
92
+ body: body ? JSON.stringify(body) : void 0,
93
+ signal: controller.signal
94
+ });
95
+ clearTimeout(timeoutId);
96
+ const contentType = response.headers.get("content-type");
97
+ let data;
98
+ if (contentType?.includes("application/json")) {
99
+ data = await response.json();
100
+ } else {
101
+ data = await response.text();
102
+ }
103
+ if (!response.ok) {
104
+ this.handleErrorResponse(response.status, data);
105
+ }
106
+ return {
107
+ data,
108
+ status: response.status,
109
+ headers: response.headers
110
+ };
111
+ } catch (error) {
112
+ clearTimeout(timeoutId);
113
+ if (error instanceof ScarletError) {
114
+ throw error;
115
+ }
116
+ if (error instanceof Error) {
117
+ if (error.name === "AbortError") {
118
+ throw new NetworkError(`Request timeout after ${this.config.timeout}ms`);
119
+ }
120
+ throw new NetworkError(error.message, error);
121
+ }
122
+ throw new NetworkError("Unknown network error");
123
+ }
124
+ }
125
+ handleErrorResponse(status, data) {
126
+ const errorData = data;
127
+ const message = errorData?.error || errorData?.message || "Unknown error";
128
+ const code = errorData?.code || "UNKNOWN";
129
+ const details = errorData?.details;
130
+ switch (status) {
131
+ case 401:
132
+ throw new AuthenticationError(message);
133
+ case 429:
134
+ throw new RateLimitError();
135
+ default:
136
+ throw new ScarletError(message, status, code, details);
137
+ }
138
+ }
139
+ // Convenience methods
140
+ async get(path, params) {
141
+ const response = await this.request({ method: "GET", path, params });
142
+ return response.data;
143
+ }
144
+ async post(path, body) {
145
+ const response = await this.request({ method: "POST", path, body });
146
+ return response.data;
147
+ }
148
+ async patch(path, body) {
149
+ const response = await this.request({ method: "PATCH", path, body });
150
+ return response.data;
151
+ }
152
+ async put(path, body) {
153
+ const response = await this.request({ method: "PUT", path, body });
154
+ return response.data;
155
+ }
156
+ async delete(path, body) {
157
+ const response = await this.request({ method: "DELETE", path, body });
158
+ return response.data;
159
+ }
160
+ /**
161
+ * Upload file using multipart/form-data
162
+ */
163
+ async upload(path, file, fileName) {
164
+ const formData = new FormData();
165
+ formData.append("file", file, fileName);
166
+ const controller = new AbortController();
167
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout * 2);
168
+ try {
169
+ const response = await fetch(`${this.config.baseUrl}${path}`, {
170
+ method: "POST",
171
+ headers: {
172
+ "Authorization": `Bearer ${this.config.apiKey}`
173
+ },
174
+ body: formData,
175
+ signal: controller.signal
176
+ });
177
+ clearTimeout(timeoutId);
178
+ const data = await response.json();
179
+ if (!response.ok) {
180
+ this.handleErrorResponse(response.status, data);
181
+ }
182
+ return data;
183
+ } catch (error) {
184
+ clearTimeout(timeoutId);
185
+ if (error instanceof ScarletError) throw error;
186
+ throw new NetworkError("Upload failed", error);
187
+ }
188
+ }
189
+ };
190
+
191
+ // src/modules/data.ts
192
+ var DataModule = class {
193
+ constructor(client) {
194
+ this.client = client;
195
+ }
196
+ /**
197
+ * Start a query on a table
198
+ */
199
+ from(table) {
200
+ return new QueryBuilder(this.client, table);
201
+ }
202
+ };
203
+ var QueryBuilder = class {
204
+ constructor(client, table) {
205
+ this.client = client;
206
+ this.table = table;
207
+ }
208
+ _columns = [];
209
+ _where = {};
210
+ _orderBy;
211
+ _limit;
212
+ _offset;
213
+ /**
214
+ * Select specific columns (default: all)
215
+ */
216
+ select(...columns) {
217
+ this._columns = columns;
218
+ return this;
219
+ }
220
+ /**
221
+ * Add where conditions
222
+ */
223
+ where(conditions) {
224
+ this._where = { ...this._where, ...conditions };
225
+ return this;
226
+ }
227
+ /**
228
+ * Add equality condition
229
+ */
230
+ eq(column, value) {
231
+ this._where[column] = value;
232
+ return this;
233
+ }
234
+ /**
235
+ * Order results
236
+ */
237
+ orderBy(column, direction = "asc") {
238
+ this._orderBy = { column, direction };
239
+ return this;
240
+ }
241
+ /**
242
+ * Limit results
243
+ */
244
+ limit(count) {
245
+ this._limit = count;
246
+ return this;
247
+ }
248
+ /**
249
+ * Offset results (for pagination)
250
+ */
251
+ offset(count) {
252
+ this._offset = count;
253
+ return this;
254
+ }
255
+ /**
256
+ * Execute SELECT query
257
+ */
258
+ async execute() {
259
+ const params = {};
260
+ if (this._limit !== void 0) params.limit = this._limit;
261
+ if (this._offset !== void 0) params.offset = this._offset;
262
+ if (this._orderBy) {
263
+ params.sortBy = this._orderBy.column;
264
+ params.sortDir = this._orderBy.direction;
265
+ }
266
+ if (Object.keys(this._where).length > 0) {
267
+ params.search = JSON.stringify(this._where);
268
+ }
269
+ return this.client.get(
270
+ `/tables/${this.table}/rows`,
271
+ params
272
+ );
273
+ }
274
+ /**
275
+ * Execute and return all rows
276
+ */
277
+ async then(resolve) {
278
+ const result = await this.execute();
279
+ const resolved = resolve ? resolve(result.rows) : result.rows;
280
+ return resolved;
281
+ }
282
+ /**
283
+ * Get single result (or null)
284
+ */
285
+ async single() {
286
+ this._limit = 1;
287
+ const result = await this.execute();
288
+ return result.rows[0] ?? null;
289
+ }
290
+ /**
291
+ * Insert data
292
+ */
293
+ async insert(data) {
294
+ return this.client.post(
295
+ `/tables/${this.table}/rows`,
296
+ Array.isArray(data) ? { rows: data } : data
297
+ );
298
+ }
299
+ /**
300
+ * Update data (requires where clause)
301
+ */
302
+ async update(data) {
303
+ if (Object.keys(this._where).length === 0) {
304
+ throw new Error("Update requires at least one where condition for safety");
305
+ }
306
+ return this.client.patch(
307
+ `/tables/${this.table}/rows`,
308
+ { filters: this._where, data }
309
+ );
310
+ }
311
+ /**
312
+ * Delete data (requires where clause)
313
+ */
314
+ async delete() {
315
+ if (Object.keys(this._where).length === 0) {
316
+ throw new Error("Delete requires at least one where condition for safety");
317
+ }
318
+ return this.client.delete(
319
+ `/tables/${this.table}/rows`,
320
+ { filters: this._where }
321
+ );
322
+ }
323
+ };
324
+
325
+ // src/modules/storage.ts
326
+ var StorageModule = class {
327
+ constructor(client, baseUrl) {
328
+ this.client = client;
329
+ this.baseUrl = baseUrl;
330
+ }
331
+ baseUrl;
332
+ /**
333
+ * Create a new storage bucket
334
+ */
335
+ async createBucket(name, options) {
336
+ return this.client.post("/storage/buckets", {
337
+ name,
338
+ publicAccess: options?.publicAccess ?? false
339
+ });
340
+ }
341
+ /**
342
+ * List all buckets
343
+ */
344
+ async listBuckets() {
345
+ return this.client.get("/storage/buckets");
346
+ }
347
+ /**
348
+ * Upload a file to a bucket
349
+ */
350
+ async upload(bucket, file, options) {
351
+ const fileName = options?.fileName || (file instanceof File ? file.name : "file");
352
+ return this.client.upload(
353
+ `/storage/buckets/${bucket}/upload`,
354
+ file,
355
+ fileName
356
+ );
357
+ }
358
+ /**
359
+ * List files in a bucket
360
+ */
361
+ async list(bucket, options) {
362
+ const params = {};
363
+ if (options?.limit) params.limit = options.limit;
364
+ if (options?.offset) params.offset = options.offset;
365
+ if (options?.prefix) params.prefix = options.prefix;
366
+ return this.client.get(`/storage/buckets/${bucket}/files`, params);
367
+ }
368
+ /**
369
+ * Get a signed URL for private file access
370
+ */
371
+ async getSignedUrl(bucket, fileName) {
372
+ const result = await this.client.get(
373
+ `/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}/url`
374
+ );
375
+ return result.url;
376
+ }
377
+ /**
378
+ * Get public URL for a file (bucket must be public)
379
+ */
380
+ getPublicUrl(bucket, fileName) {
381
+ return `${this.baseUrl}/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}`;
382
+ }
383
+ /**
384
+ * Delete a file
385
+ */
386
+ async delete(bucket, fileName) {
387
+ return this.client.delete(
388
+ `/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}`
389
+ );
390
+ }
391
+ /**
392
+ * Get storage statistics
393
+ */
394
+ async getStats() {
395
+ return this.client.get("/storage/stats");
396
+ }
397
+ };
398
+
399
+ // src/modules/email.ts
400
+ var EmailModule = class {
401
+ constructor(client) {
402
+ this.client = client;
403
+ }
404
+ /**
405
+ * Send a transactional email
406
+ */
407
+ async send(options) {
408
+ return this.client.post("/email/send", options);
409
+ }
410
+ /**
411
+ * Add a custom email domain
412
+ */
413
+ async addDomain(domain) {
414
+ const result = await this.client.post("/email/domains", { domain });
415
+ return result.domain;
416
+ }
417
+ /**
418
+ * List configured email domains
419
+ */
420
+ async listDomains() {
421
+ const result = await this.client.get("/email/domains");
422
+ return result.domains;
423
+ }
424
+ /**
425
+ * Verify domain DNS records
426
+ */
427
+ async verifyDomain(domainId) {
428
+ return this.client.post(
429
+ `/email/domains/${domainId}/verify`
430
+ );
431
+ }
432
+ /**
433
+ * Get email send logs
434
+ */
435
+ async getLogs(options) {
436
+ const params = options?.limit ? { limit: options.limit } : void 0;
437
+ const result = await this.client.get("/email/logs", params);
438
+ return result.logs;
439
+ }
440
+ };
441
+
442
+ // src/modules/ai.ts
443
+ var AIModule = class {
444
+ constructor(client) {
445
+ this.client = client;
446
+ }
447
+ /**
448
+ * Execute a natural language query
449
+ * Converts natural language to SQL and executes it
450
+ *
451
+ * @example
452
+ * const result = await db.ai.query('Show me all users who signed up last week');
453
+ * console.log(result.sql); // Generated SQL
454
+ * console.log(result.rows); // Query results
455
+ */
456
+ async query(prompt) {
457
+ return this.client.post("/ai/query", { prompt });
458
+ }
459
+ /**
460
+ * Generate SQL from natural language without executing
461
+ */
462
+ async generateSQL(prompt) {
463
+ return this.client.post("/ai/generate", { prompt });
464
+ }
465
+ };
466
+
467
+ // src/modules/sql.ts
468
+ var SQLModule = class {
469
+ constructor(client) {
470
+ this.client = client;
471
+ }
472
+ /**
473
+ * Execute a parameterized SQL query
474
+ *
475
+ * @example
476
+ * const result = await db.sql.query(
477
+ * 'SELECT * FROM users WHERE created_at > $1',
478
+ * [new Date('2024-01-01')]
479
+ * );
480
+ */
481
+ async query(sql, params = []) {
482
+ return this.client.post("/query", { query: sql, params });
483
+ }
484
+ /**
485
+ * Execute raw SQL without parameter binding
486
+ * ⚠️ Use with caution - ensure input is sanitized
487
+ */
488
+ async unsafe(sql) {
489
+ return this.client.post("/query", { query: sql, params: [] });
490
+ }
491
+ };
492
+ function createSqlTag(client) {
493
+ return async function sql(strings, ...values) {
494
+ let query = "";
495
+ const params = [];
496
+ strings.forEach((str, i) => {
497
+ query += str;
498
+ if (i < values.length) {
499
+ params.push(values[i]);
500
+ query += `$${i + 1}`;
501
+ }
502
+ });
503
+ return client.post("/query", { query, params });
504
+ };
505
+ }
506
+
507
+ // src/index.ts
508
+ var DEFAULT_BASE_URL = "https://api.scarletdb.space/api/v1";
509
+ var DEFAULT_TIMEOUT = 3e4;
510
+ var Scarlet = class {
511
+ client;
512
+ _data;
513
+ /** Storage module for file operations */
514
+ storage;
515
+ /** Email module for sending transactional emails */
516
+ email;
517
+ /** AI module for natural language queries */
518
+ ai;
519
+ /** SQL module for raw queries */
520
+ sql;
521
+ constructor(config) {
522
+ if (!config.apiKey) {
523
+ throw new Error("API key is required");
524
+ }
525
+ const baseUrl = config.baseUrl || DEFAULT_BASE_URL;
526
+ const timeout = config.timeout || DEFAULT_TIMEOUT;
527
+ this.client = new HttpClient({
528
+ apiKey: config.apiKey,
529
+ baseUrl,
530
+ timeout
531
+ });
532
+ this._data = new DataModule(this.client);
533
+ this.storage = new StorageModule(this.client, baseUrl);
534
+ this.email = new EmailModule(this.client);
535
+ this.ai = new AIModule(this.client);
536
+ const sqlModule = new SQLModule(this.client);
537
+ const sqlTag = createSqlTag(this.client);
538
+ this.sql = Object.assign(sqlTag, sqlModule);
539
+ }
540
+ /**
541
+ * Start a query on a table
542
+ *
543
+ * @example
544
+ * const users = await db.from('users').select().where({ active: true }).limit(10);
545
+ */
546
+ from(table) {
547
+ return this._data.from(table);
548
+ }
549
+ };
550
+
551
+ export { AuthenticationError, NetworkError, NotFoundError, QueryBuilder, RateLimitError, Scarlet, ScarletError, ValidationError };
552
+ //# sourceMappingURL=index.mjs.map
553
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/modules/data.ts","../src/modules/storage.ts","../src/modules/email.ts","../src/modules/ai.ts","../src/modules/sql.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Scarlet SDK - Error Classes\r\n */\r\n\r\nexport class ScarletError extends Error {\r\n public readonly status: number;\r\n public readonly code: string;\r\n public readonly details?: unknown;\r\n\r\n constructor(message: string, status: number, code: string, details?: unknown) {\r\n super(message);\r\n this.name = 'ScarletError';\r\n this.status = status;\r\n this.code = code;\r\n this.details = details;\r\n\r\n // Maintains proper stack trace for where error was thrown\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, ScarletError);\r\n }\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n status: this.status,\r\n code: this.code,\r\n details: this.details,\r\n };\r\n }\r\n}\r\n\r\nexport class NetworkError extends ScarletError {\r\n constructor(message: string, details?: unknown) {\r\n super(message, 0, 'NETWORK_ERROR', details);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends ScarletError {\r\n constructor(message = 'Invalid or missing API key') {\r\n super(message, 401, 'AUTHENTICATION_ERROR');\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class NotFoundError extends ScarletError {\r\n constructor(resource: string) {\r\n super(`${resource} not found`, 404, 'NOT_FOUND');\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\nexport class ValidationError extends ScarletError {\r\n constructor(message: string, details?: unknown) {\r\n super(message, 400, 'VALIDATION_ERROR', details);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends ScarletError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number) {\r\n super('Rate limit exceeded', 429, 'RATE_LIMIT');\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - HTTP Client\r\n * Fetch-based HTTP client with error handling\r\n */\r\n\r\nimport {\r\n ScarletError,\r\n NetworkError,\r\n AuthenticationError,\r\n RateLimitError\r\n} from './errors';\r\nimport type { RequestOptions, APIResponse } from './types';\r\n\r\nexport interface ClientConfig {\r\n apiKey: string;\r\n baseUrl: string;\r\n timeout: number;\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly config: ClientConfig;\r\n\r\n constructor(config: ClientConfig) {\r\n this.config = config;\r\n }\r\n\r\n async request<T>(options: RequestOptions): Promise<APIResponse<T>> {\r\n const { method, path, body, headers = {}, params } = options;\r\n\r\n // Build URL with query params\r\n let url = `${this.config.baseUrl}${path}`;\r\n if (params) {\r\n const searchParams = new URLSearchParams();\r\n Object.entries(params).forEach(([key, value]) => {\r\n if (value !== undefined) {\r\n searchParams.set(key, String(value));\r\n }\r\n });\r\n const queryString = searchParams.toString();\r\n if (queryString) {\r\n url += `?${queryString}`;\r\n }\r\n }\r\n\r\n // Setup headers\r\n const requestHeaders: Record<string, string> = {\r\n 'Authorization': `Bearer ${this.config.apiKey}`,\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json',\r\n ...headers,\r\n };\r\n\r\n // Create abort controller for timeout\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method,\r\n headers: requestHeaders,\r\n body: body ? JSON.stringify(body) : undefined,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n // Parse response\r\n const contentType = response.headers.get('content-type');\r\n let data: T;\r\n\r\n if (contentType?.includes('application/json')) {\r\n data = await response.json() as T;\r\n } else {\r\n data = await response.text() as unknown as T;\r\n }\r\n\r\n // Handle errors\r\n if (!response.ok) {\r\n this.handleErrorResponse(response.status, data);\r\n }\r\n\r\n return {\r\n data,\r\n status: response.status,\r\n headers: response.headers,\r\n };\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n if (error instanceof ScarletError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error) {\r\n if (error.name === 'AbortError') {\r\n throw new NetworkError(`Request timeout after ${this.config.timeout}ms`);\r\n }\r\n throw new NetworkError(error.message, error);\r\n }\r\n\r\n throw new NetworkError('Unknown network error');\r\n }\r\n }\r\n\r\n private handleErrorResponse(status: number, data: unknown): never {\r\n const errorData = data as { error?: string; message?: string; code?: string; details?: unknown };\r\n const message = errorData?.error || errorData?.message || 'Unknown error';\r\n const code = errorData?.code || 'UNKNOWN';\r\n const details = errorData?.details;\r\n\r\n switch (status) {\r\n case 401:\r\n throw new AuthenticationError(message);\r\n case 429:\r\n throw new RateLimitError();\r\n default:\r\n throw new ScarletError(message, status, code, details);\r\n }\r\n }\r\n\r\n // Convenience methods\r\n async get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T> {\r\n const response = await this.request<T>({ method: 'GET', path, params });\r\n return response.data;\r\n }\r\n\r\n async post<T>(path: string, body?: unknown): Promise<T> {\r\n const response = await this.request<T>({ method: 'POST', path, body });\r\n return response.data;\r\n }\r\n\r\n async patch<T>(path: string, body?: unknown): Promise<T> {\r\n const response = await this.request<T>({ method: 'PATCH', path, body });\r\n return response.data;\r\n }\r\n\r\n async put<T>(path: string, body?: unknown): Promise<T> {\r\n const response = await this.request<T>({ method: 'PUT', path, body });\r\n return response.data;\r\n }\r\n\r\n async delete<T>(path: string, body?: unknown): Promise<T> {\r\n const response = await this.request<T>({ method: 'DELETE', path, body });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Upload file using multipart/form-data\r\n */\r\n async upload<T>(path: string, file: Blob, fileName?: string): Promise<T> {\r\n const formData = new FormData();\r\n formData.append('file', file, fileName);\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout * 2); // Double timeout for uploads\r\n\r\n try {\r\n const response = await fetch(`${this.config.baseUrl}${path}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Authorization': `Bearer ${this.config.apiKey}`,\r\n },\r\n body: formData,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n const data = await response.json() as T;\r\n\r\n if (!response.ok) {\r\n this.handleErrorResponse(response.status, data);\r\n }\r\n\r\n return data;\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n if (error instanceof ScarletError) throw error;\r\n throw new NetworkError('Upload failed', error);\r\n }\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - Data API Module\r\n * Fluent query builder for CRUD operations\r\n */\r\n\r\nimport type { HttpClient } from '../client';\r\nimport type {\r\n WhereCondition,\r\n OrderDirection,\r\n QueryResult,\r\n InsertResult,\r\n UpdateResult,\r\n DeleteResult\r\n} from '../types';\r\n\r\nexport class DataModule {\r\n constructor(private readonly client: HttpClient) { }\r\n\r\n /**\r\n * Start a query on a table\r\n */\r\n from<T = Record<string, unknown>>(table: string): QueryBuilder<T> {\r\n return new QueryBuilder<T>(this.client, table);\r\n }\r\n}\r\n\r\nexport class QueryBuilder<T = Record<string, unknown>> {\r\n private _columns: string[] = [];\r\n private _where: WhereCondition = {};\r\n private _orderBy?: { column: string; direction: OrderDirection };\r\n private _limit?: number;\r\n private _offset?: number;\r\n\r\n constructor(\r\n private readonly client: HttpClient,\r\n private readonly table: string\r\n ) { }\r\n\r\n /**\r\n * Select specific columns (default: all)\r\n */\r\n select(...columns: (keyof T & string)[]): this {\r\n this._columns = columns;\r\n return this;\r\n }\r\n\r\n /**\r\n * Add where conditions\r\n */\r\n where(conditions: Partial<{ [K in keyof T]: T[K] | WhereCondition[string] }>): this {\r\n this._where = { ...this._where, ...conditions } as WhereCondition;\r\n return this;\r\n }\r\n\r\n /**\r\n * Add equality condition\r\n */\r\n eq<K extends keyof T & string>(column: K, value: T[K]): this {\r\n this._where[column] = value as WhereCondition[string];\r\n return this;\r\n }\r\n\r\n /**\r\n * Order results\r\n */\r\n orderBy(column: keyof T & string, direction: OrderDirection = 'asc'): this {\r\n this._orderBy = { column, direction };\r\n return this;\r\n }\r\n\r\n /**\r\n * Limit results\r\n */\r\n limit(count: number): this {\r\n this._limit = count;\r\n return this;\r\n }\r\n\r\n /**\r\n * Offset results (for pagination)\r\n */\r\n offset(count: number): this {\r\n this._offset = count;\r\n return this;\r\n }\r\n\r\n /**\r\n * Execute SELECT query\r\n */\r\n async execute(): Promise<QueryResult<T>> {\r\n const params: Record<string, string | number | boolean | undefined> = {};\r\n\r\n if (this._limit !== undefined) params.limit = this._limit;\r\n if (this._offset !== undefined) params.offset = this._offset;\r\n if (this._orderBy) {\r\n params.sortBy = this._orderBy.column;\r\n params.sortDir = this._orderBy.direction;\r\n }\r\n if (Object.keys(this._where).length > 0) {\r\n params.search = JSON.stringify(this._where);\r\n }\r\n\r\n return this.client.get<QueryResult<T>>(\r\n `/tables/${this.table}/rows`,\r\n params\r\n );\r\n }\r\n\r\n /**\r\n * Execute and return all rows\r\n */\r\n async then<TResult = T[]>(\r\n resolve?: (value: T[]) => TResult | PromiseLike<TResult>\r\n ): Promise<TResult> {\r\n const result = await this.execute();\r\n const resolved = resolve ? resolve(result.rows) : result.rows as unknown as TResult;\r\n return resolved;\r\n }\r\n\r\n /**\r\n * Get single result (or null)\r\n */\r\n async single(): Promise<T | null> {\r\n this._limit = 1;\r\n const result = await this.execute();\r\n return result.rows[0] ?? null;\r\n }\r\n\r\n /**\r\n * Insert data\r\n */\r\n async insert(data: Partial<T> | Partial<T>[]): Promise<InsertResult<T>> {\r\n return this.client.post<InsertResult<T>>(\r\n `/tables/${this.table}/rows`,\r\n Array.isArray(data) ? { rows: data } : data\r\n );\r\n }\r\n\r\n /**\r\n * Update data (requires where clause)\r\n */\r\n async update(data: Partial<T>): Promise<UpdateResult> {\r\n if (Object.keys(this._where).length === 0) {\r\n throw new Error('Update requires at least one where condition for safety');\r\n }\r\n return this.client.patch<UpdateResult>(\r\n `/tables/${this.table}/rows`,\r\n { filters: this._where, data }\r\n );\r\n }\r\n\r\n /**\r\n * Delete data (requires where clause)\r\n */\r\n async delete(): Promise<DeleteResult> {\r\n if (Object.keys(this._where).length === 0) {\r\n throw new Error('Delete requires at least one where condition for safety');\r\n }\r\n return this.client.delete<DeleteResult>(\r\n `/tables/${this.table}/rows`,\r\n { filters: this._where }\r\n );\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - Storage Module\r\n * File storage operations\r\n */\r\n\r\nimport type { HttpClient } from '../client';\r\nimport type {\r\n StorageBucket,\r\n StorageFile,\r\n UploadOptions,\r\n ListFilesOptions\r\n} from '../types';\r\n\r\nexport class StorageModule {\r\n private readonly baseUrl: string;\r\n\r\n constructor(\r\n private readonly client: HttpClient,\r\n baseUrl: string\r\n ) {\r\n this.baseUrl = baseUrl;\r\n }\r\n\r\n /**\r\n * Create a new storage bucket\r\n */\r\n async createBucket(name: string, options?: { publicAccess?: boolean }): Promise<StorageBucket> {\r\n return this.client.post<StorageBucket>('/storage/buckets', {\r\n name,\r\n publicAccess: options?.publicAccess ?? false,\r\n });\r\n }\r\n\r\n /**\r\n * List all buckets\r\n */\r\n async listBuckets(): Promise<StorageBucket[]> {\r\n return this.client.get<StorageBucket[]>('/storage/buckets');\r\n }\r\n\r\n /**\r\n * Upload a file to a bucket\r\n */\r\n async upload(\r\n bucket: string,\r\n file: Blob | File,\r\n options?: UploadOptions\r\n ): Promise<StorageFile> {\r\n const fileName = options?.fileName || (file instanceof File ? file.name : 'file');\r\n return this.client.upload<StorageFile>(\r\n `/storage/buckets/${bucket}/upload`,\r\n file,\r\n fileName\r\n );\r\n }\r\n\r\n /**\r\n * List files in a bucket\r\n */\r\n async list(bucket: string, options?: ListFilesOptions): Promise<StorageFile[]> {\r\n const params: Record<string, string | number | undefined> = {};\r\n if (options?.limit) params.limit = options.limit;\r\n if (options?.offset) params.offset = options.offset;\r\n if (options?.prefix) params.prefix = options.prefix;\r\n\r\n return this.client.get<StorageFile[]>(`/storage/buckets/${bucket}/files`, params);\r\n }\r\n\r\n /**\r\n * Get a signed URL for private file access\r\n */\r\n async getSignedUrl(bucket: string, fileName: string): Promise<string> {\r\n const result = await this.client.get<{ url: string }>(\r\n `/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}/url`\r\n );\r\n return result.url;\r\n }\r\n\r\n /**\r\n * Get public URL for a file (bucket must be public)\r\n */\r\n getPublicUrl(bucket: string, fileName: string): string {\r\n return `${this.baseUrl}/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}`;\r\n }\r\n\r\n /**\r\n * Delete a file\r\n */\r\n async delete(bucket: string, fileName: string): Promise<{ success: boolean }> {\r\n return this.client.delete<{ success: boolean }>(\r\n `/storage/buckets/${bucket}/files/${encodeURIComponent(fileName)}`\r\n );\r\n }\r\n\r\n /**\r\n * Get storage statistics\r\n */\r\n async getStats(): Promise<{ size_bytes: number; object_count: number }> {\r\n return this.client.get<{ size_bytes: number; object_count: number }>('/storage/stats');\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - Email Module\r\n * Transactional email sending\r\n */\r\n\r\nimport type { HttpClient } from '../client';\r\nimport type { SendEmailOptions, EmailDomain, EmailLog } from '../types';\r\n\r\nexport class EmailModule {\r\n constructor(private readonly client: HttpClient) { }\r\n\r\n /**\r\n * Send a transactional email\r\n */\r\n async send(options: SendEmailOptions): Promise<{ success: boolean; messageId?: string }> {\r\n return this.client.post<{ success: boolean; messageId?: string }>('/email/send', options);\r\n }\r\n\r\n /**\r\n * Add a custom email domain\r\n */\r\n async addDomain(domain: string): Promise<EmailDomain> {\r\n const result = await this.client.post<{ domain: EmailDomain }>('/email/domains', { domain });\r\n return result.domain;\r\n }\r\n\r\n /**\r\n * List configured email domains\r\n */\r\n async listDomains(): Promise<EmailDomain[]> {\r\n const result = await this.client.get<{ domains: EmailDomain[] }>('/email/domains');\r\n return result.domains;\r\n }\r\n\r\n /**\r\n * Verify domain DNS records\r\n */\r\n async verifyDomain(domainId: string): Promise<{ verified: boolean; error?: string }> {\r\n return this.client.post<{ verified: boolean; error?: string }>(\r\n `/email/domains/${domainId}/verify`\r\n );\r\n }\r\n\r\n /**\r\n * Get email send logs\r\n */\r\n async getLogs(options?: { limit?: number }): Promise<EmailLog[]> {\r\n const params = options?.limit ? { limit: options.limit } : undefined;\r\n const result = await this.client.get<{ logs: EmailLog[] }>('/email/logs', params);\r\n return result.logs;\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - AI Module\r\n * Natural language query processing\r\n */\r\n\r\nimport type { HttpClient } from '../client';\r\nimport type { AIQueryResult } from '../types';\r\n\r\nexport class AIModule {\r\n constructor(private readonly client: HttpClient) { }\r\n\r\n /**\r\n * Execute a natural language query\r\n * Converts natural language to SQL and executes it\r\n * \r\n * @example\r\n * const result = await db.ai.query('Show me all users who signed up last week');\r\n * console.log(result.sql); // Generated SQL\r\n * console.log(result.rows); // Query results\r\n */\r\n async query(prompt: string): Promise<AIQueryResult> {\r\n return this.client.post<AIQueryResult>('/ai/query', { prompt });\r\n }\r\n\r\n /**\r\n * Generate SQL from natural language without executing\r\n */\r\n async generateSQL(prompt: string): Promise<{ sql: string; explanation: string }> {\r\n return this.client.post<{ sql: string; explanation: string }>('/ai/generate', { prompt });\r\n }\r\n}\r\n","/**\r\n * Scarlet SDK - SQL Module\r\n * Raw SQL query execution\r\n */\r\n\r\nimport type { HttpClient } from '../client';\r\nimport type { SQLResult } from '../types';\r\n\r\nexport class SQLModule {\r\n constructor(private readonly client: HttpClient) { }\r\n\r\n /**\r\n * Execute a parameterized SQL query\r\n * \r\n * @example\r\n * const result = await db.sql.query(\r\n * 'SELECT * FROM users WHERE created_at > $1',\r\n * [new Date('2024-01-01')]\r\n * );\r\n */\r\n async query<T = Record<string, unknown>>(\r\n sql: string,\r\n params: unknown[] = []\r\n ): Promise<SQLResult<T>> {\r\n return this.client.post<SQLResult<T>>('/query', { query: sql, params });\r\n }\r\n\r\n /**\r\n * Execute raw SQL without parameter binding\r\n * ⚠️ Use with caution - ensure input is sanitized\r\n */\r\n async unsafe<T = Record<string, unknown>>(sql: string): Promise<SQLResult<T>> {\r\n return this.client.post<SQLResult<T>>('/query', { query: sql, params: [] });\r\n }\r\n}\r\n\r\n/**\r\n * SQL template tag for parameterized queries\r\n * \r\n * @example\r\n * const userId = 123;\r\n * const result = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\r\n */\r\nexport function createSqlTag(client: HttpClient) {\r\n return async function sql<T = Record<string, unknown>>(\r\n strings: TemplateStringsArray,\r\n ...values: unknown[]\r\n ): Promise<SQLResult<T>> {\r\n // Build parameterized query\r\n let query = '';\r\n const params: unknown[] = [];\r\n\r\n strings.forEach((str, i) => {\r\n query += str;\r\n if (i < values.length) {\r\n params.push(values[i]);\r\n query += `$${i + 1}`;\r\n }\r\n });\r\n\r\n return client.post<SQLResult<T>>('/query', { query, params });\r\n };\r\n}\r\n","/**\r\n * @scarlet/sdk\r\n * Official TypeScript SDK for Scarlet DB\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Scarlet } from '@scarlet/sdk';\r\n * \r\n * const db = new Scarlet({ apiKey: 'sk_live_...' });\r\n * \r\n * // Query data\r\n * const users = await db.from('users').select().limit(10);\r\n * \r\n * // Storage\r\n * await db.storage.upload('avatars', file);\r\n * \r\n * // Email\r\n * await db.email.send({ from: '...', to: '...', subject: '...', html: '...' });\r\n * \r\n * // AI Query\r\n * const result = await db.ai.query('Show me active users');\r\n * \r\n * // Raw SQL\r\n * const result = await db.sql.query('SELECT * FROM users WHERE id = $1', [1]);\r\n * ```\r\n */\r\n\r\nimport { HttpClient } from './client';\r\nimport { DataModule, QueryBuilder } from './modules/data';\r\nimport { StorageModule } from './modules/storage';\r\nimport { EmailModule } from './modules/email';\r\nimport { AIModule } from './modules/ai';\r\nimport { SQLModule, createSqlTag } from './modules/sql';\r\nimport type { ScarletConfig, SQLResult } from './types';\r\n\r\n// Default configuration\r\nconst DEFAULT_BASE_URL = 'https://api.scarletdb.space/api/v1';\r\nconst DEFAULT_TIMEOUT = 30000;\r\n\r\n/**\r\n * Main Scarlet SDK client\r\n */\r\nexport class Scarlet {\r\n private readonly client: HttpClient;\r\n private readonly _data: DataModule;\r\n\r\n /** Storage module for file operations */\r\n public readonly storage: StorageModule;\r\n\r\n /** Email module for sending transactional emails */\r\n public readonly email: EmailModule;\r\n\r\n /** AI module for natural language queries */\r\n public readonly ai: AIModule;\r\n\r\n /** SQL module for raw queries */\r\n public readonly sql: SQLModule & {\r\n <T = Record<string, unknown>>(\r\n strings: TemplateStringsArray,\r\n ...values: unknown[]\r\n ): Promise<SQLResult<T>>;\r\n };\r\n\r\n constructor(config: ScarletConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('API key is required');\r\n }\r\n\r\n const baseUrl = config.baseUrl || DEFAULT_BASE_URL;\r\n const timeout = config.timeout || DEFAULT_TIMEOUT;\r\n\r\n this.client = new HttpClient({\r\n apiKey: config.apiKey,\r\n baseUrl,\r\n timeout,\r\n });\r\n\r\n // Initialize modules\r\n this._data = new DataModule(this.client);\r\n this.storage = new StorageModule(this.client, baseUrl);\r\n this.email = new EmailModule(this.client);\r\n this.ai = new AIModule(this.client);\r\n\r\n // SQL module with template tag support\r\n const sqlModule = new SQLModule(this.client);\r\n const sqlTag = createSqlTag(this.client);\r\n\r\n // Merge module methods with template tag function\r\n this.sql = Object.assign(sqlTag, sqlModule) as typeof this.sql;\r\n }\r\n\r\n /**\r\n * Start a query on a table\r\n * \r\n * @example\r\n * const users = await db.from('users').select().where({ active: true }).limit(10);\r\n */\r\n from<T = Record<string, unknown>>(table: string): QueryBuilder<T> {\r\n return this._data.from<T>(table);\r\n }\r\n}\r\n\r\n// Re-export types\r\nexport * from './types';\r\nexport * from './errors';\r\nexport { QueryBuilder } from './modules/data';\r\n"]}