@tspvivek/baasix-sdk 0.1.0-alpha.1 → 0.1.0-alpha.3

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 CHANGED
@@ -1080,6 +1080,35 @@ var AuthModule = class {
1080
1080
  }
1081
1081
  };
1082
1082
 
1083
+ // src/utils/sort.ts
1084
+ function normalizeSort(sort) {
1085
+ if (!sort) return void 0;
1086
+ if (typeof sort === "string") {
1087
+ return sort;
1088
+ }
1089
+ if (Array.isArray(sort)) {
1090
+ if (sort.length === 0) return void 0;
1091
+ if (typeof sort[0] === "object" && "column" in sort[0]) {
1092
+ return sort.map((s) => `${s.column}:${s.order.toLowerCase()}`).join(",");
1093
+ }
1094
+ return sort.map((s) => {
1095
+ if (s.startsWith("-")) {
1096
+ return `${s.substring(1)}:desc`;
1097
+ }
1098
+ if (s.includes(":")) {
1099
+ return s;
1100
+ }
1101
+ return `${s}:asc`;
1102
+ }).join(",");
1103
+ }
1104
+ if (typeof sort === "object") {
1105
+ const entries = Object.entries(sort);
1106
+ if (entries.length === 0) return void 0;
1107
+ return entries.map(([field, direction]) => `${field}:${direction.toLowerCase()}`).join(",");
1108
+ }
1109
+ return void 0;
1110
+ }
1111
+
1083
1112
  // src/modules/items.ts
