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