@giaeulate/baas-sdk 1.0.0 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giaeulate/baas-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Standalone SDK for BaaS Golang",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/src/client.ts CHANGED
@@ -12,7 +12,6 @@ import { RealtimeAction, RealtimeCallback } from './types';
12
12
  // Module imports
13
13
  import { createAuthModule, type AuthModule } from './modules/auth';
14
14
  import { createUsersModule, type UsersModule } from './modules/users';
15
- import { createProjectsModule, type ProjectsModule } from './modules/projects';
16
15
  import { createDatabaseModule, type DatabaseModule } from './modules/database';
17
16
  import { createStorageModule, type StorageModule } from './modules/storage';
18
17
  import { createBackupsModule, type BackupsModule } from './modules/backups';
@@ -30,6 +29,7 @@ import { createLogDrainsModule, type LogDrainsModule } from './modules/log-drain
30
29
  import { createBranchesModule, type BranchesModule } from './modules/branches';
31
30
  import { createRealtimeModule, type RealtimeModule } from './modules/realtime';
32
31
  import { createApiKeysModule, type ApiKeysModule } from './modules/api-keys';
32
+ import { createEnvironmentsModule, type EnvironmentsModule } from './modules/environments';
33
33
 
34
34
  /**
35
35
  * Main BaaS Client - Composes all feature modules
@@ -52,7 +52,6 @@ export class BaasClient extends HttpClient {
52
52
  // Feature modules
53
53
  public readonly auth: AuthModule;
54
54
  public readonly users: UsersModule;
55
- public readonly projects: ProjectsModule;
56
55
  public readonly database: DatabaseModule;
57
56
  public readonly storage: StorageModule;
58
57
  public readonly backups: BackupsModule;
@@ -70,14 +69,14 @@ export class BaasClient extends HttpClient {
70
69
  public readonly branches: BranchesModule;
71
70
  public readonly realtime: RealtimeModule;
72
71
  public readonly apiKeys: ApiKeysModule;
72
+ public readonly environments: EnvironmentsModule;
73
73
 
74
- constructor(url?: string, projectID?: string) {
75
- super(url, projectID);
74
+ constructor(url?: string, apiKey?: string) {
75
+ super(url, apiKey);
76
76
 
77
77
  // Initialize all modules with this client instance
78
78
  this.auth = createAuthModule(this);
79
79
  this.users = createUsersModule(this);
80
- this.projects = createProjectsModule(this);
81
80
  this.database = createDatabaseModule(this);
82
81
  this.storage = createStorageModule(this);
83
82
  this.backups = createBackupsModule(this);
@@ -95,6 +94,7 @@ export class BaasClient extends HttpClient {
95
94
  this.branches = createBranchesModule(this);
96
95
  this.realtime = createRealtimeModule(this);
97
96
  this.apiKeys = createApiKeysModule(this);
97
+ this.environments = createEnvironmentsModule(this);
98
98
  }
99
99
 
100
100
  /**
@@ -130,10 +130,6 @@ export class BaasClient extends HttpClient {
130
130
  async updateUser(id: string, updates: any) { return this.users.update(id, updates); }
131
131
  async deleteUser(id: string) { return this.users.delete(id); }
132
132
 
133
- // Projects shortcuts
134
- async listProjects() { return this.projects.list(); }
135
- async createProject(name: string) { return this.projects.create(name); }
136
-
137
133
  // Database shortcuts
138
134
  async raw(query: string) { return this.database.raw(query); }
139
135
  async getSchemas(options?: any) { return this.database.getSchemas(options); }
@@ -257,7 +253,13 @@ export class BaasClient extends HttpClient {
257
253
  async getAuditActions() { return this.audit.getActions(); }
258
254
 
259
255
  // Realtime shortcuts
260
- subscribe<T = any>(table: string, action: RealtimeAction, callback: RealtimeCallback<T>) {
261
- return this.realtime.subscribe<T>(table, action, callback);
256
+ subscribe<T = any>(table: string, action: RealtimeAction, callback: RealtimeCallback<T>) {
257
+ return this.realtime.subscribe<T>(table, action, callback);
262
258
  }
259
+
260
+ // Environment shortcuts
261
+ async getEnvironmentStatus() { return this.environments.status(); }
262
+ async initTestEnvironment() { return this.environments.init(); }
263
+ async promoteTestToProd() { return this.environments.promote(); }
264
+ async revertTestEnvironment() { return this.environments.revert(); }
263
265
  }
@@ -7,20 +7,17 @@ import type { RequestOptions } from './types';
7
7
 
8
8
  export class HttpClient {
9
9
  public url: string;
10
- public projectID: string = '';
10
+ public apiKey: string = '';
11
11
  public token: string | null = null;
12
+ private environment: string = 'prod';
12
13
 
13
- constructor(url?: string, projectID?: string) {
14
+ constructor(url?: string, apiKey?: string) {
14
15
  let baseUrl = url || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost:8080');
15
16
  this.url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
16
-
17
- if (projectID) this.projectID = projectID;
18
-
17
+
18
+ if (apiKey) this.apiKey = apiKey;
19
+
19
20
  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
21
  }
25
22
 
26
23
  protected cleanValue(val: string | null): string | null {
@@ -32,13 +29,12 @@ export class HttpClient {
32
29
  * Public header generator for adapters
33
30
  */
