@symbo.ls/sdk 3.1.1 → 3.1.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.
Files changed (55) hide show
  1. package/README.md +172 -11
  2. package/dist/cjs/config/environment.js +39 -33
  3. package/dist/cjs/index.js +35 -8
  4. package/dist/cjs/services/AuthService.js +44 -3
  5. package/dist/cjs/services/BasedService.js +530 -24
  6. package/dist/cjs/services/CoreService.js +1751 -0
  7. package/dist/cjs/services/SocketIOService.js +34 -36
  8. package/dist/cjs/services/SymstoryService.js +135 -49
  9. package/dist/cjs/services/index.js +4 -4
  10. package/dist/cjs/utils/TokenManager.js +374 -0
  11. package/dist/cjs/utils/basedQuerys.js +120 -0
  12. package/dist/cjs/utils/permission.js +4 -4
  13. package/dist/cjs/utils/services.js +32 -9
  14. package/dist/cjs/utils/symstoryClient.js +32 -1
  15. package/dist/esm/config/environment.js +39 -33
  16. package/dist/esm/index.js +8964 -11076
  17. package/dist/esm/services/AuthService.js +48 -7
  18. package/dist/esm/services/BasedService.js +683 -56
  19. package/dist/esm/services/CoreService.js +2264 -0
  20. package/dist/esm/services/SocketIOService.js +71 -68
  21. package/dist/esm/services/SymstoryService.js +293 -101
  22. package/dist/esm/services/index.js +8905 -11066
  23. package/dist/esm/utils/TokenManager.js +360 -0
  24. package/dist/esm/utils/basedQuerys.js +120 -0
  25. package/dist/esm/utils/permission.js +4 -4
  26. package/dist/esm/utils/services.js +32 -9
  27. package/dist/esm/utils/symstoryClient.js +69 -33
  28. package/dist/esm/utils/validation.js +89 -19
  29. package/dist/node/config/environment.js +39 -33
  30. package/dist/node/index.js +43 -10
  31. package/dist/node/services/AuthService.js +44 -3
  32. package/dist/node/services/BasedService.js +531 -25
  33. package/dist/node/services/CoreService.js +1722 -0
  34. package/dist/node/services/SocketIOService.js +34 -36
  35. package/dist/node/services/SymstoryService.js +135 -49
  36. package/dist/node/services/index.js +4 -4
  37. package/dist/node/utils/TokenManager.js +355 -0
  38. package/dist/node/utils/basedQuerys.js +120 -0
  39. package/dist/node/utils/permission.js +4 -4
  40. package/dist/node/utils/services.js +32 -9
  41. package/dist/node/utils/symstoryClient.js +32 -1
  42. package/package.json +16 -13
  43. package/src/config/environment.js +40 -35
  44. package/src/index.js +49 -10
  45. package/src/services/AuthService.js +52 -3
  46. package/src/services/BasedService.js +602 -23
  47. package/src/services/CoreService.js +1943 -0
  48. package/src/services/SocketIOService.js +49 -71
  49. package/src/services/SymstoryService.js +150 -64
  50. package/src/services/index.js +4 -4
  51. package/src/utils/TokenManager.js +424 -0
  52. package/src/utils/basedQuerys.js +123 -0
  53. package/src/utils/permission.js +4 -4
  54. package/src/utils/services.js +32 -9
  55. package/src/utils/symstoryClient.js +35 -1
@@ -90,6 +90,122 @@ var buildUserQuery = (userId) => ({
90
90
  $all: true
91
91
  }
92
92
  });
93
+ var buildGetUserDataQuery = (userId) => ({
94
+ $id: userId,
95
+ id: true,
96
+ name: true,
97
+ email: true,
98
+ username: true,
99
+ globalRole: true,
100
+ updatedAt: true,
101
+ createdAt: true,
102
+ memberProjects: {
103
+ $list: true,
104
+ id: true,
105
+ role: true,
106
+ createdAt: true,
107
+ updatedAt: true,
108
+ project: {
109
+ id: true,
110
+ key: true,
111
+ name: true,
112
+ thumbnail: true,
113
+ icon: true,
114
+ tier: true,
115
+ visibility: true,
116
+ access: true,
117
+ members: {
118
+ $list: true,
119
+ user: {
120
+ id: true,
121
+ name: true,
122
+ email: true,
123
+ globalRole: true
124
+ },
125
+ role: true,
126
+ updatedAt: true,
127
+ createdAt: true
128
+ }
129
+ }
130
+ }
131
+ });
132
+ var buildGetProjectsByKeysQuery = (keys) => ({
133
+ projects: {
134
+ id: true,
135
+ key: true,
136
+ name: true,
137
+ thumbnail: true,
138
+ icon: true,
139
+ tier: true,
140
+ visibility: true,
141
+ access: true,
142
+ members: {
143
+ $list: true,
144
+ user: {
145
+ id: true,
146
+ name: true,
147
+ email: true,
148
+ globalRole: true
149
+ },
150
+ role: true,
151
+ updatedAt: true,
152
+ createdAt: true
153
+ },
154
+ $list: {
155
+ $find: {
156
+ $traverse: "children",
157
+ $filter: [
158
+ { $field: "type", $operator: "=", $value: "project" },
159
+ { $field: "key", $operator: "=", $value: keys }
160
+ ]
161
+ }
162
+ }
163
+ }
164
+ });
165
+ var GetProjectFields = {
166
+ id: true,
167
+ name: true,
168
+ key: true,
169
+ tier: true,
170
+ projectType: true,
171
+ icon: true,
172
+ package: true,
173
+ seats: true,
174
+ projectPassword: true,
175
+ stripe: true,
176
+ payments: {
177
+ $list: true,
178
+ id: true,
179
+ name: true
180
+ },
181
+ access: true,
182
+ isSharedLibrary: true,
183
+ framework: true,
184
+ designTool: true,
185
+ language: true,
186
+ visibility: true,
187
+ domains: true,
188
+ subscription: { id: true },
189
+ members: {
190
+ $list: true,
191
+ user: { id: true, name: true, email: true },
192
+ role: true
193
+ }
194
+ };
195
+ var buildGetProjectDataQuery = (projectId) => ({
196
+ $id: projectId,
197
+ ...GetProjectFields
198
+ });
199
+ var buildGetProjectByKeyDataQuery = (key) => ({
200
+ ...GetProjectFields,
201
+ $find: {
202
+ $traverse: "children",
203
+ $filter: [
204
+ { $field: "type", $operator: "=", $value: "project" },
205
+ { $field: "key", $operator: "=", $value: key }
206
+ ]
207
+ }
208
+ });
93
209
 
