@giaeulate/baas-sdk 1.0.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/js/demo/index.html +133 -0
- package/js/src/index.ts +278 -0
- package/package.json +34 -0
- package/realtime.test.ts +184 -0
- package/scripts/dev.sh +30 -0
- package/src/client.ts +263 -0
- package/src/http-client.ts +144 -0
- package/src/index.ts +43 -0
- package/src/modules/api-keys.ts +36 -0
- package/src/modules/audit.ts +46 -0
- package/src/modules/auth.ts +158 -0
- package/src/modules/backups.ts +68 -0
- package/src/modules/branches.ts +46 -0
- package/src/modules/database.ts +158 -0
- package/src/modules/email.ts +93 -0
- package/src/modules/env-vars.ts +42 -0
- package/src/modules/functions.ts +57 -0
- package/src/modules/graphql.ts +24 -0
- package/src/modules/jobs.ts +78 -0
- package/src/modules/log-drains.ts +76 -0
- package/src/modules/metrics.ts +72 -0
- package/src/modules/migrations.ts +51 -0
- package/src/modules/projects.ts +25 -0
- package/src/modules/realtime.ts +30 -0
- package/src/modules/search.ts +37 -0
- package/src/modules/storage.ts +27 -0
- package/src/modules/users.ts +31 -0
- package/src/modules/webhooks.ts +58 -0
- package/src/query-builder.ts +157 -0
- package/src/realtime.ts +157 -0
- package/src/types.ts +49 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +14 -0
package/src/client.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaaS Client SDK
|
|
3
|
+
* A fluent JavaScript/TypeScript client for the Go BaaS.
|
|
4
|
+
*
|
|
5
|
+
* This is the main client that composes all feature modules.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { HttpClient } from './http-client';
|
|
9
|
+
import { QueryBuilder } from './query-builder';
|
|
10
|
+
import { RealtimeAction, RealtimeCallback } from './types';
|
|
11
|
+
|
|
12
|
+
// Module imports
|
|
13
|
+
import { createAuthModule, type AuthModule } from './modules/auth';
|
|
14
|
+
import { createUsersModule, type UsersModule } from './modules/users';
|
|
15
|
+
import { createProjectsModule, type ProjectsModule } from './modules/projects';
|
|
16
|
+
import { createDatabaseModule, type DatabaseModule } from './modules/database';
|
|
17
|
+
import { createStorageModule, type StorageModule } from './modules/storage';
|
|
18
|
+
import { createBackupsModule, type BackupsModule } from './modules/backups';
|
|
19
|
+
import { createMigrationsModule, type MigrationsModule } from './modules/migrations';
|
|
20
|
+
import { createFunctionsModule, type FunctionsModule } from './modules/functions';
|
|
21
|
+
import { createJobsModule, type JobsModule } from './modules/jobs';
|
|
22
|
+
import { createEnvVarsModule, type EnvVarsModule } from './modules/env-vars';
|
|
23
|
+
import { createEmailModule, type EmailModule } from './modules/email';
|
|
24
|
+
import { createSearchModule, type SearchModule } from './modules/search';
|
|
25
|
+
import { createGraphQLModule, type GraphQLModule } from './modules/graphql';
|
|
26
|
+
import { createMetricsModule, type MetricsModule } from './modules/metrics';
|
|
27
|
+
import { createAuditModule, type AuditModule } from './modules/audit';
|
|
28
|
+
import { createWebhooksModule, type WebhooksModule } from './modules/webhooks';
|
|
29
|
+
import { createLogDrainsModule, type LogDrainsModule } from './modules/log-drains';
|
|
30
|
+
import { createBranchesModule, type BranchesModule } from './modules/branches';
|
|
31
|
+
import { createRealtimeModule, type RealtimeModule } from './modules/realtime';
|
|
32
|
+
import { createApiKeysModule, type ApiKeysModule } from './modules/api-keys';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Main BaaS Client - Composes all feature modules
|
|
36
|
+
*
|
|
37
|
+
* Usage:
|
|
38
|
+
* ```ts
|
|
39
|
+
* const client = new BaasClient();
|
|
40
|
+
*
|
|
41
|
+
* // Authentication
|
|
42
|
+
* await client.auth.login('user@example.com', 'password');
|
|
43
|
+
*
|
|
44
|
+
* // Database operations
|
|
45
|
+
* const schemas = await client.database.getSchemas();
|
|
46
|
+
*
|
|
47
|
+
* // Query builder (fluent API)
|
|
48
|
+
* const users = await client.from('users').select('*').limit(10).get();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export class BaasClient extends HttpClient {
|
|
52
|
+
// Feature modules
|
|
53
|
+
public readonly auth: AuthModule;
|
|
54
|
+
public readonly users: UsersModule;
|
|
55
|
+
public readonly projects: ProjectsModule;
|
|
56
|
+
public readonly database: DatabaseModule;
|
|
57
|
+
public readonly storage: StorageModule;
|
|
58
|
+
public readonly backups: BackupsModule;
|
|
59
|
+
public readonly migrations: MigrationsModule;
|
|
60
|
+
public readonly functions: FunctionsModule;
|
|
61
|
+
public readonly jobs: JobsModule;
|
|
62
|
+
public readonly envVars: EnvVarsModule;
|
|
63
|
+
public readonly email: EmailModule;
|
|
64
|
+
public readonly searchService: SearchModule;
|
|
65
|
+
public readonly graphqlService: GraphQLModule;
|
|
66
|
+
public readonly metrics: MetricsModule;
|
|
67
|
+
public readonly audit: AuditModule;
|
|
68
|
+
public readonly webhooks: WebhooksModule;
|
|
69
|
+
public readonly logDrains: LogDrainsModule;
|
|
70
|
+
public readonly branches: BranchesModule;
|
|
71
|
+
public readonly realtime: RealtimeModule;
|
|
72
|
+
public readonly apiKeys: ApiKeysModule;
|
|
73
|
+
|
|
74
|
+
constructor(url?: string, projectID?: string) {
|
|
75
|
+
super(url, projectID);
|
|
76
|
+
|
|
77
|
+
// Initialize all modules with this client instance
|
|
78
|
+
this.auth = createAuthModule(this);
|
|
79
|
+
this.users = createUsersModule(this);
|
|
80
|
+
this.projects = createProjectsModule(this);
|
|
81
|
+
this.database = createDatabaseModule(this);
|
|
82
|
+
this.storage = createStorageModule(this);
|
|
83
|
+
this.backups = createBackupsModule(this);
|
|
84
|
+
this.migrations = createMigrationsModule(this);
|
|
85
|
+
this.functions = createFunctionsModule(this);
|
|
86
|
+
this.jobs = createJobsModule(this);
|
|
87
|
+
this.envVars = createEnvVarsModule(this);
|
|
88
|
+
this.email = createEmailModule(this);
|
|
89
|
+
this.searchService = createSearchModule(this);
|
|
90
|
+
this.graphqlService = createGraphQLModule(this);
|
|
91
|
+
this.metrics = createMetricsModule(this);
|
|
92
|
+
this.audit = createAuditModule(this);
|
|
93
|
+
this.webhooks = createWebhooksModule(this);
|
|
94
|
+
this.logDrains = createLogDrainsModule(this);
|
|
95
|
+
this.branches = createBranchesModule(this);
|
|
96
|
+
this.realtime = createRealtimeModule(this);
|
|
97
|
+
this.apiKeys = createApiKeysModule(this);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create a query builder for fluent data queries
|
|
102
|
+
*/
|
|
103
|
+
from(table: string): QueryBuilder {
|
|
104
|
+
return new QueryBuilder(table, this.url, this);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================
|
|
108
|
+
// BACKWARD COMPATIBILITY METHODS
|
|
109
|
+
// These delegate to the appropriate modules
|
|
110
|
+
// ============================================
|
|
111
|
+
|
|
112
|
+
// Auth shortcuts
|
|
113
|
+
async login(email: string, password: string) { return this.auth.login(email, password); }
|
|
114
|
+
async verifyMFA(mfaToken: string, code: string) { return this.auth.verifyMFA(mfaToken, code); }
|
|
115
|
+
async getProfile() { return this.auth.getProfile(); }
|
|
116
|
+
async register(email: string, password: string) { return this.auth.register(email, password); }
|
|
117
|
+
async forgotPassword(email: string) { return this.auth.forgotPassword(email); }
|
|
118
|
+
async resetPassword(token: string, newPassword: string) { return this.auth.resetPassword(token, newPassword); }
|
|
119
|
+
async validateResetToken(token: string) { return this.auth.validateResetToken(token); }
|
|
120
|
+
async verifyEmail(token: string) { return this.auth.verifyEmail(token); }
|
|
121
|
+
async requestEmailVerification() { return this.auth.requestEmailVerification(); }
|
|
122
|
+
async getAuthProviders() { return this.auth.getAuthProviders(); }
|
|
123
|
+
async getAuthProvider(provider: string) { return this.auth.getAuthProvider(provider); }
|
|
124
|
+
async configureAuthProvider(provider: string, clientID: string, clientSecret: string, enabled: boolean) {
|
|
125
|
+
return this.auth.configureAuthProvider(provider, clientID, clientSecret, enabled);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Users shortcuts
|
|
129
|
+
async listUsers(limit = 20, offset = 0) { return this.users.list(limit, offset); }
|
|
130
|
+
async updateUser(id: string, updates: any) { return this.users.update(id, updates); }
|
|
131
|
+
async deleteUser(id: string) { return this.users.delete(id); }
|
|
132
|
+
|
|
133
|
+
// Projects shortcuts
|
|
134
|
+
async listProjects() { return this.projects.list(); }
|
|
135
|
+
async createProject(name: string) { return this.projects.create(name); }
|
|
136
|
+
|
|
137
|
+
// Database shortcuts
|
|
138
|
+
async raw(query: string) { return this.database.raw(query); }
|
|
139
|
+
async getSchemas(options?: any) { return this.database.getSchemas(options); }
|
|
140
|
+
async getSchema(name: string) { return this.database.getSchema(name); }
|
|
141
|
+
async createTable(tableName: string, definition: any) { return this.database.createTable(tableName, definition); }
|
|
142
|
+
async dropTable(tableName: string) { return this.database.dropTable(tableName); }
|
|
143
|
+
async renameTable(tableName: string, newName: string) { return this.database.renameTable(tableName, newName); }
|
|
144
|
+
async addColumn(tableName: string, column: any) { return this.database.addColumn(tableName, column); }
|
|
145
|
+
async dropColumn(tableName: string, columnName: string) { return this.database.dropColumn(tableName, columnName); }
|
|
146
|
+
async modifyColumn(tableName: string, columnName: string, changes: any) { return this.database.modifyColumn(tableName, columnName, changes); }
|
|
147
|
+
async renameColumn(tableName: string, columnName: string, newName: string) { return this.database.renameColumn(tableName, columnName, newName); }
|
|
148
|
+
async setColumnDefault(tableName: string, columnName: string, defaultValue: string | null) { return this.database.setColumnDefault(tableName, columnName, defaultValue); }
|
|
149
|
+
async addForeignKey(tableName: string, fk: any) { return this.database.addForeignKey(tableName, fk); }
|
|
150
|
+
async listForeignKeys(tableName: string) { return this.database.listForeignKeys(tableName); }
|
|
151
|
+
async dropForeignKey(tableName: string, constraintName: string) { return this.database.dropForeignKey(tableName, constraintName); }
|
|
152
|
+
async addUniqueConstraint(tableName: string, columnName: string) { return this.database.addUniqueConstraint(tableName, columnName); }
|
|
153
|
+
async dropConstraint(tableName: string, constraintName: string) { return this.database.dropConstraint(tableName, constraintName); }
|
|
154
|
+
async queryData(tableName: string, options: any) { return this.database.queryData(tableName, options); }
|
|
155
|
+
async downloadExport(tableName: string, format: 'sql' | 'csv' | 'backup', filters?: any[]) { return this.database.downloadExport(tableName, format, filters); }
|
|
156
|
+
|
|
157
|
+
// Storage shortcuts
|
|
158
|
+
async upload(table: string, file: File) { return this.storage.upload(table, file); }
|
|
159
|
+
|
|
160
|
+
// Functions shortcuts
|
|
161
|
+
async invokeFunction(id: string, data?: any) { return this.functions.invoke(id, data); }
|
|
162
|
+
|
|
163
|
+
// API Keys shortcuts
|
|
164
|
+
async createApiKey(name: string, permissions?: string[], expiresAt?: string) { return this.apiKeys.create(name, permissions, expiresAt); }
|
|
165
|
+
async listApiKeys() { return this.apiKeys.list(); }
|
|
166
|
+
async revokeApiKey(keyId: string) { return this.apiKeys.revoke(keyId); }
|
|
167
|
+
async deleteApiKey(keyId: string) { return this.apiKeys.delete(keyId); }
|
|
168
|
+
|
|
169
|
+
// Backups shortcuts
|
|
170
|
+
async createBackup(options?: any) { return this.backups.create(options); }
|
|
171
|
+
async listBackups() { return this.backups.list(); }
|
|
172
|
+
async getBackup(backupId: string) { return this.backups.get(backupId); }
|
|
173
|
+
async restoreBackup(backupId: string) { return this.backups.restore(backupId); }
|
|
174
|
+
async deleteBackup(backupId: string) { return this.backups.delete(backupId); }
|
|
175
|
+
getBackupDownloadUrl(backupId: string) { return this.backups.getDownloadUrl(backupId); }
|
|
176
|
+
async listBackupTables() { return this.backups.listTables(); }
|
|
177
|
+
async importFile(formData: FormData) { return this.backups.importFile(formData); }
|
|
178
|
+
|
|
179
|
+
// Search shortcuts
|
|
180
|
+
async search(query: string, options?: any) { return this.searchService.search(query, options); }
|
|
181
|
+
async createSearchIndex(table: string, columns: string[]) { return this.searchService.createIndex(table, columns); }
|
|
182
|
+
|
|
183
|
+
// GraphQL shortcuts
|
|
184
|
+
async graphql(query: string, variables?: Record<string, any>) { return this.graphqlService.query(query, variables); }
|
|
185
|
+
getGraphQLPlaygroundUrl() { return this.graphqlService.getPlaygroundUrl(); }
|
|
186
|
+
|
|
187
|
+
// Migrations shortcuts
|
|
188
|
+
async createMigration(input: any) { return this.migrations.create(input); }
|
|
189
|
+
async listMigrations() { return this.migrations.list(); }
|
|
190
|
+
async getMigration(id: string) { return this.migrations.get(id); }
|
|
191
|
+
async applyMigration(id: string) { return this.migrations.apply(id); }
|
|
192
|
+
async rollbackMigration(id: string) { return this.migrations.rollback(id); }
|
|
193
|
+
async deleteMigration(id: string) { return this.migrations.delete(id); }
|
|
194
|
+
async generateMigration(tableName: string, changes: any[]) { return this.migrations.generate(tableName, changes); }
|
|
195
|
+
|
|
196
|
+
// Email shortcuts
|
|
197
|
+
async sendEmail(input: any) { return this.email.send(input); }
|
|
198
|
+
async getEmailConfig() { return this.email.getConfig(); }
|
|
199
|
+
async saveEmailConfig(config: any) { return this.email.saveConfig(config); }
|
|
200
|
+
async createEmailTemplate(template: any) { return this.email.createTemplate(template); }
|
|
201
|
+
async listEmailTemplates() { return this.email.listTemplates(); }
|
|
202
|
+
async getEmailTemplate(id: string) { return this.email.getTemplate(id); }
|
|
203
|
+
async updateEmailTemplate(id: string, template: any) { return this.email.updateTemplate(id, template); }
|
|
204
|
+
async deleteEmailTemplate(id: string) { return this.email.deleteTemplate(id); }
|
|
205
|
+
async getEmailLogs(options?: any) { return this.email.getLogs(options); }
|
|
206
|
+
|
|
207
|
+
// Metrics shortcuts
|
|
208
|
+
async getDashboardStats() { return this.metrics.getDashboardStats(); }
|
|
209
|
+
async getRequestLogs(options?: any) { return this.metrics.getRequestLogs(options); }
|
|
210
|
+
async getApplicationLogs(options?: any) { return this.metrics.getApplicationLogs(options); }
|
|
211
|
+
async getMetricTimeseries(metric: string, options?: any) { return this.metrics.getTimeseries(metric, options); }
|
|
212
|
+
|
|
213
|
+
// Jobs shortcuts
|
|
214
|
+
async createJob(input: any) { return this.jobs.create(input); }
|
|
215
|
+
async listJobs() { return this.jobs.list(); }
|
|
216
|
+
async getJob(id: string) { return this.jobs.get(id); }
|
|
217
|
+
async updateJob(id: string, input: any) { return this.jobs.update(id, input); }
|
|
218
|
+
async deleteJob(id: string) { return this.jobs.delete(id); }
|
|
219
|
+
async toggleJob(id: string, enabled: boolean) { return this.jobs.toggle(id, enabled); }
|
|
220
|
+
async runJobNow(id: string) { return this.jobs.runNow(id); }
|
|
221
|
+
async getJobExecutions(id: string, limit?: number) { return this.jobs.getExecutions(id, limit); }
|
|
222
|
+
|
|
223
|
+
// Env Vars shortcuts
|
|
224
|
+
async createEnvVar(input: any) { return this.envVars.create(input); }
|
|
225
|
+
async listEnvVars() { return this.envVars.list(); }
|
|
226
|
+
async getEnvVar(id: string) { return this.envVars.get(id); }
|
|
227
|
+
async updateEnvVar(id: string, value: string) { return this.envVars.update(id, value); }
|
|
228
|
+
async deleteEnvVar(id: string) { return this.envVars.delete(id); }
|
|
229
|
+
|
|
230
|
+
// Branches shortcuts
|
|
231
|
+
async createBranch(input: any) { return this.branches.create(input); }
|
|
232
|
+
async listBranches() { return this.branches.list(); }
|
|
233
|
+
async getBranch(id: string) { return this.branches.get(id); }
|
|
234
|
+
async deleteBranch(id: string) { return this.branches.delete(id); }
|
|
235
|
+
async mergeBranch(id: string, targetBranchId: string) { return this.branches.merge(id, targetBranchId); }
|
|
236
|
+
async resetBranch(id: string) { return this.branches.reset(id); }
|
|
237
|
+
|
|
238
|
+
// Log Drains shortcuts
|
|
239
|
+
async createLogDrain(input: any) { return this.logDrains.create(input); }
|
|
240
|
+
async listLogDrains() { return this.logDrains.list(); }
|
|
241
|
+
async getLogDrain(id: string) { return this.logDrains.get(id); }
|
|
242
|
+
async updateLogDrain(id: string, input: any) { return this.logDrains.update(id, input); }
|
|
243
|
+
async deleteLogDrain(id: string) { return this.logDrains.delete(id); }
|
|
244
|
+
async toggleLogDrain(id: string, enabled: boolean) { return this.logDrains.toggle(id, enabled); }
|
|
245
|
+
async testLogDrain(id: string) { return this.logDrains.test(id); }
|
|
246
|
+
|
|
247
|
+
// Webhooks shortcuts
|
|
248
|
+
async listWebhooks() { return this.webhooks.list(); }
|
|
249
|
+
async getWebhook(id: string) { return this.webhooks.get(id); }
|
|
250
|
+
async createWebhook(input: any) { return this.webhooks.create(input); }
|
|
251
|
+
async updateWebhook(id: string, input: any) { return this.webhooks.update(id, input); }
|
|
252
|
+
async deleteWebhook(id: string) { return this.webhooks.delete(id); }
|
|
253
|
+
async testWebhook(id: string) { return this.webhooks.test(id); }
|
|
254
|
+
|
|
255
|
+
// Audit shortcuts
|
|
256
|
+
async listAuditLogs(options?: any) { return this.audit.list(options); }
|
|
257
|
+
async getAuditActions() { return this.audit.getActions(); }
|
|
258
|
+
|
|
259
|
+
// Realtime shortcuts
|
|
260
|
+
subscribe<T = any>(table: string, action: RealtimeAction, callback: RealtimeCallback<T>) {
|
|
261
|
+
return this.realtime.subscribe<T>(table, action, callback);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core HTTP Client
|
|
3
|
+
* Base class providing HTTP request infrastructure for all SDK modules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { RequestOptions } from './types';
|
|
7
|
+
|
|
8
|
+
export class HttpClient {
|
|
9
|
+
public url: string;
|
|
10
|
+
public projectID: string = '';
|
|
11
|
+
public token: string | null = null;
|
|
12
|
+
|
|
13
|
+
constructor(url?: string, projectID?: string) {
|
|
14
|
+
let baseUrl = url || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost:8080');
|
|
15
|
+
this.url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
16
|
+
|
|
17
|
+
if (projectID) this.projectID = projectID;
|
|
18
|
+
|
|
19
|
+
this.token = this.cleanValue(localStorage.getItem('baas_token'));
|
|
20
|
+
const storedProject = this.cleanValue(localStorage.getItem('baas_project_id'));
|
|
21
|
+
if (storedProject && !this.projectID) {
|
|
22
|
+
this.projectID = storedProject;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
protected cleanValue(val: string | null): string | null {
|
|
27
|
+
if (!val || val === 'null' || val === 'undefined') return null;
|
|
28
|
+
return val.trim();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Public header generator for adapters
|
|
33
|
+
*/
|
|
34
|
+
public getHeaders(contentType: string = 'application/json') {
|
|
35
|
+
const dynamicProject = this.getDynamicProjectID();
|
|
36
|
+
const dynamicToken = this.getDynamicToken();
|
|
37
|
+
|
|
38
|
+
const headers: Record<string, string> = {
|
|
39
|
+
'X-Project-ID': dynamicProject,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (contentType) {
|
|
43
|
+
headers['Content-Type'] = contentType;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (dynamicToken) {
|
|
47
|
+
headers['Authorization'] = `Bearer ${dynamicToken}`;
|
|
48
|
+
}
|
|
49
|
+
return headers;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public getDynamicToken() {
|
|
53
|
+
return this.cleanValue(this.token || localStorage.getItem('baas_token'));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public getDynamicProjectID() {
|
|
57
|
+
const stored = this.cleanValue(localStorage.getItem('baas_project_id'));
|
|
58
|
+
if (this.projectID && this.projectID !== 'default' && this.projectID !== '') {
|
|
59
|
+
return this.projectID;
|
|
60
|
+
}
|
|
61
|
+
return stored || 'default';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Core HTTP request method - DRY principle
|
|
66
|
+
*/
|
|
67
|
+
protected async request<T = any>(endpoint: string, options: RequestOptions = {}): Promise<T> {
|
|
68
|
+
const { method = 'GET', body, headers: customHeaders, skipAuth = false } = options;
|
|
69
|
+
|
|
70
|
+
const headers = { ...this.getHeaders(), ...customHeaders };
|
|
71
|
+
|
|
72
|
+
const fetchOptions: RequestInit = {
|
|
73
|
+
method,
|
|
74
|
+
headers,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
if (body !== undefined) {
|
|
78
|
+
fetchOptions.body = JSON.stringify(body);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const res = await fetch(`${this.url}${endpoint}`, fetchOptions);
|
|
82
|
+
|
|
83
|
+
if (res.status === 204) {
|
|
84
|
+
return { success: true } as T;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const data = await res.json().catch(() => null);
|
|
88
|
+
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
if (res.status === 401 && !skipAuth) {
|
|
91
|
+
this.forceLogout();
|
|
92
|
+
}
|
|
93
|
+
if (res.status === 403 && data?.error === 'ip_not_allowed') {
|
|
94
|
+
this.handleIPBlocked(data.ip);
|
|
95
|
+
}
|
|
96
|
+
return { error: data?.error || `Request failed: ${res.status}`, ...data } as T;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return data;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected get<T = any>(endpoint: string): Promise<T> {
|
|
103
|
+
return this.request<T>(endpoint);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected post<T = any>(endpoint: string, body?: unknown): Promise<T> {
|
|
107
|
+
return this.request<T>(endpoint, { method: 'POST', body });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected put<T = any>(endpoint: string, body?: unknown): Promise<T> {
|
|
111
|
+
return this.request<T>(endpoint, { method: 'PUT', body });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected patch<T = any>(endpoint: string, body?: unknown): Promise<T> {
|
|
115
|
+
return this.request<T>(endpoint, { method: 'PATCH', body });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected delete<T = any>(endpoint: string): Promise<T> {
|
|
119
|
+
return this.request<T>(endpoint, { method: 'DELETE' });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
logout() {
|
|
123
|
+
this.token = null;
|
|
124
|
+
localStorage.removeItem('baas_token');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
forceLogout() {
|
|
128
|
+
this.logout();
|
|
129
|
+
if (typeof window !== 'undefined') {
|
|
130
|
+
if (!window.location.search.includes('expired')) {
|
|
131
|
+
window.location.href = '/auth/login?reason=expired';
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
handleIPBlocked(ip?: string) {
|
|
137
|
+
if (typeof window !== 'undefined') {
|
|
138
|
+
const params = ip ? `?ip=${encodeURIComponent(ip)}` : '';
|
|
139
|
+
if (!window.location.pathname.includes('/blocked')) {
|
|
140
|
+
window.location.href = `/blocked${params}`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaaS SDK - Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all SDK components for easy importing:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { BaasClient } from '@/sdk';
|
|
8
|
+
* // or
|
|
9
|
+
* import { BaasClient, QueryFilter } from '@/sdk';
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Main client
|
|
14
|
+
export { BaasClient } from './client';
|
|
15
|
+
|
|
16
|
+
// Core utilities
|
|
17
|
+
export { HttpClient } from './http-client';
|
|
18
|
+
export { QueryBuilder } from './query-builder';
|
|
19
|
+
|
|
20
|
+
// Types
|
|
21
|
+
export type { QueryFilter, HttpMethod, RequestOptions, PaginationOptions, ApiResponse } from './types';
|
|
22
|
+
|
|
23
|
+
// Module types (for advanced usage)
|
|
24
|
+
export type { AuthModule } from './modules/auth';
|
|
25
|
+
export type { UsersModule } from './modules/users';
|
|
26
|
+
export type { ProjectsModule } from './modules/projects';
|
|
27
|
+
export type { DatabaseModule } from './modules/database';
|
|
28
|
+
export type { StorageModule } from './modules/storage';
|
|
29
|
+
export type { BackupsModule } from './modules/backups';
|
|
30
|
+
export type { MigrationsModule } from './modules/migrations';
|
|
31
|
+
export type { FunctionsModule } from './modules/functions';
|
|
32
|
+
export type { JobsModule, JobInput, JobUpdateInput } from './modules/jobs';
|
|
33
|
+
export type { EnvVarsModule } from './modules/env-vars';
|
|
34
|
+
export type { EmailModule, EmailConfig, EmailTemplate, SendEmailInput } from './modules/email';
|
|
35
|
+
export type { SearchModule, SearchOptions } from './modules/search';
|
|
36
|
+
export type { GraphQLModule } from './modules/graphql';
|
|
37
|
+
export type { MetricsModule, RequestLogsOptions, ApplicationLogsOptions, TimeseriesOptions } from './modules/metrics';
|
|
38
|
+
export type { AuditModule, AuditLogsOptions } from './modules/audit';
|
|
39
|
+
export type { WebhooksModule, WebhookInput, WebhookUpdateInput } from './modules/webhooks';
|
|
40
|
+
export type { LogDrainsModule, LogDrainInput, LogDrainUpdateInput } from './modules/log-drains';
|
|
41
|
+
export type { BranchesModule } from './modules/branches';
|
|
42
|
+
export type { RealtimeModule, Subscription } from './modules/realtime';
|
|
43
|
+
export type { ApiKeysModule } from './modules/api-keys';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Keys Module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../http-client';
|
|
6
|
+
|
|
7
|
+
export interface ApiKeysModule {
|
|
8
|
+
create(name: string, permissions?: string[], expiresAt?: string): Promise<any>;
|
|
9
|
+
list(): Promise<any>;
|
|
10
|
+
revoke(keyId: string): Promise<any>;
|
|
11
|
+
delete(keyId: string): Promise<any>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function createApiKeysModule(client: HttpClient): ApiKeysModule {
|
|
15
|
+
const get = (endpoint: string) => (client as any).get(endpoint);
|
|
16
|
+
const post = (endpoint: string, body?: unknown) => (client as any).post(endpoint, body);
|
|
17
|
+
const del = (endpoint: string) => (client as any).delete(endpoint);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
async create(name: string, permissions?: string[], expiresAt?: string) {
|
|
21
|
+
return post('/api/api-keys', { name, permissions, expires_at: expiresAt });
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
async list() {
|
|
25
|
+
return get('/api/api-keys');
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
async revoke(keyId: string) {
|
|
29
|
+
return post(`/api/api-keys/${keyId}/revoke`, {});
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
async delete(keyId: string) {
|
|
33
|
+
return del(`/api/api-keys/${keyId}`);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Module - Audit log operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../http-client';
|
|
6
|
+
|
|
7
|
+
export interface AuditLogsOptions {
|
|
8
|
+
limit?: number;
|
|
9
|
+
offset?: number;
|
|
10
|
+
action?: string;
|
|
11
|
+
user_id?: string;
|
|
12
|
+
method?: string;
|
|
13
|
+
path?: string;
|
|
14
|
+
status_code?: number;
|
|
15
|
+
start_date?: string;
|
|
16
|
+
end_date?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface AuditModule {
|
|
20
|
+
list(options?: AuditLogsOptions): Promise<any>;
|
|
21
|
+
getActions(): Promise<any>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createAuditModule(client: HttpClient): AuditModule {
|
|
25
|
+
const get = (endpoint: string) => (client as any).get(endpoint);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
async list(options?: AuditLogsOptions) {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (options?.limit) params.set('limit', options.limit.toString());
|
|
31
|
+
if (options?.offset) params.set('offset', options.offset.toString());
|
|
32
|
+
if (options?.action) params.set('action', options.action);
|
|
33
|
+
if (options?.user_id) params.set('user_id', options.user_id);
|
|
34
|
+
if (options?.method) params.set('method', options.method);
|
|
35
|
+
if (options?.path) params.set('path', options.path);
|
|
36
|
+
if (options?.status_code) params.set('status_code', options.status_code.toString());
|
|
37
|
+
if (options?.start_date) params.set('start_date', options.start_date);
|
|
38
|
+
if (options?.end_date) params.set('end_date', options.end_date);
|
|
39
|
+
return get(`/api/audit/logs?${params.toString()}`);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
async getActions() {
|
|
43
|
+
return get('/api/audit/actions');
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|