34
31
  public getHeaders(contentType: string = 'application/json') {
35
- const dynamicProject = this.getDynamicProjectID();
36
32
  const dynamicToken = this.getDynamicToken();
37
-
33
+
38
34
  const headers: Record<string, string> = {
39
- 'X-Project-ID': dynamicProject,
35
+ 'apikey': this.apiKey,
40
36
  };
41
-
37
+
42
38
  if (contentType) {
43
39
  headers['Content-Type'] = contentType;
44
40
  }
@@ -46,6 +42,11 @@ export class HttpClient {
46
42
  if (dynamicToken) {
47
43
  headers['Authorization'] = `Bearer ${dynamicToken}`;
48
44
  }
45
+
46
+ if (this.environment && this.environment !== 'prod') {
47
+ headers['X-Environment'] = this.environment;
48
+ }
49
+
49
50
  return headers;
50
51
  }
51
52
 
@@ -53,39 +54,31 @@ export class HttpClient {
53
54
  return this.cleanValue(this.token || localStorage.getItem('baas_token'));
54
55
  }
55
56
 
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
57
  /**
65
58
  * Core HTTP request method - DRY principle
66
59
  */
67
60
  protected async request<T = any>(endpoint: string, options: RequestOptions = {}): Promise<T> {
68
61
  const { method = 'GET', body, headers: customHeaders, skipAuth = false } = options;
69
-
62
+
70
63
  const headers = { ...this.getHeaders(), ...customHeaders };
71
-
64
+
72
65
  const fetchOptions: RequestInit = {
73
66
  method,
74
67
  headers,
75
68
  };
76
-
69
+
77
70
  if (body !== undefined) {
78
71
  fetchOptions.body = JSON.stringify(body);
79
72
  }
80
-
73
+
81
74
  const res = await fetch(`${this.url}${endpoint}`, fetchOptions);
82
-
75
+
83
76
  if (res.status === 204) {
84
77
  return { success: true } as T;
85
78
  }
86
-
79
+
87
80
  const data = await res.json().catch(() => null);
88
-
81
+
89
82
  if (!res.ok) {
90
83
  if (res.status === 401 && !skipAuth) {
91
84
  this.forceLogout();
@@ -95,7 +88,7 @@ export class HttpClient {
95
88
  }
96
89
  return { error: data?.error || `Request failed: ${res.status}`, ...data } as T;
97
90
  }
98
-
91
+
99
92
  return data;
100
93
  }
101
94
 
@@ -119,6 +112,14 @@ export class HttpClient {
119
112
  return this.request<T>(endpoint, { method: 'DELETE' });
120
113
  }
121
114
 
115
+ setEnvironment(env: string) {
116
+ this.environment = env;
117
+ }
118
+
119
+ getEnvironment(): string {
120
+ return this.environment;
121
+ }
122
+
122
123
  logout() {
123
124
  this.token = null;
124
125
  localStorage.removeItem('baas_token');
package/src/index.ts CHANGED
@@ -23,7 +23,6 @@ export type { QueryFilter, HttpMethod, RequestOptions, PaginationOptions, ApiRes
23
23
  // Module types (for advanced usage)
24
24
  export type { AuthModule } from './modules/auth';
25
25
  export type { UsersModule } from './modules/users';
26
- export type { ProjectsModule } from './modules/projects';
27
26
  export type { DatabaseModule } from './modules/database';
28
27
  export type { StorageModule } from './modules/storage';
29
28
  export type { BackupsModule } from './modules/backups';
@@ -43,8 +43,7 @@ export function createBackupsModule(client: HttpClient): BackupsModule {
43
43
 
44
44
  getDownloadUrl(backupId: string) {
45
45
  const token = client.getDynamicToken();
46
- const projectId = client.getDynamicProjectID();
47
- return `${client.url}/api/backups/${backupId}/download?access_token=${token}&project_id=${projectId}`;
46
+ return `${client.url}/api/backups/${backupId}/download?access_token=${token}&apikey=${client.apiKey}`;
48
47
  },
49
48
 
50
49
  async listTables() {
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Environments Module - Test/Prod environment management
3
+ */
4
+
5
+ import type { HttpClient } from '../http-client';
6
+
7
+ export interface EnvironmentStatus {
8
+ test_exists: boolean;
9
+ test_status?: string;
10
+ test_created_at?: string;
11
+ test_schema_name?: string;
12
+ prod_schema_name: string;
13
+ table_count: number;
14
+ }
15
+
16
+ export interface PromoteResult {
17
+ tables_promoted: number;
18
+ status: string;
19
+ }
20
+
21
+ export interface EnvironmentsModule {
22
+ status(): Promise<EnvironmentStatus>;
23
+ init(): Promise<any>;
24
+ promote(): Promise<PromoteResult>;
25
+ revert(): Promise<any>;
26
+ setActive(env: 'test' | 'prod'): void;
27
+ getActive(): string;
28
+ }
29
+
30
+ export function createEnvironmentsModule(client: HttpClient): EnvironmentsModule {
31
+ const get = (endpoint: string) => (client as any).get(endpoint);
32
+ const post = (endpoint: string, body?: unknown) => (client as any).post(endpoint, body);
33
+
34
+ return {
35
+ async status() {
36
+ return get('/api/environments/status');
37
+ },
38
+
39
+ async init() {
40
+ return post('/api/environments/init');
41
+ },
42
+
43
+ async promote() {
44
+ return post('/api/environments/promote');
45
+ },
46
+
47
+ async revert() {
48
+ return post('/api/environments/revert');
49
+ },
50
+
51
+ setActive(env: 'test' | 'prod') {
52
+ client.setEnvironment(env);
53
+ },
54
+
55
+ getActive() {
56
+ return client.getEnvironment();
57
+ },
58
+ };
59
+ }
@@ -17,7 +17,7 @@ export interface RealtimeModule {
17
17
  export function createRealtimeModule(client: HttpClient): RealtimeModule {
18
18
  const service = new RealtimeService(
19
19
  client.url,
20
- client.getDynamicProjectID(),
20
+ client.apiKey,
21
21
  () => client.getDynamicToken(),
22
22
  typeof WebSocket !== 'undefined' ? WebSocket : undefined
23
23
  );
package/src/realtime.ts CHANGED
@@ -13,7 +13,7 @@ export class RealtimeService {
13
13
 
14
14
  constructor(
15
15
  private url: string,
16
- private projectId: string | null,
16
+ private apiKey: string,
17
17
  private tokenProvider: () => string | null,
18
18
  private wsConstructor: any = typeof WebSocket !== 'undefined' ? WebSocket : null
19
19
  ) {}
@@ -26,14 +26,14 @@ export class RealtimeService {
26
26
 
27
27
  return new Promise((resolve, reject) => {
28
28
  const token = this.tokenProvider();
29
- if (!this.projectId || !token) {
30
- reject(new Error('Missing project ID or authentication token for Realtime connection'));
29
+ if (!this.apiKey || !token) {
30
+ reject(new Error('Missing API key or authentication token for Realtime connection'));
31
31
  return;
32
32
  }
33
33
 
34
34
  // Convert http/https to ws/wss
35
35
  const wsUrl = this.url.replace(/^http/, 'ws') + '/ws';
36
- const fullUrl = `${wsUrl}?project_id=${this.projectId}&token=${token}`;
36
+ const fullUrl = `${wsUrl}?apikey=${this.apiKey}&token=${token}`;
37
37
 
38
38
  if (!this.wsConstructor) {
39
39
  reject(new Error('WebSocket constructor not provided or available in this environment'));
@@ -1,25 +0,0 @@
1
- /**
2
- * Projects Module - Project management operations
3
- */
4
-
5
- import type { HttpClient } from '../http-client';
6
-
7
- export interface ProjectsModule {
8
- list(): Promise<any>;
9
- create(name: string): Promise<any>;
10
- }
11
-
12
- export function createProjectsModule(client: HttpClient): ProjectsModule {
13
- const get = (endpoint: string) => (client as any).get(endpoint);
14
- const post = (endpoint: string, body?: unknown) => (client as any).post(endpoint, body);
15
-
16
- return {
17
- async list() {
18
- return get('/api/projects');
19
- },
20
-
21
- async create(name: string) {
22
- return post('/api/projects', { name });
23
- },
24
- };
25
- }