@wowsql/sdk 3.4.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.js ADDED
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ /**
3
+ * WowSQL TypeScript SDK
4
+ * Official client library for WowSQL REST API v2
5
+ *
6
+ * @version 2.0.0
7
+ * @license MIT
8
+ * @see https://github.com/wowsql/wowsql
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.QueryBuilder = exports.Table = exports.WowSQLClient = void 0;
29
+ const axios_1 = __importDefault(require("axios"));
30
+ const errors_1 = require("./errors");
31
+ // ==================== Main Client ====================
32
+ class WowSQLClient {
33
+ constructor(config) {
34
+ // Build base URL
35
+ const protocol = config.secure !== false ? 'https' : 'http';
36
+ if (config.projectUrl.startsWith('http://') || config.projectUrl.startsWith('https://')) {
37
+ this.baseUrl = config.projectUrl;
38
+ }
39
+ else {
40
+ const domain = config.baseDomain || 'wowsql.com';
41
+ // If it already contains the base domain, don't append it again
42
+ if (config.projectUrl.includes(`.${domain}`) || config.projectUrl.endsWith(domain)) {
43
+ this.baseUrl = `${protocol}://${config.projectUrl}`;
44
+ }
45
+ else {
46
+ // Just a project slug, append domain
47
+ this.baseUrl = `${protocol}://${config.projectUrl}.${domain}`;
48
+ }
49
+ }
50
+ // Create axios instance
51
+ this.client = axios_1.default.create({
52
+ baseURL: `${this.baseUrl}/api/v2`,
53
+ headers: {
54
+ 'Authorization': `Bearer ${config.apiKey}`,
55
+ 'Content-Type': 'application/json',
56
+ },
57
+ timeout: config.timeout || 30000,
58
+ });
59
+ // Add error interceptor
60
+ this.client.interceptors.response.use((response) => response, (error) => {
61
+ if (error.response) {
62
+ const errorData = error.response.data;
63
+ const errorMessage = errorData?.detail || errorData?.message || error.message;
64
+ throw new errors_1.WOWSQLError(errorMessage, error.response.status, errorData);
65
+ }
66
+ throw new errors_1.WOWSQLError(error.message);
67
+ });
68
+ }
69
+ /**
70
+ * Get a table interface for fluent API
71
+ */
72
+ table(tableName) {
73
+ return new Table(this.client, tableName);
74
+ }
75
+ /**
76
+ * List all tables in the database
77
+ */
78
+ async listTables() {
79
+ const response = await this.client.get('/tables');
80
+ return response.data.tables;
81
+ }
82
+ /**
83
+ * Get table schema
84
+ */
85
+ async getTableSchema(tableName) {
86
+ const response = await this.client.get(`/tables/${tableName}/schema`);
87
+ return response.data;
88
+ }
89
+ /**
90
+ * Execute raw SQL query (read-only for safety)
91
+ */
92
+ async query(sql) {
93
+ const response = await this.client.post('/query', { sql });
94
+ return response.data.results || response.data;
95
+ }
96
+ /**
97
+ * Health check
98
+ */
99
+ async health() {
100
+ const response = await this.client.get('/health');
101
+ return response.data;
102
+ }
103
+ }
104
+ exports.WowSQLClient = WowSQLClient;
105
+ // ==================== Table Class ====================
106
+ class Table {
107
+ constructor(client, tableName) {
108
+ this.client = client;
109
+ this.tableName = tableName;
110
+ }
111
+ /**
112
+ * Query records with filters and pagination
113
+ *
114
+ * @example
115
+ * const users = await client.table('users')
116
+ * .select(['id', 'name', 'email'])
117
+ * .filter({ column: 'age', operator: 'gt', value: 18 })
118
+ * .order('created_at', 'desc')
119
+ * .limit(10)
120
+ * .get();
121
+ */
122
+ select(columns) {
123
+ return new QueryBuilder(this.client, this.tableName).select(columns);
124
+ }
125
+ /**
126
+ * Query with filter
127
+ */
128
+ filter(filter) {
129
+ return new QueryBuilder(this.client, this.tableName).filter(filter);
130
+ }
131
+ /**
132
+ * Get all records (with optional limit)
133
+ */
134
+ async get(options) {
135
+ return new QueryBuilder(this.client, this.tableName).get(options);
136
+ }
137
+ /**
138
+ * Get a single record by ID
139
+ */
140
+ async getById(id) {
141
+ const response = await this.client.get(`/${this.tableName}/${id}`);
142
+ return response.data;
143
+ }
144
+ /**
145
+ * Create a new record
146
+ */
147
+ async create(data) {
148
+ const response = await this.client.post(`/${this.tableName}`, data);
149
+ return response.data;
150
+ }
151
+ /**
152
+ * Update a record by ID
153
+ */
154
+ async update(id, data) {
155
+ const response = await this.client.patch(`/${this.tableName}/${id}`, data);
156
+ return response.data;
157
+ }
158
+ /**
159
+ * Delete a record by ID
160
+ */
161
+ async delete(id) {
162
+ const response = await this.client.delete(`/${this.tableName}/${id}`);
163
+ return response.data;
164
+ }
165
+ }
166
+ exports.Table = Table;
167
+ // ==================== Query Builder ====================
168
+ class QueryBuilder {
169
+ constructor(client, tableName) {
170
+ this.client = client;
171
+ this.tableName = tableName;
172
+ this.options = {};
173
+ }
174
+ /**
175
+ * Select specific columns
176
+ */
177
+ select(columns) {
178
+ this.options.select = Array.isArray(columns) ? columns.join(',') : columns;
179
+ return this;
180
+ }
181
+ /**
182
+ * Add filter condition
183
+ */
184
+ filter(filter) {
185
+ if (!this.options.filter) {
186
+ this.options.filter = [];
187
+ }
188
+ if (Array.isArray(this.options.filter)) {
189
+ this.options.filter.push(filter);
190
+ }
191
+ else {
192
+ this.options.filter = [this.options.filter, filter];
193
+ }
194
+ return this;
195
+ }
196
+ /**
197
+ * Order by column
198
+ */
199
+ order(column, direction = 'asc') {
200
+ this.options.order = column;
201
+ this.options.orderDirection = direction;
202
+ return this;
203
+ }
204
+ /**
205
+ * Limit number of results
206
+ */
207
+ limit(limit) {
208
+ this.options.limit = limit;
209
+ return this;
210
+ }
211
+ /**
212
+ * Skip records (pagination)
213
+ */
214
+ offset(offset) {
215
+ this.options.offset = offset;
216
+ return this;
217
+ }
218
+ /**
219
+ * Execute query
220
+ */
221
+ async get(additionalOptions) {
222
+ const finalOptions = { ...this.options, ...additionalOptions };
223
+ // Build query parameters
224
+ const params = {};
225
+ if (finalOptions.select) {
226
+ params.select = finalOptions.select;
227
+ }
228
+ if (finalOptions.filter) {
229
+ const filters = Array.isArray(finalOptions.filter)
230
+ ? finalOptions.filter
231
+ : [finalOptions.filter];
232
+ params.filter = filters
233
+ .map((f) => `${f.column}.${f.operator}.${f.value}`)
234
+ .join(',');
235
+ }
236
+ if (finalOptions.order) {
237
+ params.order = finalOptions.order;
238
+ params.order_direction = finalOptions.orderDirection || 'asc';
239
+ }
240
+ if (finalOptions.limit !== undefined) {
241
+ params.limit = finalOptions.limit;
242
+ }
243
+ if (finalOptions.offset !== undefined) {
244
+ params.offset = finalOptions.offset;
245
+ }
246
+ const response = await this.client.get(`/${this.tableName}`, { params });
247
+ return response.data;
248
+ }
249
+ /**
250
+ * Get first record
251
+ */
252
+ async first() {
253
+ const result = await this.limit(1).get();
254
+ return result.data[0] || null;
255
+ }
256
+ }
257
+ exports.QueryBuilder = QueryBuilder;
258
+ // ==================== Exports ====================
259
+ // Re-export storage SDK
260
+ __exportStar(require("./storage"), exports);
261
+ __exportStar(require("./auth"), exports);
262
+ __exportStar(require("./schema"), exports);
263
+ __exportStar(require("./errors"), exports);
264
+ exports.default = WowSQLClient;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Schema management client for WowSQL.
3
+ * Requires SERVICE ROLE key.
4
+ */
5
+ export interface ColumnDefinition {
6
+ name: string;
7
+ type: string;
8
+ auto_increment?: boolean;
9
+ unique?: boolean;
10
+ nullable?: boolean;
11
+ default?: string;
12
+ }
13
+ export interface CreateTableOptions {
14
+ tableName: string;
15
+ columns: ColumnDefinition[];
16
+ primaryKey?: string;
17
+ indexes?: string[];
18
+ }
19
+ export interface AlterTableOptions {
20
+ tableName: string;
21
+ operation: 'add_column' | 'drop_column' | 'modify_column' | 'rename_column';
22
+ columnName?: string;
23
+ columnType?: string;
24
+ newColumnName?: string;
25
+ nullable?: boolean;
26
+ default?: string;
27
+ }
28
+ export declare class WowSQLSchema {
29
+ private baseUrl;
30
+ private serviceKey;
31
+ /**
32
+ * Initialize schema client.
33
+ *
34
+ * ⚠️ IMPORTANT: Requires SERVICE ROLE key, not anonymous key!
35
+ *
36
+ * @param projectUrl - Project URL (e.g., "https://myproject.wowsql.com")
37
+ * @param serviceKey - SERVICE ROLE key (not anonymous key!)
38
+ */
39
+ constructor(projectUrl: string, serviceKey: string);
40
+ /**
41
+ * Create a new table.
42
+ */
43
+ createTable(options: CreateTableOptions): Promise<any>;
44
+ /**
45
+ * Alter an existing table.
46
+ */
47
+ alterTable(options: AlterTableOptions): Promise<any>;
48
+ /**
49
+ * Drop a table.
50
+ *
51
+ * ⚠️ WARNING: This operation cannot be undone!
52
+ */
53
+ dropTable(tableName: string, cascade?: boolean): Promise<any>;
54
+ /**
55
+ * Execute raw SQL for schema operations.
56
+ */
57
+ executeSQL(sql: string): Promise<any>;
58
+ }
package/dist/schema.js ADDED
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * Schema management client for WowSQL.
4
+ * Requires SERVICE ROLE key.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.WowSQLSchema = void 0;
8
+ class WowSQLSchema {
9
+ /**
10
+ * Initialize schema client.
11
+ *
12
+ * ⚠️ IMPORTANT: Requires SERVICE ROLE key, not anonymous key!
13
+ *
14
+ * @param projectUrl - Project URL (e.g., "https://myproject.wowsql.com")
15
+ * @param serviceKey - SERVICE ROLE key (not anonymous key!)
16
+ */
17
+ constructor(projectUrl, serviceKey) {
18
+ this.baseUrl = projectUrl.replace(/\/$/, '');
19
+ this.serviceKey = serviceKey;
20
+ }
21
+ /**
22
+ * Create a new table.
23
+ */
24
+ async createTable(options) {
25
+ const url = `${this.baseUrl}/api/v2/schema/tables`;
26
+ const response = await fetch(url, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Authorization': `Bearer ${this.serviceKey}`,
30
+ 'Content-Type': 'application/json'
31
+ },
32
+ body: JSON.stringify({
33
+ table_name: options.tableName,
34
+ columns: options.columns,
35
+ primary_key: options.primaryKey,
36
+ indexes: options.indexes
37
+ })
38
+ });
39
+ if (response.status === 403) {
40
+ throw new Error('Schema operations require a SERVICE ROLE key. ' +
41
+ 'You are using an anonymous key which cannot modify database schema.');
42
+ }
43
+ if (!response.ok) {
44
+ const error = await response.json();
45
+ throw new Error(`Failed to create table: ${error.detail || response.statusText}`);
46
+ }
47
+ return response.json();
48
+ }
49
+ /**
50
+ * Alter an existing table.
51
+ */
52
+ async alterTable(options) {
53
+ const url = `${this.baseUrl}/api/v2/schema/tables/${options.tableName}`;
54
+ const response = await fetch(url, {
55
+ method: 'PATCH',
56
+ headers: {
57
+ 'Authorization': `Bearer ${this.serviceKey}`,
58
+ 'Content-Type': 'application/json'
59
+ },
60
+ body: JSON.stringify(options)
61
+ });
62
+ if (response.status === 403) {
63
+ throw new Error('Schema operations require a SERVICE ROLE key.');
64
+ }
65
+ if (!response.ok) {
66
+ const error = await response.json();
67
+ throw new Error(`Failed to alter table: ${error.detail || response.statusText}`);
68
+ }
69
+ return response.json();
70
+ }
71
+ /**
72
+ * Drop a table.
73
+ *
74
+ * ⚠️ WARNING: This operation cannot be undone!
75
+ */
76
+ async dropTable(tableName, cascade = false) {
77
+ const url = `${this.baseUrl}/api/v2/schema/tables/${tableName}?cascade=${cascade}`;
78
+ const response = await fetch(url, {
79
+ method: 'DELETE',
80
+ headers: {
81
+ 'Authorization': `Bearer ${this.serviceKey}`
82
+ }
83
+ });
84
+ if (response.status === 403) {
85
+ throw new Error('Schema operations require a SERVICE ROLE key.');
86
+ }
87
+ if (!response.ok) {
88
+ const error = await response.json();
89
+ throw new Error(`Failed to drop table: ${error.detail || response.statusText}`);
90
+ }
91
+ return response.json();
92
+ }
93
+ /**
94
+ * Execute raw SQL for schema operations.
95
+ */
96
+ async executeSQL(sql) {
97
+ const url = `${this.baseUrl}/api/v2/schema/execute`;
98
+ const response = await fetch(url, {
99
+ method: 'POST',
100
+ headers: {
101
+ 'Authorization': `Bearer ${this.serviceKey}`,
102
+ 'Content-Type': 'application/json'
103
+ },
104
+ body: JSON.stringify({ sql })
105
+ });
106
+ if (response.status === 403) {
107
+ throw new Error('Schema operations require a SERVICE ROLE key.');
108
+ }
109
+ if (!response.ok) {
110
+ const error = await response.json();
111
+ throw new Error(`Failed to execute SQL: ${error.detail || response.statusText}`);
112
+ }
113
+ return response.json();
114
+ }
115
+ }
116
+ exports.WowSQLSchema = WowSQLSchema;