1084
1113
  var QueryBuilder = class {
1085
1114
  collection;
@@ -1387,8 +1416,12 @@ var ItemsModule = class {
1387
1416
  * ```
1388
1417
  */
1389
1418
  async find(params) {
1419
+ const normalizedParams = params ? {
1420
+ ...params,
1421
+ sort: normalizeSort(params.sort)
1422
+ } : void 0;
1390
1423
  return this.client.get(`/items/${this.collection}`, {
1391
- params
1424
+ params: normalizedParams
1392
1425
  });
1393
1426
  }
1394
1427
  /**
@@ -1605,38 +1638,23 @@ var ItemsModule = class {
1605
1638
  * const fileInput = document.querySelector('input[type="file"]');
1606
1639
  * const file = fileInput.files[0];
1607
1640
  *
1608
- * const result = await baasix.items('products').importCSV(file, {
1609
- * delimiter: ',',
1610
- * skipFirstRow: true
1611
- * });
1641
+ * const result = await baasix.items('products').importCSV(file);
1612
1642
  *
1613
- * console.log(`Imported ${result.created} items`);
1643
+ * console.log(`Imported ${result.imported} items`);
1614
1644
  * ```
1615
1645
  */
1616
- async importCSV(file, options) {
1646
+ async importCSV(file) {
1617
1647
  const formData = new FormData();
1618
1648
  if (file instanceof File) {
1619
- formData.append("file", file);
1649
+ formData.append("csvFile", file);
1620
1650
  } else {
1621
- formData.append("file", file);
1622
- }
1623
- if (options?.delimiter) {
1624
- formData.append("delimiter", options.delimiter);
1625
- }
1626
- if (options?.skipFirstRow !== void 0) {
1627
- formData.append("skipFirstRow", String(options.skipFirstRow));
1628
- }
1629
- if (options?.dateFormat) {
1630
- formData.append("dateFormat", options.dateFormat);
1631
- }
1632
- if (options?.fieldMapping) {
1633
- formData.append("fieldMapping", JSON.stringify(options.fieldMapping));
1651
+ formData.append("csvFile", file);
1634
1652
  }
1635
1653
  const response = await this.client.post(
1636
- `/items/${this.collection}/import/csv`,
1654
+ `/items/${this.collection}/import-csv`,
1637
1655
  formData
1638
1656
  );
1639
- return response.data;
1657
+ return response.results;
1640
1658
  }
1641
1659
  /**
1642
1660
  * Import items from a JSON file
@@ -1646,24 +1664,21 @@ var ItemsModule = class {
1646
1664
  * const file = fileInput.files[0]; // JSON file
1647
1665
  * const result = await baasix.items('products').importJSON(file);
1648
1666
  *
1649
- * console.log(`Imported ${result.created} items`);
1667
+ * console.log(`Imported ${result.imported} items`);
1650
1668
  * ```
1651
1669
  */
1652
- async importJSON(file, options) {
1670
+ async importJSON(file) {
1653
1671
  const formData = new FormData();
1654
1672
  if (file instanceof File) {
1655
- formData.append("file", file);
1673
+ formData.append("jsonFile", file);
1656
1674
  } else {
1657
- formData.append("file", file);
1658
- }
1659
- if (options?.fieldMapping) {
1660
- formData.append("fieldMapping", JSON.stringify(options.fieldMapping));
1675
+ formData.append("jsonFile", file);
1661
1676
  }
1662
1677
  const response = await this.client.post(
1663
- `/items/${this.collection}/import/json`,
1678
+ `/items/${this.collection}/import-json`,
1664
1679
  formData
1665
1680
  );
1666
- return response.data;
1681
+ return response.results;
1667
1682
  }
1668
1683
  /**
1669
1684
  * Import items from an array of objects
@@ -1689,19 +1704,22 @@ var ItemsModule = class {
1689
1704
  // Sort Operations
1690
1705
  // ===================
1691
1706
  /**
1692
- * Sort/reorder items (move item before another)
1707
+ * Sort/reorder items (move item before or after another)
1693
1708
  *
1694
1709
  * @example
1695
1710
  * ```typescript
1696
1711
  * // Move item1 before item2
1697
1712
  * await baasix.items('products').sortItem('item1-uuid', 'item2-uuid');
1713
+ *
1714
+ * // Move item1 after item2
1715
+ * await baasix.items('products').sortItem('item1-uuid', 'item2-uuid', 'after');
1698
1716
  * ```
1699
1717
  */
1700
- async sortItem(itemId, beforeItemId) {
1701
- await this.client.post("/utils/sort", {
1702
- collection: this.collection,
1718
+ async sortItem(itemId, targetItemId, mode = "before") {
1719
+ await this.client.post(`/utils/sort/${this.collection}`, {
1703
1720
  item: itemId,
1704
- to: beforeItemId
1721
+ to: targetItemId,
1722
+ mode
1705
1723
  });
1706
1724
  }
1707
1725
  /**
@@ -1719,10 +1737,10 @@ var ItemsModule = class {
1719
1737
  */
1720
1738
  async reorder(orderedIds) {
1721
1739
  for (let i = 1; i < orderedIds.length; i++) {
1722
- await this.client.post("/utils/sort", {
1723
- collection: this.collection,
1740
+ await this.client.post(`/utils/sort/${this.collection}`, {
1724
1741
  item: orderedIds[i],
1725
- to: orderedIds[i - 1]
1742
+ to: orderedIds[i - 1],
1743
+ mode: "after"
1726
1744
  });
1727
1745
  }
1728
1746
  }
@@ -1819,8 +1837,12 @@ var FilesModule = class {
1819
1837
  * ```
1820
1838
  */
1821
1839
  async find(params) {
1840
+ const normalizedParams = params ? {
1841
+ ...params,
1842
+ sort: normalizeSort(params.sort)
1843
+ } : void 0;
1822
1844
  return this.client.get("/files", {
1823
- params
1845
+ params: normalizedParams
1824
1846
  });
1825
1847
  }
1826
1848
  /**
@@ -2002,10 +2024,17 @@ var SchemasModule = class {
2002
2024
  * ```typescript
2003
2025
  * const { data } = await baasix.schemas.find();
2004
2026
  * console.log(data.map(s => s.collectionName));
2027
+ *
2028
+ * // With pagination
2029
+ * const { data } = await baasix.schemas.find({ page: 1, limit: 50 });
2005
2030
  * ```
2006
2031
  */
2007
- async find() {
2008
- return this.client.get("/schemas");
2032
+ async find(params) {
2033
+ const normalizedParams = params ? {
2034
+ ...params,
2035
+ sort: normalizeSort(params.sort)
2036
+ } : void 0;
2037
+ return this.client.get("/schemas", { params: normalizedParams });
2009
2038
  }
2010
2039
  /**
2011
2040
  * Get schema for a specific collection
@@ -2148,6 +2177,23 @@ var SchemasModule = class {
2148
2177
  `/schemas/${collection}/relationships/${relationshipName}`
2149
2178
  );
2150
2179
  }
2180
+ /**
2181
+ * Update a relationship
2182
+ *
2183
+ * @example
2184
+ * ```typescript
2185
+ * await baasix.schemas.updateRelationship('posts', 'author', {
2186
+ * alias: 'authoredPosts',
2187
+ * onDelete: 'CASCADE'
2188
+ * });
2189
+ * ```
2190
+ */
2191
+ async updateRelationship(collection, relationshipName, data) {
2192
+ await this.client.patch(
2193
+ `/schemas/${collection}/relationships/${relationshipName}`,
2194
+ data
2195
+ );
2196
+ }
2151
2197
  /**
2152
2198
  * Create an index on a collection
2153
2199
  *
@@ -2276,71 +2322,56 @@ var NotificationsModule = class {
2276
2322
  });
2277
2323
  }
2278
2324
  /**
2279
- * Get a single notification by ID
2280
- */
2281
- async findOne(id) {
2282
- const response = await this.client.get(
2283
- `/notifications/${id}`
2284
- );
2285
- return response.data;
2286
- }
2287
- /**
2288
- * Mark a notification as seen
2289
- *
2290
- * @example
2291
- * ```typescript
2292
- * await baasix.notifications.markAsSeen('notification-uuid');
2293
- * ```
2294
- */
2295
- async markAsSeen(id) {
2296
- await this.client.patch(`/notifications/${id}/seen`, { seen: true });
2297
- }
2298
- /**
2299
- * Mark multiple notifications as seen
2300
- *
2301
- * @example
2302
- * ```typescript
2303
- * await baasix.notifications.markManySeen(['id1', 'id2', 'id3']);
2304
- * ```
2305
- */
2306
- async markManySeen(ids) {
2307
- await Promise.all(ids.map((id) => this.markAsSeen(id)));
2308
- }
2309
- /**
2310
- * Mark all notifications as seen
2325
+ * Get unread notification count
2311
2326
  *
2312
2327
  * @example
2313
2328
  * ```typescript
2314
- * await baasix.notifications.markAllSeen();
2329
+ * const count = await baasix.notifications.getUnreadCount();
2315
2330
  * ```
2316
2331
  */
2317
- async markAllSeen() {
2318
- await this.client.post("/notifications/seen-all");
2332
+ async getUnreadCount() {
2333
+ const response = await this.client.get(
2334
+ "/notifications/unread/count"
2335
+ );
2336
+ return response.count;
2319
2337
  }
2320
2338
  /**
2321
- * Get unread notification count
2339
+ * Mark notifications as seen
2322
2340
  *
2323
2341
  * @example
2324
2342
  * ```typescript
2325
- * const count = await baasix.notifications.getUnreadCount();
2343
+ * // Mark specific notifications as seen
2344
+ * await baasix.notifications.markAsSeen(['id1', 'id2']);
2345
+ *
2346
+ * // Mark all notifications as seen
2347
+ * await baasix.notifications.markAsSeen();
2326
2348
  * ```
2327
2349
  */
2328
- async getUnreadCount() {
2329
- const response = await this.client.get(
2330
- "/notifications/unread-count"
2350
+ async markAsSeen(notificationIds) {
2351
+ const response = await this.client.post(
2352
+ "/notifications/mark-seen",
2353
+ { notificationIds }
2331
2354
  );
2332
- return response.data.count;
2355
+ return { count: response.count };
2333
2356
  }
2334
2357
  /**
2335
- * Delete a notification
2358
+ * Delete notifications for the current user
2336
2359
  *
2337
2360
  * @example
2338
2361
  * ```typescript
2339
- * await baasix.notifications.delete('notification-uuid');
2362
+ * // Delete specific notifications
2363
+ * await baasix.notifications.delete(['id1', 'id2']);
2364
+ *
2365
+ * // Delete all notifications
2366
+ * await baasix.notifications.delete();
2340
2367
  * ```
2341
2368
  */
2342
- async delete(id) {
2343
- await this.client.delete(`/notifications/${id}`);
2369
+ async delete(notificationIds) {
2370
+ const response = await this.client.delete(
2371
+ "/notifications",
2372
+ { params: notificationIds ? { notificationIds } : void 0 }
2373
+ );
2374
+ return { count: response.count };
2344
2375
  }
2345
2376
  /**
2346
2377
  * Send a notification to users (requires admin permissions)
@@ -2357,7 +2388,30 @@ var NotificationsModule = class {
2357
2388
  * ```
2358
2389
  */
2359
2390
  async send(data) {
2360
- await this.client.post("/notifications/send", data);
2391
+ const response = await this.client.post(
2392
+ "/notifications/send",
2393
+ data
2394
+ );
2395
+ return { notificationIds: response.notificationIds };
2396
+ }
2397
+ /**
2398
+ * Cleanup old notifications (requires admin permissions)
2399
+ *
2400
+ * @example
2401
+ * ```typescript
2402
+ * // Clean up notifications older than 30 days (default)
2403
+ * await baasix.notifications.cleanup();
2404
+ *
2405
+ * // Clean up notifications older than 7 days
2406
+ * await baasix.notifications.cleanup(7);
2407
+ * ```
2408
+ */
2409
+ async cleanup(days = 30) {
2410
+ const response = await this.client.post(
2411
+ "/notifications/cleanup",
2412
+ { days }
2413
+ );
2414
+ return { count: response.count };
2361
2415
  }
2362
2416
  };
2363
2417
 
@@ -3714,15 +3768,21 @@ var MigrationsModule = class {
3714
3768
  return response.data;
3715
3769
  }
3716
3770
  /**
3717
- * Get all completed migrations
3771
+ * Get all migrations with optional filtering
3718
3772
  *
3719
3773
  * @example
3720
3774
  * ```typescript
3775
+ * // Get all migrations
3721
3776
  * const migrations = await baasix.migrations.list();
3777
+ *
3778
+ * // Get completed migrations
3779
+ * const completed = await baasix.migrations.list({ status: 'completed' });
3722
3780
  * ```
3723
3781
  */
3724
- async list() {
3725
- const response = await this.client.get("/migrations");
3782
+ async list(options) {
3783
+ const response = await this.client.get("/migrations", {
3784
+ params: options
3785
+ });
3726
3786
  return response.data;
3727
3787
  }
3728
3788
  /**
@@ -3740,31 +3800,34 @@ var MigrationsModule = class {
3740
3800
  return response.data;
3741
3801
  }
3742
3802
  /**
3743
- * Check if there are pending migrations
3803
+ * Check if migrations are needed
3744
3804
  *
3745
3805
  * @example
3746
3806
  * ```typescript
3747
- * const needsMigration = await baasix.migrations.hasPending();
3807
+ * const check = await baasix.migrations.check();
3808
+ * if (check.hasPending) {
3809
+ * console.log('Migrations needed');
3810
+ * }
3748
3811
  * ```
3749
3812
  */
3750
- async hasPending() {
3813
+ async check() {
3751
3814
  const response = await this.client.get(
3752
3815
  "/migrations/check"
3753
3816
  );
3754
- return response.data.hasPending;
3817
+ return response.data;
3755
3818
  }
3756
3819
  /**
3757
- * Get a specific migration by name
3820
+ * Get a specific migration by version
3758
3821
  *
3759
3822
  * @example
3760
3823
  * ```typescript
3761
- * const migration = await baasix.migrations.get('20231201_create_users');
3824
+ * const migration = await baasix.migrations.get('20231201000000');
3762
3825
  * ```
3763
3826
  */
3764
- async get(name) {
3827
+ async get(version) {
3765
3828
  try {
3766
3829
  const response = await this.client.get(
3767
- `/migrations/${encodeURIComponent(name)}`
3830
+ `/migrations/${encodeURIComponent(version)}`
3768
3831
  );
3769
3832
  return response.data;
3770
3833
  } catch {
@@ -3776,14 +3839,20 @@ var MigrationsModule = class {
3776
3839
  *
3777
3840
  * @example
3778
3841
  * ```typescript
3842
+ * // Run all pending migrations
3779
3843
  * const result = await baasix.migrations.run();
3780
- * console.log(`Ran ${result.migrationsRun.length} migrations`);
3844
+ *
3845
+ * // Run with options
3846
+ * const result = await baasix.migrations.run({
3847
+ * step: 1, // Run only 1 migration
3848
+ * dryRun: true // Preview without executing
3849
+ * });
3781
3850
  * ```
3782
3851
  */
3783
- async run() {
3852
+ async run(options) {
3784
3853
  const response = await this.client.post(
3785
3854
  "/migrations/run",
3786
- {}
3855
+ options || {}
3787
3856
  );
3788
3857
  return response.data;
3789
3858
  }
@@ -3792,13 +3861,13 @@ var MigrationsModule = class {
3792
3861
  *
3793
3862
  * @example
3794
3863
  * ```typescript
3795
- * const result = await baasix.migrations.rollback('20231201_create_users');
3864
+ * const result = await baasix.migrations.rollback('20231201000000');
3796
3865
  * ```
3797
3866
  */
3798
- async rollback(name) {
3867
+ async rollback(version) {
3799
3868
  const response = await this.client.post(
3800
- "/migrations/rollback",
3801
- { name }
3869
+ `/migrations/rollback/${encodeURIComponent(version)}`,
3870
+ {}
3802
3871
  );
3803
3872
  return response.data;
3804
3873
  }
@@ -3807,12 +3876,12 @@ var MigrationsModule = class {
3807
3876
  *
3808
3877
  * @example
3809
3878
  * ```typescript
3810
- * const result = await baasix.migrations.rollbackLast();
3879
+ * const result = await baasix.migrations.rollbackBatch();
3811
3880
  * ```
3812
3881
  */
3813
- async rollbackLast() {
3882
+ async rollbackBatch() {
3814
3883
  const response = await this.client.post(
3815
- "/migrations/rollback-last",
3884
+ "/migrations/rollback-batch",
3816
3885
  {}
3817
3886
  );
3818
3887
  return response.data;
@@ -3822,37 +3891,91 @@ var MigrationsModule = class {
3822
3891
  *
3823
3892
  * @example
3824
3893
  * ```typescript
3825
- * const migrationName = await baasix.migrations.create('add_status_column');
3894
+ * const { filepath } = await baasix.migrations.create('add_status_column', {
3895
+ * type: 'schema',
3896
+ * description: 'Add status column to orders'
3897
+ * });
3826
3898
  * ```
3827
3899
  */
3828
- async create(name) {
3900
+ async create(name, options) {
3829
3901
  const response = await this.client.post(
3830
3902
  "/migrations/create",
3831
- { name }
3903
+ { name, ...options }
3832
3904
  );
3833
- return response.data.name;
3905
+ return response.data;
3834
3906
  }
3835
3907
  /**
3836
- * Mark a migration as complete (without running it)
3908
+ * Mark a specific migration as completed without running it
3909
+ * Useful for existing installations that already have the changes
3837
3910
  *
3838
3911
  * @example
3839
3912
  * ```typescript
3840
- * await baasix.migrations.markComplete('20231201_create_users');
3913
+ * await baasix.migrations.markCompleted('20231201000000');
3841
3914
  * ```
3842
3915
  */
3843
- async markComplete(name) {
3844
- await this.client.post("/migrations/mark-complete", { name });
3916
+ async markCompleted(version, metadata) {
3917
+ const response = await this.client.post(
3918
+ `/migrations/mark-completed/${encodeURIComponent(version)}`,
3919
+ { metadata }
3920
+ );
3921
+ return response.data;
3845
3922
  }
3846
3923
  /**
3847
- * Mark all pending migrations as complete
3924
+ * Mark all pending migrations as completed
3925
+ * Useful for bringing an existing database up to date without running migrations
3926
+ *
3927
+ * @example
3928
+ * ```typescript
3929
+ * // Mark all pending
3930
+ * await baasix.migrations.markAllCompleted();
3848
3931
  *
3932
+ * // Mark up to a specific version
3933
+ * await baasix.migrations.markAllCompleted('20231201000000');
3934
+ * ```
3935
+ */
3936
+ async markAllCompleted(toVersion) {
3937
+ const response = await this.client.post(
3938
+ "/migrations/mark-all-completed",
3939
+ { toVersion }
3940
+ );
3941
+ return response.data;
3942
+ }
3943
+ };
3944
+
3945
+ // src/modules/server.ts
3946
+ var ServerModule = class {
3947
+ client;
3948
+ constructor(config) {
3949
+ this.client = config.client;
3950
+ }
3951
+ /**
3952
+ * Get server information including project settings
3953
+ *
3954
+ * @example
3955
+ * ```typescript
3956
+ * const info = await baasix.server.info();
3957
+ * console.log('Project:', info.project?.name);
3958
+ * console.log('Version:', info.version);
3959
+ * ```
3960
+ */
3961
+ async info() {
3962
+ return this.client.get("/");
3963
+ }
3964
+ /**
3965
+ * Check server health
3966
+ *
3849
3967
  * @example
3850
3968
  * ```typescript
3851
- * await baasix.migrations.markAllComplete();
3969
+ * const isHealthy = await baasix.server.health();
3852
3970
  * ```
3853
3971
  */
3854
- async markAllComplete() {
3855
- await this.client.post("/migrations/mark-all-complete", {});
3972
+ async health() {
3973
+ try {
3974
+ await this.client.get("/health");
3975
+ return true;
3976
+ } catch {
3977
+ return false;
3978
+ }
3856
3979
  }
3857
3980
  };
3858
3981
 
@@ -3931,6 +4054,7 @@ var Baasix = class {
3931
4054
  roles;
3932
4055
  users;
3933
4056
  migrations;
4057
+ server;
3934
4058
  // Items module factory cache
3935
4059
  itemsModules = /* @__PURE__ */ new Map();
3936
4060
  constructor(config) {
@@ -3979,6 +4103,7 @@ var Baasix = class {
3979
4103
  this.roles = new RolesModule({ client: this.httpClient });
3980
4104
  this.users = new UsersModule({ client: this.httpClient });
3981
4105
  this.migrations = new MigrationsModule({ client: this.httpClient });
4106
+ this.server = new ServerModule({ client: this.httpClient });
3982
4107
  this.realtime = new RealtimeModule({
3983
4108
  client: this.httpClient,
3984
4109
  storage: this.storage,
@@ -4107,6 +4232,23 @@ var Baasix = class {
4107
4232
  this.httpClient.updateConfig({ tenantId: void 0 });
4108
4233
  await this.storage.remove(STORAGE_KEYS.TENANT);
4109
4234
  }
4235
+ /**
4236
+ * Set a static token (convenience method that delegates to auth.setToken)
4237
+ *
4238
+ * @example
4239
+ * ```typescript
4240
+ * baasix.setToken('your-api-token');
4241
+ * ```
4242
+ */
4243
+ async setToken(token) {
4244
+ return this.auth.setToken(token);
4245
+ }
4246
+ /**
4247
+ * Get the current auth token
4248
+ */
4249
+ async getToken() {
4250
+ return this.storage.get(STORAGE_KEYS.ACCESS_TOKEN);
4251
+ }
4110
4252
  /**
4111
4253
  * Get the base URL
4112
4254
  */