appbuild-oceanbase-console 1.11.1 → 1.12.1

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/cjs/sdk.js CHANGED
@@ -434,9 +434,9 @@ Query.notTouches = (attribute, values) => new Query("notTouches", attribute, [va
434
434
  /**
435
435
  * Environment detection helpers
436
436
  */
437
- const isBrowser = typeof window !== 'undefined';
437
+ const isBrowser$1 = typeof window !== 'undefined';
438
438
  // Memory storage for server-side environment
439
- class MemoryStorage {
439
+ class MemoryStorage$1 {
440
440
  constructor() {
441
441
  this.data = new Map();
442
442
  }
@@ -450,9 +450,9 @@ class MemoryStorage {
450
450
  this.data.delete(key);
451
451
  }
452
452
  }
453
- const memoryStorage = new MemoryStorage();
454
- const getStorage = () => isBrowser ? window.localStorage : memoryStorage;
455
- const getLocation = () => isBrowser ? window.location : { host: 'nodejs' };
453
+ const memoryStorage$1 = new MemoryStorage$1();
454
+ const getStorage$1 = () => isBrowser$1 ? window.localStorage : memoryStorage$1;
455
+ const getLocation = () => isBrowser$1 ? window.location : { host: 'nodejs' };
456
456
  const getWebSocket = () => {
457
457
  if (typeof WebSocket !== 'undefined')
458
458
  return WebSocket;
@@ -619,7 +619,7 @@ class Client {
619
619
  case 'connected':
620
620
  let session = this.config.session;
621
621
  if (!session) {
622
- const storage = getStorage();
622
+ const storage = getStorage$1();
623
623
  const cookieFallback = storage.getItem('cookieFallback');
624
624
  if (cookieFallback) {
625
625
  const cookie = JSON.parse(cookieFallback);
@@ -772,6 +772,19 @@ class Client {
772
772
  this.config.mode = value;
773
773
  return this;
774
774
  }
775
+ /**
776
+ * Set Session Refresh Handler
777
+ *
778
+ * Set a callback function that will be called when a 401 error is detected.
779
+ * This allows automatic re-login when session expires.
780
+ *
781
+ * @param handler Function that returns a Promise to refresh the session
782
+ * @returns {this}
783
+ */
784
+ setSessionRefreshHandler(handler) {
785
+ this.sessionRefreshHandler = handler;
786
+ return this;
787
+ }
775
788
  /**
776
789
  * Subscribes to Appwrite events and passes you the payload in realtime.
777
790
  *
@@ -818,7 +831,7 @@ class Client {
818
831
  prepareRequest(method, url, headers = {}, params = {}) {
819
832
  method = method.toUpperCase();
820
833
  headers = Object.assign({}, this.headers, headers);
821
- const storage = getStorage();
834
+ const storage = getStorage$1();
822
835
  const cookieFallback = storage.getItem('cookieFallback');
823
836
  if (cookieFallback) {
824
837
  headers['X-Fallback-Cookies'] = cookieFallback;
@@ -906,7 +919,7 @@ class Client {
906
919
  return this.call('GET', new URL(this.config.endpoint + '/ping'));
907
920
  });
908
921
  }
909
- call(method, url, headers = {}, params = {}, responseType = 'json') {
922
+ call(method, url, headers = {}, params = {}, responseType = 'json', retryOn401 = true) {
910
923
  var _a, _b;
911
924
  return __awaiter(this, void 0, void 0, function* () {
912
925
  const { uri, options } = this.prepareRequest(method, url, headers, params);
@@ -950,6 +963,17 @@ class Client {
950
963
  };
951
964
  }
952
965
  if (400 <= response.status) {
966
+ // Handle 401 Unauthorized with automatic re-login
967
+ if (response.status === 401 && retryOn401 && this.sessionRefreshHandler) {
968
+ try {
969
+ yield this.sessionRefreshHandler();
970
+ // Retry the request once after re-login
971
+ return this.call(method, url, headers, params, responseType, false);
972
+ }
973
+ catch (refreshError) {
974
+ // If refresh fails, throw the original 401 error
975
+ }
976
+ }
953
977
  let responseText = '';
954
978
  if (((_b = response.headers.get('content-type')) === null || _b === void 0 ? void 0 : _b.includes('application/json')) || responseType === 'arrayBuffer') {
955
979
  responseText = JSON.stringify(data);
@@ -961,9 +985,9 @@ class Client {
961
985
  }
962
986
  const cookieFallback = response.headers.get('X-Fallback-Cookies');
963
987
  if (cookieFallback) {
964
- const storage = getStorage();
988
+ const storage = getStorage$1();
965
989
  storage.setItem('cookieFallback', cookieFallback);
966
- if (isBrowser) {
990
+ if (isBrowser$1) {
967
991
  console.warn('Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.');
968
992
  }
969
993
  }
@@ -13943,6 +13967,26 @@ class Role {
13943
13967
  }
13944
13968
  }
13945
13969
 
13970
+ /**
13971
+ * Exception thrown when migration execution fails
13972
+ * Contains information about all failed operations
13973
+ */
13974
+ class MigrationExecutionException extends Error {
13975
+ constructor(failedOperations, totalOperations) {
13976
+ const failedCount = failedOperations.length;
13977
+ const succeededCount = totalOperations - failedCount;
13978
+ const errorMessages = failedOperations.map(fo => ` - ${fo.operation.type} for collection ${fo.operation.collectionId}: ${fo.errorMessage}`).join('\n');
13979
+ const message = `Migration execution completed with ${failedCount} failure(s) out of ${totalOperations} operation(s).\n` +
13980
+ `Succeeded: ${succeededCount}, Failed: ${failedCount}\n\n` +
13981
+ `Failed operations:\n${errorMessages}`;
13982
+ super(message);
13983
+ this.name = 'MigrationExecutionException';
13984
+ this.failedOperations = failedOperations;
13985
+ this.totalOperations = totalOperations;
13986
+ this.succeededOperations = succeededCount;
13987
+ this.failedOperationsCount = failedCount;
13988
+ }
13989
+ }
13946
13990
  /**
13947
13991
  * Database Schema Migration Tool
13948
13992
  *
@@ -14004,26 +14048,29 @@ class SchemaMigration {
14004
14048
  this._currentSchema = schema;
14005
14049
  const operations = [];
14006
14050
  const skippedBuiltIns = [];
14007
- // If databaseId is empty, create a database with id "default"
14051
+ // Auto-create database if it doesn't exist
14052
+ // If databaseId is empty, use "default" as the database id
14008
14053
  let databaseId = schema.databaseId;
14009
14054
  if (!databaseId || databaseId.trim() === '') {
14010
14055
  databaseId = 'default';
14011
- try {
14012
- yield this.databases.create({
14013
- databaseId: databaseId,
14014
- name: 'default',
14015
- enabled: true
14016
- });
14017
- }
14018
- catch (error) {
14019
- // If database already exists, that's fine
14020
- if (!(error instanceof AppwriteException && error.code === 409)) {
14021
- throw error;
14022
- }
14056
+ }
14057
+ // Try to create the database if it doesn't exist
14058
+ // If it already exists (409 error), that's fine - continue execution
14059
+ try {
14060
+ yield this.databases.create({
14061
+ databaseId: databaseId,
14062
+ name: databaseId,
14063
+ enabled: true
14064
+ });
14065
+ }
14066
+ catch (error) {
14067
+ // If database already exists, that's fine
14068
+ if (!(error instanceof AppwriteException && error.code === 409)) {
14069
+ throw error;
14023
14070
  }
14024
- // Update schema.databaseId for later use
14025
- schema.databaseId = databaseId;
14026
14071
  }
14072
+ // Update schema.databaseId for later use
14073
+ schema.databaseId = databaseId;
14027
14074
  // Get current tables
14028
14075
  const currentTables = yield this.databases.listTables({
14029
14076
  databaseId: databaseId,
@@ -14434,18 +14481,37 @@ class SchemaMigration {
14434
14481
  }
14435
14482
  // Store schema for use in executeOperation
14436
14483
  this._currentSchema = schema;
14437
- // Execute operations in order
14484
+ // Execute operations in order and collect all failures
14485
+ const failedOperations = [];
14438
14486
  for (const operation of plan.operations) {
14439
14487
  try {
14440
14488
  yield this.executeOperation(operation);
14441
14489
  }
14442
14490
  catch (error) {
14443
14491
  if (error instanceof AppwriteException) {
14444
- throw new Error(`Failed to execute ${operation.type} for collection ${operation.collectionId}: ${error.message}`);
14492
+ // Collect the error instead of throwing immediately
14493
+ const errorMessage = `Failed to execute ${operation.type} for collection ${operation.collectionId}: ${error.message}`;
14494
+ failedOperations.push({
14495
+ operation,
14496
+ error,
14497
+ errorMessage
14498
+ });
14499
+ }
14500
+ else {
14501
+ // For non-AppwriteException errors, still collect but mark as unexpected
14502
+ const errorMessage = error instanceof Error ? error.message : String(error);
14503
+ failedOperations.push({
14504
+ operation,
14505
+ error: new AppwriteException(`Unexpected error: ${errorMessage}`, 500, 'unexpected_error', JSON.stringify(error)),
14506
+ errorMessage: `Unexpected error during ${operation.type} for collection ${operation.collectionId}: ${errorMessage}`
14507
+ });
14445
14508
  }
14446
- throw error;
14447
14509
  }
14448
14510
  }
14511
+ // If there were any failures, throw an exception with all failure details
14512
+ if (failedOperations.length > 0) {
14513
+ throw new MigrationExecutionException(failedOperations, plan.operations.length);
14514
+ }
14449
14515
  });
14450
14516
  }
14451
14517
  /**
@@ -25625,6 +25691,27 @@ class Vcs {
25625
25691
  }
25626
25692
  }
25627
25693
 
25694
+ /**
25695
+ * Environment detection helper
25696
+ */
25697
+ const isBrowser = typeof window !== 'undefined';
25698
+ // Memory storage for server-side environment
25699
+ class MemoryStorage {
25700
+ constructor() {
25701
+ this.data = new Map();
25702
+ }
25703
+ getItem(key) {
25704
+ return this.data.get(key) || null;
25705
+ }
25706
+ setItem(key, value) {
25707
+ this.data.set(key, value);
25708
+ }
25709
+ removeItem(key) {
25710
+ this.data.delete(key);
25711
+ }
25712
+ }
25713
+ const memoryStorage = new MemoryStorage();
25714
+ const getStorage = () => isBrowser ? window.localStorage : memoryStorage;
25628
25715
  var RealtimeCode;
25629
25716
  (function (RealtimeCode) {
25630
25717
  RealtimeCode[RealtimeCode["NORMAL_CLOSURE"] = 1000] = "NORMAL_CLOSURE";
@@ -25866,7 +25953,7 @@ class Realtime {
25866
25953
  }
25867
25954
  }
25868
25955
  handleResponseConnected(message) {
25869
- var _a, _b;
25956
+ var _a;
25870
25957
  if (!message.data) {
25871
25958
  return;
25872
25959
  }
@@ -25874,15 +25961,19 @@ class Realtime {
25874
25961
  let session = this.client.config.session;
25875
25962
  if (!session) {
25876
25963
  try {
25877
- const cookie = JSON.parse((_a = window.localStorage.getItem('cookieFallback')) !== null && _a !== void 0 ? _a : '{}');
25878
- session = cookie === null || cookie === void 0 ? void 0 : cookie[`a_session_${this.client.config.project}`];
25964
+ const storage = getStorage();
25965
+ const cookieFallback = storage.getItem('cookieFallback');
25966
+ if (cookieFallback) {
25967
+ const cookie = JSON.parse(cookieFallback);
25968
+ session = cookie === null || cookie === void 0 ? void 0 : cookie[`a_session_${this.client.config.project}`];
25969
+ }
25879
25970
  }
25880
25971
  catch (error) {
25881
25972
  console.error('Failed to parse cookie fallback:', error);
25882
25973
  }
25883
25974
  }
25884
25975
  if (session && !messageData.user) {
25885
- (_b = this.socket) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify({
25976
+ (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
25886
25977
  type: 'authentication',
25887
25978
  data: {
25888
25979
  session
@@ -27877,6 +27968,7 @@ exports.Health = Health;
27877
27968
  exports.ID = ID;
27878
27969
  exports.Locale = Locale;
27879
27970
  exports.Messaging = Messaging;
27971
+ exports.MigrationExecutionException = MigrationExecutionException;
27880
27972
  exports.Migrations = Migrations;
27881
27973
  exports.Operator = Operator;
27882
27974
  exports.Organizations = Organizations;