94
210
  // ../../../node_modules/@based/client/dist/src/websocket/urlLoader.js
95
211
  var urlLoader_default = (url, cb) => {
@@ -3869,6 +3985,7 @@ function based(opts, settings) {
3869
3985
  import { isFunction, isString } from "@domql/utils";
3870
3986
 
3871
3987
  // src/config/environment.js
3988
+ import { isDevelopment } from "@domql/utils";
3872
3989
  var CONFIG = {
3873
3990
  // Common defaults for all environments
3874
3991
  common: {
@@ -3882,17 +3999,18 @@ var CONFIG = {
3882
3999
  },
3883
4000
  // Environment-specific configurations
3884
4001
  local: {
3885
- baseUrl: "http://localhost:3000",
4002
+ // local
4003
+ baseUrl: "http://localhost:8080",
3886
4004
  // For symstory api
3887
4005
  socketUrl: "http://localhost:8080",
3888
4006
  // For socket api
3889
- routerUrl: "http://localhost:3090",
4007
+ routerUrl: "http://localhost:8080",
3890
4008
  // For router api
3891
- apiUrl: "http://localhost:13335",
4009
+ apiUrl: "http://localhost:8080",
3892
4010
  // For server api
3893
4011
  basedEnv: "development",
3894
4012
  // For based api
3895
- basedProject: "platform-v2",
4013
+ basedProject: "platform-v2-sm",
3896
4014
  // For based api
3897
4015
  basedOrg: "symbols",
3898
4016
  // For based api
@@ -3905,41 +4023,50 @@ var CONFIG = {
3905
4023
  }
3906
4024
  },
3907
4025
  development: {
3908
- baseUrl: "https://story.symbo.ls",
3909
- socketUrl: "https://socket.symbols.app",
3910
- routerUrl: "https://router.symbols.app",
3911
- apiUrl: "https://api.symbols.app",
4026
+ baseUrl: "https://dev.api.symbols.app",
4027
+ socketUrl: "https://dev.api.symbols.app",
4028
+ routerUrl: "https://dev.api.symbols.app",
4029
+ apiUrl: "https://dev.api.symbols.app",
3912
4030
  basedEnv: "development",
3913
- basedProject: "platform-v2",
4031
+ basedProject: "platform-v2-sm",
4032
+ basedOrg: "symbols",
4033
+ githubClientId: "Ov23liHxyWFBxS8f1gnF"
4034
+ },
4035
+ testing: {
4036
+ baseUrl: "https://test.api.symbols.app",
4037
+ socketUrl: "https://test.api.symbols.app",
4038
+ routerUrl: "https://test.api.symbols.app",
4039
+ apiUrl: "https://test.api.symbols.app",
4040
+ basedEnv: "testing",
4041
+ basedProject: "platform-v2-sm",
3914
4042
  basedOrg: "symbols",
3915
4043
  githubClientId: "Ov23liHxyWFBxS8f1gnF"
3916
4044
  },
3917
4045
  staging: {
3918
- baseUrl: "https://staging.story.symbo.ls",
3919
- socketUrl: "https://staging.socket.symbols.app",
3920
- routerUrl: "https://staging.router.symbols.app",
4046
+ baseUrl: "https://staging.api.symbols.app",
4047
+ socketUrl: "https://staging.api.symbols.app",
4048
+ routerUrl: "https://staging.api.symbols.app",
3921
4049
  apiUrl: "https://staging.api.symbols.app",
3922
4050
  basedEnv: "staging",
3923
- basedProject: "platform-v2",
4051
+ basedProject: "platform-v2-sm",
3924
4052
  basedOrg: "symbols",
3925
4053
  githubClientId: "Ov23ligwZDQVD0VfuWNa"
3926
4054
  },
3927
4055
  production: {
3928
- baseUrl: "https://story.symbo.ls",
3929
- socketUrl: "https://socket.symbols.app",
3930
- routerUrl: "https://router.symbols.app",
4056
+ baseUrl: "https://api.symbols.app",
4057
+ socketUrl: "https://api.symbols.app",
4058
+ routerUrl: "https://api.symbols.app",
3931
4059
  apiUrl: "https://api.symbols.app",
3932
4060
  basedEnv: "production",
3933
- basedProject: "platform-v2",
4061
+ basedProject: "platform-v2-sm",
3934
4062
  basedOrg: "symbols",
3935
4063
  githubClientId: "Ov23liFAlOEIXtX3dBtR"
3936
4064
  }
3937
4065
  };
3938
4066
  var getEnvironment = () => {
3939
- const env2 = process.env.SYMBOLS_APP_ENV || "" || "development";
4067
+ const env2 = process.env.SYMBOLS_APP_ENV || process.env.NODE_ENV;
3940
4068
  if (!CONFIG[env2]) {
3941
- console.warn(`Unknown environment "${env2}", falling back to development`);
3942
- return "development";
4069
+ throw new Error(`Unknown environment "${env2}"`);
3943
4070
  }
3944
4071
  return env2;
3945
4072
  };
@@ -3957,9 +4084,11 @@ var getConfig = () => {
3957
4084
  basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
3958
4085
  basedOrg: process.env.SYMBOLS_APP_BASED_ORG || envConfig.basedOrg,
3959
4086
  githubClientId: process.env.SYMBOLS_APP_GITHUB_CLIENT_ID || envConfig.githubClientId,
3960
- isDevelopment: env2 === "development" || env2 === "local",
4087
+ isDevelopment: isDevelopment(env2),
4088
+ isTesting: env2 === "testing",
3961
4089
  isStaging: env2 === "staging",
3962
4090
  isProduction: env2 === "production"
4091
+ // Store all environment variables for potential future use
3963
4092
  };
3964
4093
  const requiredFields = [
3965
4094
  "baseUrl",
@@ -3980,9 +4109,7 @@ var getConfig = () => {
3980
4109
  if (finalConfig.isDevelopment) {
3981
4110
  console.log(
3982
4111
  "environment in SDK:",
3983
- env2,
3984
- "",
3985
- process.env.SYMBOLS_APP_ENV
4112
+ env2 || process.env.NODE_ENV || process.env.NODE_ENV
3986
4113
  );
3987
4114
  console.log(finalConfig);
3988
4115
  }
@@ -3990,14 +4117,7 @@ var getConfig = () => {
3990
4117
  } catch (error) {
3991
4118
  console.error("Failed to load environment configuration:", error);
3992
4119
  return {
3993
- baseUrl: "https://story.symbo.ls",
3994
- socketUrl: "https://socket.symbols.app",
3995
- routerUrl: "https://router.symbols.app",
3996
- apiUrl: "https://api.symbols.app",
3997
- basedEnv: "development",
3998
- basedProject: "platform-v2",
3999
- basedOrg: "symbols",
4000
- githubClientId: "Ov23liHxyWFBxS8f1gnF"
4120
+ ...CONFIG.development
4001
4121
  };
4002
4122
  }
4003
4123
  };
@@ -4106,7 +4226,7 @@ var BasedService = class extends BaseService {
4106
4226
  role: obj.role,
4107
4227
  joinedAt: Date.now()
4108
4228
  });
4109
- await Promise.all([
4229
+ return await Promise.all([
4110
4230
  this._client.call("db:set", {
4111
4231
  $id: userId,
4112
4232
  memberProjects: { $add: membershipId }
@@ -4116,7 +4236,6 @@ var BasedService = class extends BaseService {
4116
4236
  members: { $add: membershipId }
4117
4237
  })
4118
4238
  ]);
4119
- return await this._client.call("db:set", obj);
4120
4239
  } catch (error) {
4121
4240
  throw new Error(`Failed to set bucket: ${error.message}`);
4122
4241
  }
@@ -4154,6 +4273,7 @@ var BasedService = class extends BaseService {
4154
4273
  throw new Error(`Query failed: ${error.message}`);
4155
4274
  }
4156
4275
  }
4276
+ // DEPRECATED
4157
4277
  async fetchUser(userId) {
4158
4278
  if (!userId) {
4159
4279
  throw new Error("User Id is required");
@@ -4161,15 +4281,113 @@ var BasedService = class extends BaseService {
4161
4281
  return await this.query("db", buildUserQuery(userId));
4162
4282
  }
4163
4283
  async getUser(userId) {
4164
- this._requireReady();
4165
4284
  if (!userId) {
4166
- throw new Error("User Id is required");
4167
- }
4168
- try {
4169
- return await this.call("users:get", { userId });
4170
- } catch (error) {
4171
- throw new Error(`Failed to get user: ${error.message}`);
4172
- }
4285
+ throw new Error("UserId is required");
4286
+ }
4287
+ const userData = await this._client.query("db", buildGetUserDataQuery(userId)).get();
4288
+ const user = {
4289
+ id: userData.id,
4290
+ name: userData.name,
4291
+ email: userData.email,
4292
+ username: userData.username,
4293
+ globalRole: userData.globalRole,
4294
+ createdAt: userData.createdAt,
4295
+ updatedAt: userData.updatedAt
4296
+ };
4297
+ if (!user) {
4298
+ throw new Error("User not found");
4299
+ }
4300
+ let memberProjects = [];
4301
+ if (userData.memberProjects && userData.memberProjects.length > 0) {
4302
+ const projectKeys = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => membership.project.key);
4303
+ if (projectKeys.length > 0) {
4304
+ const allProjects = await this._fetchProjectsByKeysInChunks(projectKeys);
4305
+ memberProjects = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => {
4306
+ const projectKey = membership.project.key;
4307
+ const correctProject = allProjects.find(
4308
+ (p) => p.key === projectKey
4309
+ );
4310
+ return {
4311
+ project: correctProject || membership.project,
4312
+ role: membership.role,
4313
+ updatedAt: membership.updatedAt,
4314
+ createdAt: membership.createdAt
4315
+ };
4316
+ });
4317
+ }
4318
+ } else {
4319
+ console.log(`[getUser] No member projects found with ID: ${userId}`);
4320
+ }
4321
+ const formattedProjects = memberProjects.filter((membership) => membership.project).map((membership) => ({
4322
+ id: membership.project.id,
4323
+ name: membership.project.name,
4324
+ key: membership.project.key,
4325
+ thumbnail: membership.project.thumbnail,
4326
+ icon: membership.project.icon,
4327
+ tier: membership.project.tier,
4328
+ visibility: membership.project.visibility,
4329
+ access: membership.project.access,
4330
+ role: membership.role,
4331
+ joinedAt: membership.createdAt,
4332
+ updatedAt: membership.updatedAt,
4333
+ members: membership.project.members
4334
+ })) || [];
4335
+ return {
4336
+ id: userId,
4337
+ name: user.name,
4338
+ email: user.email,
4339
+ username: user.username,
4340
+ globalRole: user.globalRole,
4341
+ projects: formattedProjects,
4342
+ createdAt: user.createdAt,
4343
+ updatedAt: user.updatedAt
4344
+ };
4345
+ }
4346
+ /**
4347
+ * Fetches projects by keys in chunks with adaptive chunk sizing
4348
+ * @param {Array<string>} allKeys - All project keys to fetch
4349
+ * @returns {Promise<Array>} - All projects found
4350
+ */
4351
+ async _fetchProjectsByKeysInChunks(allKeys) {
4352
+ if (!allKeys.length) {
4353
+ return [];
4354
+ }
4355
+ const INITIAL_CHUNK_SIZE = 50;
4356
+ const MAX_CHUNK_SIZE = 1e3;
4357
+ const MIN_CHUNK_SIZE = 10;
4358
+ const optimalChunkSize = INITIAL_CHUNK_SIZE;
4359
+ const processChunks = async (keys, size) => {
4360
+ if (!keys.length) {
4361
+ return [];
4362
+ }
4363
+ const chunks = [];
4364
+ for (let i2 = 0; i2 < keys.length; i2 += size) {
4365
+ chunks.push(keys.slice(i2, i2 + size));
4366
+ }
4367
+ try {
4368
+ const result = await this._client.query("db", buildGetProjectsByKeysQuery(chunks[0])).get();
4369
+ const newSize = Math.min(Math.floor(size * 1.5), MAX_CHUNK_SIZE);
4370
+ const firstChunkProjects = result.projects || [];
4371
+ const remainingKeys = keys.slice(chunks[0].length);
4372
+ const remainingProjects = await processChunks(remainingKeys, newSize);
4373
+ return [...firstChunkProjects, ...remainingProjects];
4374
+ } catch (error) {
4375
+ if (error.message && error.message.includes("PayloadTooLarge")) {
4376
+ const newSize = Math.max(Math.floor(size / 2), MIN_CHUNK_SIZE);
4377
+ console.warn(`Reducing chunk size to ${newSize} due to PayloadTooLarge error`);
4378
+ if (newSize === MIN_CHUNK_SIZE && chunks[0].length <= MIN_CHUNK_SIZE) {
4379
+ console.error(`Cannot process chunk, skipping ${chunks[0].length} keys`);
4380
+ const remainingKeys2 = keys.slice(chunks[0].length);
4381
+ return processChunks(remainingKeys2, newSize);
4382
+ }
4383
+ return processChunks(keys, newSize);
4384
+ }
4385
+ console.error(`Error fetching projects: ${error.message}`);
4386
+ const remainingKeys = keys.slice(chunks[0].length);
4387
+ return processChunks(remainingKeys, size);
4388
+ }
4389
+ };
4390
+ return await processChunks(allKeys, optimalChunkSize);
4173
4391
  }
4174
4392
  async getUserByEmail(email) {
4175
4393
  this._requireReady();
@@ -4331,31 +4549,26 @@ var BasedService = class extends BaseService {
4331
4549
  throw new Error(`Failed to create project: ${error.message}`);
4332
4550
  }
4333
4551
  }
4334
- async getProject(projectId, fields = { $all: true }) {
4552
+ async getProject(projectId) {
4335
4553
  this._requireReady();
4336
4554
  if (!projectId) {
4337
4555
  throw new Error("Project ID is required");
4338
4556
  }
4339
4557
  try {
4340
- return await this.call("projects:get", {
4341
- projectId,
4342
- fields: { ...fields }
4343
- });
4558
+ return await this._client.query("db", buildGetProjectDataQuery(projectId)).get();
4344
4559
  } catch (error) {
4345
4560
  throw new Error(`Failed to get project: ${error.message}`);
4346
4561
  }
4347
4562
  }
4348
- async getProjectByKey(key, fields = { $all: true }) {
4563
+ async getProjectByKey(key) {
4349
4564
  this._requireReady();
4350
4565
  try {
4351
- return await this.call("projects:get", {
4352
- key,
4353
- fields: { ...fields }
4354
- });
4566
+ return await this._client.query("db", buildGetProjectByKeyDataQuery(key)).get();
4355
4567
  } catch (error) {
4356
4568
  throw new Error(`Failed to get project by key: ${error.message}`);
4357
4569
  }
4358
4570
  }
4571
+ // DEPRECATED
4359
4572
  async fetchProject(projectId) {
4360
4573
  this._requireReady();
4361
4574
  if (!projectId) {
@@ -4436,7 +4649,9 @@ var BasedService = class extends BaseService {
4436
4649
  pkg = 2,
4437
4650
  seats = 1,
4438
4651
  interval = "monthly",
4439
- plan = "startup"
4652
+ plan = "startup",
4653
+ successUrl = `${window.location.origin}/success`,
4654
+ cancelUrl = `${window.location.origin}/pricing`
4440
4655
  }) {
4441
4656
  this._requireReady();
4442
4657
  const prices = {
@@ -4458,7 +4673,9 @@ var BasedService = class extends BaseService {
4458
4673
  return await this.call("checkout", {
4459
4674
  price,
4460
4675
  seats,
4461
- projectId
4676
+ projectId,
4677
+ successUrl,
4678
+ cancelUrl
4462
4679
  });
4463
4680
  } catch (error) {
4464
4681
  throw new Error(`Failed to checkout: ${error.message}`);
@@ -4633,19 +4850,429 @@ var BasedService = class extends BaseService {
4633
4850
  * @param {string} newKey - The new key of the project (optional)
4634
4851
  * @returns {Promise<Object>} The duplicated project
4635
4852
  */
4636
- async duplicateProject(projectId, newName, newKey) {
4853
+ async duplicateProject(projectId, newName, newKey, targetUserId) {
4637
4854
  this._requireReady();
4638
4855
  try {
4639
4856
  return await this.call("projects:duplicate", {
4640
4857
  projectId,
4641
4858
  newName,
4642
- newKey
4859
+ newKey,
4860
+ targetUserId
4643
4861
  });
4644
4862
  } catch (error) {
4645
4863
  throw new Error(`Failed to duplicate project: ${error.message}`);
4646
4864
  }
4647
4865
  }
4866
+ /**
4867
+ * List available subscription plans
4868
+ * @param {Object} options - Options for filtering plans
4869
+ * @param {number} options.page - Page number (default: 1)
4870
+ * @param {number} options.limit - Number of plans per page (default: 20)
4871
+ * @param {string} options.status - Filter plans by status (admin only)
4872
+ * @param {boolean} options.includeSubscriptionCounts - Include subscription counts (admin only)
4873
+ * @param {string} options.sortBy - Field to sort by (default: 'displayOrder')
4874
+ * @param {string} options.sortOrder - Sort order ('asc' or 'desc', default: 'asc')
4875
+ * @returns {Promise<Object>} List of plans with pagination info
4876
+ */
4877
+ async listPlans(options = {}) {
4878
+ this._requireReady();
4879
+ try {
4880
+ return await this.call("plans:list", options);
4881
+ } catch (error) {
4882
+ throw new Error(`Failed to list plans: ${error.message}`);
4883
+ }
4884
+ }
4885
+ /**
4886
+ * Subscribe to a plan
4887
+ * @param {string} planId - ID of the plan to subscribe to
4888
+ * @param {Object} options - Options for the subscription
4889
+ * @param {string} options.paymentMethod - Payment method
4890
+ * @param {Object} options.billingAddress - Billing address
4891
+ * @param {string} options.stripeCustomerId - Stripe customer ID
4892
+ * @param {string} options.stripeSubscriptionId - Stripe subscription ID
4893
+ * @returns {Promise<Object>} Subscription details
4894
+ */
4895
+ async subscribeToPlan(planId, options = {}) {
4896
+ this._requireReady();
4897
+ try {
4898
+ return await this.call("subscriptions:create", { planId, ...options });
4899
+ } catch (error) {
4900
+ throw new Error(`Failed to subscribe to plan: ${error.message}`);
4901
+ }
4902
+ }
4903
+ /**
4904
+ * Get details of user's current subscription
4905
+ * @param {string} subscriptionId - ID of the subscription to get details for
4906
+ * @returns {Promise<Object>} Subscription details
4907
+ */
4908
+ async getSubscriptionDetails(subscriptionId) {
4909
+ this._requireReady();
4910
+ try {
4911
+ return await this.call("subscriptions:details", {
4912
+ subscriptionId
4913
+ });
4914
+ } catch (error) {
4915
+ throw new Error(`Failed to get subscription details: ${error.message}`);
4916
+ }
4917
+ }
4918
+ /**
4919
+ * Check if the current subscription is active
4920
+ * @param {string} subscriptionId - ID of the subscription to check
4921
+ * @returns {Promise<Object>} Subscription status info
4922
+ */
4923
+ async checkSubscriptionStatus(subscriptionId) {
4924
+ this._requireReady();
4925
+ try {
4926
+ return await this.call("subscriptions:check-status", {
4927
+ subscriptionId
4928
+ });
4929
+ } catch (error) {
4930
+ throw new Error(`Failed to check subscription status: ${error.message}`);
4931
+ }
4932
+ }
4933
+ /**
4934
+ * Upgrade the current subscription to a new plan
4935
+ * @param {string} planId - ID of the plan to upgrade to
4936
+ * @param {string} stripeSubscriptionId - ID of the Stripe subscription to upgrade
4937
+ * @returns {Promise<Object>} Updated subscription details
4938
+ */
4939
+ async upgradeSubscription(planId, stripeSubscriptionId) {
4940
+ this._requireReady();
4941
+ try {
4942
+ return await this.call("subscriptions:upgrade", {
4943
+ planId,
4944
+ stripeSubscriptionId
4945
+ });
4946
+ } catch (error) {
4947
+ throw new Error(`Failed to upgrade subscription: ${error.message}`);
4948
+ }
4949
+ }
4950
+ /**
4951
+ * Downgrade the current subscription to a new plan
4952
+ * @param {string} planId - ID of the plan to downgrade to
4953
+ * @param {boolean} applyImmediately - Whether to apply the downgrade immediately
4954
+ * @param {string} stripeSubscriptionId - ID of the Stripe subscription to downgrade
4955
+ * @returns {Promise<Object>} Updated subscription details
4956
+ */
4957
+ async downgradeSubscription(planId, stripeSubscriptionId, applyImmediately = false) {
4958
+ this._requireReady();
4959
+ try {
4960
+ return await this.call("subscriptions:downgrade", {
4961
+ planId,
4962
+ applyImmediately,
4963
+ stripeSubscriptionId
4964
+ });
4965
+ } catch (error) {
4966
+ throw new Error(`Failed to downgrade subscription: ${error.message}`);
4967
+ }
4968
+ }
4969
+ /**
4970
+ * Cancel the current subscription
4971
+ * @param {boolean} cancelImmediately - Whether to cancel immediately or at period end
4972
+ * @param {string} reason - Reason for cancellation
4973
+ * @returns {Promise<Object>} Result of cancellation
4974
+ */
4975
+ async cancelSubscription(cancelImmediately = false, reason = "") {
4976
+ this._requireReady();
4977
+ try {
4978
+ return await this.call("subscriptions:cancel", {
4979
+ cancelImmediately,
4980
+ reason
4981
+ });
4982
+ } catch (error) {
4983
+ throw new Error(`Failed to cancel subscription: ${error.message}`);
4984
+ }
4985
+ }
4986
+ /**
4987
+ * Reactivate a subscription that was scheduled for cancellation
4988
+ * @returns {Promise<Object>} Updated subscription details
4989
+ */
4990
+ async reactivateSubscription(stripeSubscriptionId) {
4991
+ this._requireReady();
4992
+ try {
4993
+ return await this.call("subscriptions:reactivate", {
4994
+ stripeSubscriptionId
4995
+ });
4996
+ } catch (error) {
4997
+ throw new Error(`Failed to reactivate subscription: ${error.message}`);
4998
+ }
4999
+ }
5000
+ /**
5001
+ * Generate an invoice for the current subscription
5002
+ * @param {string} subscriptionId - ID of the subscription to generate the invoice for
5003
+ * @param {boolean} forceGenerate - Whether to force the generation of the invoice
5004
+ * @param {Array} customItems - Custom items to add to the invoice
5005
+ * @returns {Promise<Object>} Generated invoice
5006
+ */
5007
+ async generateInvoice(subscriptionId, forceGenerate = false, customItems = []) {
5008
+ this._requireReady();
5009
+ try {
5010
+ return await this.call("billing:generate-invoice", {
5011
+ subscriptionId,
5012
+ forceGenerate,
5013
+ customItems
5014
+ });
5015
+ } catch (error) {
5016
+ throw new Error(`Failed to generate invoice: ${error.message}`);
5017
+ }
5018
+ }
5019
+ /**
5020
+ * Get usage report for the current subscription
5021
+ * @param {string} subscriptionId - ID of the subscription to get the usage report for
5022
+ * @param {boolean} forceRefresh - Whether to force the refresh of the usage report
5023
+ * @returns {Promise<Object>} Usage report
5024
+ */
5025
+ async getUsageReport(subscriptionId, forceRefresh = false) {
5026
+ this._requireReady();
5027
+ try {
5028
+ return await this.call("subscriptions:get-usage-report", {
5029
+ subscriptionId,
5030
+ forceRefresh
5031
+ });
5032
+ } catch (error) {
5033
+ throw new Error(`Failed to get usage report: ${error.message}`);
5034
+ }
5035
+ }
5036
+ /**
5037
+ * Invite a user to be an account owner for the current subscription
5038
+ * @param {string} email - Email of the user to invite
5039
+ * @param {string} name - Name of the user to invite
5040
+ * @param {string} callbackUrl - URL to redirect the user to after accepting the invitation
5041
+ * @returns {Promise<Object>} Result of invitation
5042
+ */
5043
+ async inviteAccountOwner(email, name, callbackUrl) {
5044
+ this._requireReady();
5045
+ try {
5046
+ return await this.call("subscriptions:invite", {
5047
+ email,
5048
+ name,
5049
+ callbackUrl
5050
+ });
5051
+ } catch (error) {
5052
+ throw new Error(`Failed to invite account owner: ${error.message}`);
5053
+ }
5054
+ }
5055
+ /**
5056
+ * Accept an invitation to become an account owner
5057
+ * @param {string} token - Invitation token
5058
+ * @returns {Promise<Object>} Result of accepting invitation
5059
+ */
5060
+ async acceptOwnerInvitation(token) {
5061
+ this._requireReady();
5062
+ try {
5063
+ return await this.call("subscriptions:accept-owner-invitation", {
5064
+ token
5065
+ });
5066
+ } catch (error) {
5067
+ throw new Error(`Failed to accept owner invitation: ${error.message}`);
5068
+ }
5069
+ }
5070
+ /**
5071
+ * Remove an account owner from the current subscription
5072
+ * @param {string} userId - ID of the user to remove
5073
+ * @returns {Promise<Object>} Result of removal
5074
+ */
5075
+ async removeAccountOwner(userId) {
5076
+ this._requireReady();
5077
+ try {
5078
+ return await this.call("subscriptions:remove-account-owner", {
5079
+ targetUserId: userId
5080
+ });
5081
+ } catch (error) {
5082
+ throw new Error(`Failed to remove account owner: ${error.message}`);
5083
+ }
5084
+ }
5085
+ /**
5086
+ * Check if a resource limit has been reached
5087
+ * @param {string} resourceType - Type of resource to check
5088
+ * @param {string} projectId - ID of the project to check the resource limit for
5089
+ * @param {number} quantity - Amount being requested
5090
+ * @param {string} userId - ID of user to check (admin only, defaults to current user)
5091
+ * @returns {Promise<Object>} Result of check
5092
+ */
5093
+ async checkResourceLimit(resourceType, projectId, quantity = 1, userId = "") {
5094
+ this._requireReady();
5095
+ try {
5096
+ return await this.call("subscriptions:check-resource-limit", {
5097
+ resourceType,
5098
+ projectId,
5099
+ quantity,
5100
+ userId
5101
+ });
5102
+ } catch (error) {
5103
+ throw new Error(`Failed to check resource limit: ${error.message}`);
5104
+ }
5105
+ }
5106
+ /**
5107
+ * Check if a user has access to a feature
5108
+ * @param {string} featureKey - Key of the feature to check
5109
+ * @param {string} userId - ID of user to check (admin only, defaults to current user)
5110
+ * @returns {Promise<Object>} Access check result
5111
+ */
5112
+ async checkFeatureAccess(featureKey, userId) {
5113
+ this._requireReady();
5114
+ try {
5115
+ return await this.call("features:check-access", {
5116
+ featureKey,
5117
+ userId
5118
+ });
5119
+ } catch (error) {
5120
+ throw new Error(`Failed to check feature access: ${error.message}`);
5121
+ }
5122
+ }
5123
+ /**
5124
+ * Get all features available to the current user
5125
+ * @returns {Promise<Object>} Available features
5126
+ */
5127
+ async getUserFeatures() {
5128
+ this._requireReady();
5129
+ try {
5130
+ return await this.call("subscriptions:get-user-features", {});
5131
+ } catch (error) {
5132
+ throw new Error(`Failed to get user features: ${error.message}`);
5133
+ }
5134
+ }
5135
+ /**
5136
+ * Get all available features across all plans
5137
+ * @param {string} subscriptionId - ID of the subscription to get the available features for
5138
+ * @param {string} userId - ID of user to get the available features for (admin only, defaults to current user)
5139
+ * @param {boolean} includeDetails - Whether to include details about the features
5140
+ * @returns {Promise<Object>} Available features
5141
+ */
5142
+ async getAvailableFeatures(subscriptionId, userId = "", includeDetails = false) {
5143
+ this._requireReady();
5144
+ try {
5145
+ return await this.call("features:get-available", {
5146
+ subscriptionId,
5147
+ userId,
5148
+ includeDetails
5149
+ });
5150
+ } catch (error) {
5151
+ throw new Error(`Failed to get available features: ${error.message}`);
5152
+ }
5153
+ }
5154
+ /**
5155
+ * List all feature flags (admin only)
5156
+ * @param {Object} options - Options for listing feature flags
5157
+ * @param {number} options.page - Page number
5158
+ * @param {number} options.limit - Number of items per page
5159
+ * @param {string} options.status - Filter by status
5160
+ * @returns {Promise<Object>} List of feature flags
5161
+ */
5162
+ async listFeatureFlags(options = {}) {
5163
+ this._requireReady();
5164
+ try {
5165
+ return await this.call("features:list", options);
5166
+ } catch (error) {
5167
+ throw new Error(`Failed to list feature flags: ${error.message}`);
5168
+ }
5169
+ }
5170
+ /**
5171
+ * Update a feature flag (admin only)
5172
+ * @param {string} flagId - ID of the feature flag to update
5173
+ * @param {Object} options - Update data
5174
+ * @param {string} options.key - Key of the feature flag
5175
+ * @param {string} options.name - Name of the feature flag
5176
+ * @param {string} options.description - Description of the feature flag
5177
+ * @param {string} options.defaultValue - Default value of the feature flag
5178
+ * @param {Object} options.planOverrides - Plan overrides for the feature flag
5179
+ * @param {Object} options.userOverrides - User overrides for the feature flag
5180
+ * @param {string} options.status - Status of the feature flag
5181
+ * @returns {Promise<Object>} Updated feature flag
5182
+ */
5183
+ async updateFeatureFlag(flagId, options) {
5184
+ this._requireReady();
5185
+ try {
5186
+ return await this.call("features:update", {
5187
+ flagId,
5188
+ ...options
5189
+ });
5190
+ } catch (error) {
5191
+ throw new Error(`Failed to update feature flag: ${error.message}`);
5192
+ }
5193
+ }
5194
+ /**
5195
+ * Remove a feature flag (admin only)
5196
+ * @param {string} flagId - ID of the feature flag to remove
5197
+ * @returns {Promise<Object>} Result of removal
5198
+ */
5199
+ async removeFeatureFlag(flagId) {
5200
+ this._requireReady();
5201
+ try {
5202
+ return await this.call("features:remove", {
5203
+ flagId
5204
+ });
5205
+ } catch (error) {
5206
+ throw new Error(`Failed to remove feature flag: ${error.message}`);
5207
+ }
5208
+ }
5209
+ /**
5210
+ * Batch update feature flags (admin only)
5211
+ * @param {Array} operations - Array of feature flag operations
5212
+ * @param {string} operations.flagId - ID of the feature flag to update
5213
+ * @param {string} operations.key - Key of the feature flag
5214
+ * @param {string} operations.name - Name of the feature flag
5215
+ * @param {string} operations.description - Description of the feature flag
5216
+ * @param {boolean} operations.defaultValue - Default value of the feature flag
5217
+ * @param {Object} operations.planOverrides - Plan overrides for the feature flag
5218
+ * @param {Object} operations.userOverrides - User overrides for the feature flag
5219
+ * @param {string} operations.status - Status of the feature flag
5220
+ * @returns {Promise<Object>} Result of batch update
5221
+ */
5222
+ async batchUpdateFeatureFlags(operations) {
5223
+ this._requireReady();
5224
+ try {
5225
+ return await this.call("features:batch-update", {
5226
+ operations
5227
+ });
5228
+ } catch (error) {
5229
+ throw new Error(`Failed to batch update feature flags: ${error.message}`);
5230
+ }
5231
+ }
5232
+ /**
5233
+ * Update plan details (admin only)
5234
+ * @param {string} planId - ID of the plan to update
5235
+ * @param {Object} data - Update data
5236
+ * @param {string} data.name - Display name (e.g., "Pro", "Team")
5237
+ * @param {string} data.description - Marketing description
5238
+ * @param {number} data.price - Monthly price in cents
5239
+ * @param {number} data.annualPrice - Annual price in cents (discounted)
5240
+ * @param {number} data.lifetimePrice - One-time lifetime price in cents
5241
+ * @param {string} data.billingType - Payment type
5242
+ * @param {string} data.status - Status
5243
+ * @param {Object} data.features - Detailed feature configuration
5244
+ * @returns {Promise<Object>} Updated plan
5245
+ */
5246
+ async updatePlanDetails(planId, data) {
5247
+ this._requireReady();
5248
+ try {
5249
+ return await this.call("plans:update-details", {
5250
+ planId,
5251
+ data
5252
+ });
5253
+ } catch (error) {
5254
+ throw new Error(`Failed to update plan details: ${error.message}`);
5255
+ }
5256
+ }
5257
+ /**
5258
+ * Update plan status (admin only)
5259
+ * @param {string} planId - ID of the plan to update
5260
+ * @param {string} status - New status
5261
+ * @returns {Promise<Object>} Updated plan
5262
+ */
5263
+ async updatePlanStatus(planId, status) {
5264
+ this._requireReady();
5265
+ try {
5266
+ return await this.call("plans:update-status", {
5267
+ planId,
5268
+ status
5269
+ });
5270
+ } catch (error) {
5271
+ throw new Error(`Failed to update plan status: ${error.message}`);
5272
+ }
5273
+ }
4648
5274
  };
4649
5275
  export {
4650
5276
  BasedService
4651
5277
  };
5278
+ // @preserve-env