@symbo.ls/sdk 3.1.1 → 3.2.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.
Files changed (83) hide show
  1. package/README.md +174 -13
  2. package/dist/cjs/config/environment.js +32 -42
  3. package/dist/cjs/index.js +31 -24
  4. package/dist/cjs/services/AIService.js +3 -3
  5. package/dist/cjs/services/AuthService.js +44 -3
  6. package/dist/cjs/services/BasedService.js +530 -24
  7. package/dist/cjs/services/CollabService.js +420 -0
  8. package/dist/cjs/services/CoreService.js +2295 -0
  9. package/dist/cjs/services/SocketService.js +207 -59
  10. package/dist/cjs/services/SymstoryService.js +135 -49
  11. package/dist/cjs/services/index.js +8 -16
  12. package/dist/cjs/state/RootStateManager.js +86 -0
  13. package/dist/cjs/state/rootEventBus.js +65 -0
  14. package/dist/cjs/utils/CollabClient.js +157 -0
  15. package/dist/cjs/utils/TokenManager.js +409 -0
  16. package/dist/cjs/utils/basedQuerys.js +120 -0
  17. package/dist/cjs/utils/jsonDiff.js +103 -0
  18. package/dist/cjs/utils/permission.js +4 -4
  19. package/dist/cjs/utils/services.js +133 -69
  20. package/dist/cjs/utils/symstoryClient.js +33 -2
  21. package/dist/esm/config/environment.js +32 -42
  22. package/dist/esm/index.js +20586 -11525
  23. package/dist/esm/services/AIService.js +3 -3
  24. package/dist/esm/services/AuthService.js +48 -7
  25. package/dist/esm/services/BasedService.js +676 -65
  26. package/dist/esm/services/CollabService.js +18028 -0
  27. package/dist/esm/services/CoreService.js +2827 -0
  28. package/dist/esm/services/SocketService.js +323 -58
  29. package/dist/esm/services/SymstoryService.js +287 -111
  30. package/dist/esm/services/index.js +20456 -11470
  31. package/dist/esm/state/RootStateManager.js +102 -0
  32. package/dist/esm/state/rootEventBus.js +47 -0
  33. package/dist/esm/utils/CollabClient.js +17483 -0
  34. package/dist/esm/utils/TokenManager.js +395 -0
  35. package/dist/esm/utils/basedQuerys.js +120 -0
  36. package/dist/esm/utils/jsonDiff.js +6096 -0
  37. package/dist/esm/utils/permission.js +4 -4
  38. package/dist/esm/utils/services.js +133 -69
  39. package/dist/esm/utils/symstoryClient.js +63 -43
  40. package/dist/esm/utils/validation.js +89 -19
  41. package/dist/node/config/environment.js +32 -42
  42. package/dist/node/index.js +37 -28
  43. package/dist/node/services/AIService.js +3 -3
  44. package/dist/node/services/AuthService.js +44 -3
  45. package/dist/node/services/BasedService.js +531 -25
  46. package/dist/node/services/CollabService.js +401 -0
  47. package/dist/node/services/CoreService.js +2266 -0
  48. package/dist/node/services/SocketService.js +197 -59
  49. package/dist/node/services/SymstoryService.js +135 -49
  50. package/dist/node/services/index.js +8 -16
  51. package/dist/node/state/RootStateManager.js +57 -0
  52. package/dist/node/state/rootEventBus.js +46 -0
  53. package/dist/node/utils/CollabClient.js +128 -0
  54. package/dist/node/utils/TokenManager.js +390 -0
  55. package/dist/node/utils/basedQuerys.js +120 -0
  56. package/dist/node/utils/jsonDiff.js +74 -0
  57. package/dist/node/utils/permission.js +4 -4
  58. package/dist/node/utils/services.js +133 -69
  59. package/dist/node/utils/symstoryClient.js +33 -2
  60. package/package.json +23 -14
  61. package/src/config/environment.js +33 -42
  62. package/src/index.js +45 -28
  63. package/src/services/AIService.js +3 -3
  64. package/src/services/AuthService.js +52 -3
  65. package/src/services/BasedService.js +603 -23
  66. package/src/services/CollabService.js +491 -0
  67. package/src/services/CoreService.js +2548 -0
  68. package/src/services/SocketService.js +227 -59
  69. package/src/services/SymstoryService.js +150 -64
  70. package/src/services/index.js +7 -14
  71. package/src/state/RootStateManager.js +71 -0
  72. package/src/state/rootEventBus.js +48 -0
  73. package/src/utils/CollabClient.js +161 -0
  74. package/src/utils/TokenManager.js +462 -0
  75. package/src/utils/basedQuerys.js +123 -0
  76. package/src/utils/jsonDiff.js +109 -0
  77. package/src/utils/permission.js +4 -4
  78. package/src/utils/services.js +144 -69
  79. package/src/utils/symstoryClient.js +36 -2
  80. package/dist/cjs/services/SocketIOService.js +0 -309
  81. package/dist/esm/services/SocketIOService.js +0 -467
  82. package/dist/node/services/SocketIOService.js +0 -280
  83. package/src/services/SocketIOService.js +0 -356
@@ -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,14 @@ var CONFIG = {
3882
3999
  },
3883
4000
  // Environment-specific configurations
3884
4001
  local: {
3885
- baseUrl: "http://localhost:3000",
3886
- // For symstory api
4002
+ // local
3887
4003
  socketUrl: "http://localhost:8080",
3888
4004
  // For socket api
3889
- routerUrl: "http://localhost:3090",
3890
- // For router api
3891
- apiUrl: "http://localhost:13335",
4005
+ apiUrl: "http://localhost:8080",
3892
4006
  // For server api
3893
4007
  basedEnv: "development",
3894
4008
  // For based api
3895
- basedProject: "platform-v2",
4009
+ basedProject: "platform-v2-sm",
3896
4010
  // For based api
3897
4011
  basedOrg: "symbols",
3898
4012
  // For based api
@@ -3905,41 +4019,44 @@ var CONFIG = {
3905
4019
  }
3906
4020
  },
3907
4021
  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",
3912
- basedEnv: "development",
3913
- basedProject: "platform-v2",
4022
+ socketUrl: "https://dev.api.symbols.app",
4023
+ apiUrl: "https://dev.api.symbols.app",
4024
+ githubClientId: "Ov23liHxyWFBxS8f1gnF"
4025
+ },
4026
+ testing: {
4027
+ socketUrl: "https://test.api.symbols.app",
4028
+ apiUrl: "https://test.api.symbols.app",
4029
+ basedEnv: "testing",
4030
+ basedProject: "platform-v2-sm",
3914
4031
  basedOrg: "symbols",
3915
4032
  githubClientId: "Ov23liHxyWFBxS8f1gnF"
3916
4033
  },
4034
+ upcoming: {
4035
+ socketUrl: "https://upcoming.api.symbols.app",
4036
+ apiUrl: "https://upcoming.api.symbols.app",
4037
+ githubClientId: "Ov23liWF7NvdZ056RV5J"
4038
+ },
3917
4039
  staging: {
3918
- baseUrl: "https://staging.story.symbo.ls",
3919
- socketUrl: "https://staging.socket.symbols.app",
3920
- routerUrl: "https://staging.router.symbols.app",
4040
+ socketUrl: "https://staging.api.symbols.app",
3921
4041
  apiUrl: "https://staging.api.symbols.app",
3922
4042
  basedEnv: "staging",
3923
- basedProject: "platform-v2",
4043
+ basedProject: "platform-v2-sm",
3924
4044
  basedOrg: "symbols",
3925
4045
  githubClientId: "Ov23ligwZDQVD0VfuWNa"
3926
4046
  },
3927
4047
  production: {
3928
- baseUrl: "https://story.symbo.ls",
3929
- socketUrl: "https://socket.symbols.app",
3930
- routerUrl: "https://router.symbols.app",
4048
+ socketUrl: "https://api.symbols.app",
3931
4049
  apiUrl: "https://api.symbols.app",
3932
4050
  basedEnv: "production",
3933
- basedProject: "platform-v2",
4051
+ basedProject: "platform-v2-sm",
3934
4052
  basedOrg: "symbols",
3935
4053
  githubClientId: "Ov23liFAlOEIXtX3dBtR"
3936
4054
  }
3937
4055
  };
3938
4056
  var getEnvironment = () => {
3939
- const env2 = process.env.SYMBOLS_APP_ENV || "" || "development";
4057
+ const env2 = process.env.SYMBOLS_APP_ENV || process.env.NODE_ENV;
3940
4058
  if (!CONFIG[env2]) {
3941
- console.warn(`Unknown environment "${env2}", falling back to development`);
3942
- return "development";
4059
+ throw new Error(`Unknown environment "${env2}"`);
3943
4060
  }
3944
4061
  return env2;
3945
4062
  };
@@ -3949,25 +4066,21 @@ var getConfig = () => {
3949
4066
  const envConfig = { ...CONFIG.common, ...CONFIG[env2] };
3950
4067
  const finalConfig = {
3951
4068
  ...envConfig,
3952
- baseUrl: process.env.SYMBOLS_APP_BASE_URL || envConfig.baseUrl,
3953
4069
  socketUrl: process.env.SYMBOLS_APP_SOCKET_URL || envConfig.socketUrl,
3954
- routerUrl: process.env.SYMBOLS_APP_ROUTER_URL || envConfig.routerUrl,
3955
4070
  apiUrl: process.env.SYMBOLS_APP_API_URL || envConfig.apiUrl,
3956
4071
  basedEnv: process.env.SYMBOLS_APP_BASED_ENV || envConfig.basedEnv,
3957
4072
  basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
3958
4073
  basedOrg: process.env.SYMBOLS_APP_BASED_ORG || envConfig.basedOrg,
3959
4074
  githubClientId: process.env.SYMBOLS_APP_GITHUB_CLIENT_ID || envConfig.githubClientId,
3960
- isDevelopment: env2 === "development" || env2 === "local",
4075
+ isDevelopment: isDevelopment(env2),
4076
+ isTesting: env2 === "testing",
3961
4077
  isStaging: env2 === "staging",
3962
4078
  isProduction: env2 === "production"
4079
+ // Store all environment variables for potential future use
3963
4080
  };
3964
4081
  const requiredFields = [
3965
- "baseUrl",
3966
4082
  "socketUrl",
3967
4083
  "apiUrl",
3968
- "basedEnv",
3969
- "basedProject",
3970
- "basedOrg",
3971
4084
  "githubClientId",
3972
4085
  "googleClientId"
3973
4086
  ];
@@ -3980,9 +4093,7 @@ var getConfig = () => {
3980
4093
  if (finalConfig.isDevelopment) {
3981
4094
  console.log(
3982
4095
  "environment in SDK:",
3983
- env2,
3984
- "",
3985
- process.env.SYMBOLS_APP_ENV
4096
+ env2 || process.env.NODE_ENV || process.env.NODE_ENV
3986
4097
  );
3987
4098
  console.log(finalConfig);
3988
4099
  }
@@ -3990,14 +4101,7 @@ var getConfig = () => {
3990
4101
  } catch (error) {
3991
4102
  console.error("Failed to load environment configuration:", error);
3992
4103
  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"
4104
+ ...CONFIG.development
4001
4105
  };
4002
4106
  }
4003
4107
  };
@@ -4106,7 +4210,7 @@ var BasedService = class extends BaseService {
4106
4210
  role: obj.role,
4107
4211
  joinedAt: Date.now()
4108
4212
  });
4109
- await Promise.all([
4213
+ return await Promise.all([
4110
4214
  this._client.call("db:set", {
4111
4215
  $id: userId,
4112
4216
  memberProjects: { $add: membershipId }
@@ -4116,7 +4220,6 @@ var BasedService = class extends BaseService {
4116
4220
  members: { $add: membershipId }
4117
4221
  })
4118
4222
  ]);
4119
- return await this._client.call("db:set", obj);
4120
4223
  } catch (error) {
4121
4224
  throw new Error(`Failed to set bucket: ${error.message}`);
4122
4225
  }
@@ -4154,6 +4257,7 @@ var BasedService = class extends BaseService {
4154
4257
  throw new Error(`Query failed: ${error.message}`);
4155
4258
  }
4156
4259
  }
4260
+ // DEPRECATED
4157
4261
  async fetchUser(userId) {
4158
4262
  if (!userId) {
4159
4263
  throw new Error("User Id is required");
@@ -4161,15 +4265,113 @@ var BasedService = class extends BaseService {
4161
4265
  return await this.query("db", buildUserQuery(userId));
4162
4266
  }
4163
4267
  async getUser(userId) {
4164
- this._requireReady();
4165
4268
  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
- }
4269
+ throw new Error("UserId is required");
4270
+ }
4271
+ const userData = await this._client.query("db", buildGetUserDataQuery(userId)).get();
4272
+ const user = {
4273
+ id: userData.id,
4274
+ name: userData.name,
4275
+ email: userData.email,
4276
+ username: userData.username,
4277
+ globalRole: userData.globalRole,
4278
+ createdAt: userData.createdAt,
4279
+ updatedAt: userData.updatedAt
4280
+ };
4281
+ if (!user) {
4282
+ throw new Error("User not found");
4283
+ }
4284
+ let memberProjects = [];
4285
+ if (userData.memberProjects && userData.memberProjects.length > 0) {
4286
+ const projectKeys = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => membership.project.key);
4287
+ if (projectKeys.length > 0) {
4288
+ const allProjects = await this._fetchProjectsByKeysInChunks(projectKeys);
4289
+ memberProjects = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => {
4290
+ const projectKey = membership.project.key;
4291
+ const correctProject = allProjects.find(
4292
+ (p) => p.key === projectKey
4293
+ );
4294
+ return {
4295
+ project: correctProject || membership.project,
4296
+ role: membership.role,
4297
+ updatedAt: membership.updatedAt,
4298
+ createdAt: membership.createdAt
4299
+ };
4300
+ });
4301
+ }
4302
+ } else {
4303
+ console.log(`[getUser] No member projects found with ID: ${userId}`);
4304
+ }
4305
+ const formattedProjects = memberProjects.filter((membership) => membership.project).map((membership) => ({
4306
+ id: membership.project.id,
4307
+ name: membership.project.name,
4308
+ key: membership.project.key,
4309
+ thumbnail: membership.project.thumbnail,
4310
+ icon: membership.project.icon,
4311
+ tier: membership.project.tier,
4312
+ visibility: membership.project.visibility,
4313
+ access: membership.project.access,
4314
+ role: membership.role,
4315
+ joinedAt: membership.createdAt,
4316
+ updatedAt: membership.updatedAt,
4317
+ members: membership.project.members
4318
+ })) || [];
4319
+ return {
4320
+ id: userId,
4321
+ name: user.name,
4322
+ email: user.email,
4323
+ username: user.username,
4324
+ globalRole: user.globalRole,
4325
+ projects: formattedProjects,
4326
+ createdAt: user.createdAt,
4327
+ updatedAt: user.updatedAt
4328
+ };
4329
+ }
4330
+ /**
4331
+ * Fetches projects by keys in chunks with adaptive chunk sizing
4332
+ * @param {Array<string>} allKeys - All project keys to fetch
4333
+ * @returns {Promise<Array>} - All projects found
4334
+ */
4335
+ async _fetchProjectsByKeysInChunks(allKeys) {
4336
+ if (!allKeys.length) {
4337
+ return [];
4338
+ }
4339
+ const INITIAL_CHUNK_SIZE = 50;
4340
+ const MAX_CHUNK_SIZE = 1e3;
4341
+ const MIN_CHUNK_SIZE = 10;
4342
+ const optimalChunkSize = INITIAL_CHUNK_SIZE;
4343
+ const processChunks = async (keys, size) => {
4344
+ if (!keys.length) {
4345
+ return [];
4346
+ }
4347
+ const chunks = [];
4348
+ for (let i2 = 0; i2 < keys.length; i2 += size) {
4349
+ chunks.push(keys.slice(i2, i2 + size));
4350
+ }
4351
+ try {
4352
+ const result = await this._client.query("db", buildGetProjectsByKeysQuery(chunks[0])).get();
4353
+ const newSize = Math.min(Math.floor(size * 1.5), MAX_CHUNK_SIZE);
4354
+ const firstChunkProjects = result.projects || [];
4355
+ const remainingKeys = keys.slice(chunks[0].length);
4356
+ const remainingProjects = await processChunks(remainingKeys, newSize);
4357
+ return [...firstChunkProjects, ...remainingProjects];
4358
+ } catch (error) {
4359
+ if (error.message && error.message.includes("PayloadTooLarge")) {
4360
+ const newSize = Math.max(Math.floor(size / 2), MIN_CHUNK_SIZE);
4361
+ console.warn(`Reducing chunk size to ${newSize} due to PayloadTooLarge error`);
4362
+ if (newSize === MIN_CHUNK_SIZE && chunks[0].length <= MIN_CHUNK_SIZE) {
4363
+ console.error(`Cannot process chunk, skipping ${chunks[0].length} keys`);
4364
+ const remainingKeys2 = keys.slice(chunks[0].length);
4365
+ return processChunks(remainingKeys2, newSize);
4366
+ }
4367
+ return processChunks(keys, newSize);
4368
+ }
4369
+ console.error(`Error fetching projects: ${error.message}`);
4370
+ const remainingKeys = keys.slice(chunks[0].length);
4371
+ return processChunks(remainingKeys, size);
4372
+ }
4373
+ };
4374
+ return await processChunks(allKeys, optimalChunkSize);
4173
4375
  }
4174
4376
  async getUserByEmail(email) {
4175
4377
  this._requireReady();
@@ -4331,31 +4533,26 @@ var BasedService = class extends BaseService {
4331
4533
  throw new Error(`Failed to create project: ${error.message}`);
4332
4534
  }
4333
4535
  }
4334
- async getProject(projectId, fields = { $all: true }) {
4536
+ async getProject(projectId) {
4335
4537
  this._requireReady();
4336
4538
  if (!projectId) {
4337
4539
  throw new Error("Project ID is required");
4338
4540
  }
4339
4541
  try {
4340
- return await this.call("projects:get", {
4341
- projectId,
4342
- fields: { ...fields }
4343
- });
4542
+ return await this._client.query("db", buildGetProjectDataQuery(projectId)).get();
4344
4543
  } catch (error) {
4345
4544
  throw new Error(`Failed to get project: ${error.message}`);
4346
4545
  }
4347
4546
  }
4348
- async getProjectByKey(key, fields = { $all: true }) {
4547
+ async getProjectByKey(key) {
4349
4548
  this._requireReady();
4350
4549
  try {
4351
- return await this.call("projects:get", {
4352
- key,
4353
- fields: { ...fields }
4354
- });
4550
+ return await this._client.query("db", buildGetProjectByKeyDataQuery(key)).get();
4355
4551
  } catch (error) {
4356
4552
  throw new Error(`Failed to get project by key: ${error.message}`);
4357
4553
  }
4358
4554
  }
4555
+ // DEPRECATED
4359
4556
  async fetchProject(projectId) {
4360
4557
  this._requireReady();
4361
4558
  if (!projectId) {
@@ -4436,7 +4633,9 @@ var BasedService = class extends BaseService {
4436
4633
  pkg = 2,
4437
4634
  seats = 1,
4438
4635
  interval = "monthly",
4439
- plan = "startup"
4636
+ plan = "startup",
4637
+ successUrl = `${window.location.origin}/success`,
4638
+ cancelUrl = `${window.location.origin}/pricing`
4440
4639
  }) {
4441
4640
  this._requireReady();
4442
4641
  const prices = {
@@ -4458,7 +4657,9 @@ var BasedService = class extends BaseService {
4458
4657
  return await this.call("checkout", {
4459
4658
  price,
4460
4659
  seats,
4461
- projectId
4660
+ projectId,
4661
+ successUrl,
4662
+ cancelUrl
4462
4663
  });
4463
4664
  } catch (error) {
4464
4665
  throw new Error(`Failed to checkout: ${error.message}`);
@@ -4633,19 +4834,429 @@ var BasedService = class extends BaseService {
4633
4834
  * @param {string} newKey - The new key of the project (optional)
4634
4835
  * @returns {Promise<Object>} The duplicated project
4635
4836
  */
4636
- async duplicateProject(projectId, newName, newKey) {
4837
+ async duplicateProject(projectId, newName, newKey, targetUserId) {
4637
4838
  this._requireReady();
4638
4839
  try {
4639
4840
  return await this.call("projects:duplicate", {
4640
4841
  projectId,
4641
4842
  newName,
4642
- newKey
4843
+ newKey,
4844
+ targetUserId
4643
4845
  });
4644
4846
  } catch (error) {
4645
4847
  throw new Error(`Failed to duplicate project: ${error.message}`);
4646
4848
  }
4647
4849
  }
4850
+ /**
4851
+ * List available subscription plans
4852
+ * @param {Object} options - Options for filtering plans
4853
+ * @param {number} options.page - Page number (default: 1)
4854
+ * @param {number} options.limit - Number of plans per page (default: 20)
4855
+ * @param {string} options.status - Filter plans by status (admin only)
4856
+ * @param {boolean} options.includeSubscriptionCounts - Include subscription counts (admin only)
4857
+ * @param {string} options.sortBy - Field to sort by (default: 'displayOrder')
4858
+ * @param {string} options.sortOrder - Sort order ('asc' or 'desc', default: 'asc')
4859
+ * @returns {Promise<Object>} List of plans with pagination info
4860
+ */
4861
+ async listPlans(options = {}) {
4862
+ this._requireReady();
4863
+ try {
4864
+ return await this.call("plans:list", options);
4865
+ } catch (error) {
4866
+ throw new Error(`Failed to list plans: ${error.message}`);
4867
+ }
4868
+ }
4869
+ /**
4870
+ * Subscribe to a plan
4871
+ * @param {string} planId - ID of the plan to subscribe to
4872
+ * @param {Object} options - Options for the subscription
4873
+ * @param {string} options.paymentMethod - Payment method
4874
+ * @param {Object} options.billingAddress - Billing address
4875
+ * @param {string} options.stripeCustomerId - Stripe customer ID
4876
+ * @param {string} options.stripeSubscriptionId - Stripe subscription ID
4877
+ * @returns {Promise<Object>} Subscription details
4878
+ */
4879
+ async subscribeToPlan(planId, options = {}) {
4880
+ this._requireReady();
4881
+ try {
4882
+ return await this.call("subscriptions:create", { planId, ...options });
4883
+ } catch (error) {
4884
+ throw new Error(`Failed to subscribe to plan: ${error.message}`);
4885
+ }
4886
+ }
4887
+ /**
4888
+ * Get details of user's current subscription
4889
+ * @param {string} subscriptionId - ID of the subscription to get details for
4890
+ * @returns {Promise<Object>} Subscription details
4891
+ */
4892
+ async getSubscriptionDetails(subscriptionId) {
4893
+ this._requireReady();
4894
+ try {
4895
+ return await this.call("subscriptions:details", {
4896
+ subscriptionId
4897
+ });
4898
+ } catch (error) {
4899
+ throw new Error(`Failed to get subscription details: ${error.message}`);
4900
+ }
4901
+ }
4902
+ /**
4903
+ * Check if the current subscription is active
4904
+ * @param {string} subscriptionId - ID of the subscription to check
4905
+ * @returns {Promise<Object>} Subscription status info
4906
+ */
4907
+ async checkSubscriptionStatus(subscriptionId) {
4908
+ this._requireReady();
4909
+ try {
4910
+ return await this.call("subscriptions:check-status", {
4911
+ subscriptionId
4912
+ });
4913
+ } catch (error) {
4914
+ throw new Error(`Failed to check subscription status: ${error.message}`);
4915
+ }
4916
+ }
4917
+ /**
4918
+ * Upgrade the current subscription to a new plan
4919
+ * @param {string} planId - ID of the plan to upgrade to
4920
+ * @param {string} stripeSubscriptionId - ID of the Stripe subscription to upgrade
4921
+ * @returns {Promise<Object>} Updated subscription details
4922
+ */
4923
+ async upgradeSubscription(planId, stripeSubscriptionId) {
4924
+ this._requireReady();
4925
+ try {
4926
+ return await this.call("subscriptions:upgrade", {
4927
+ planId,
4928
+ stripeSubscriptionId
4929
+ });
4930
+ } catch (error) {
4931
+ throw new Error(`Failed to upgrade subscription: ${error.message}`);
4932
+ }
4933
+ }
4934
+ /**
4935
+ * Downgrade the current subscription to a new plan
4936
+ * @param {string} planId - ID of the plan to downgrade to
4937
+ * @param {boolean} applyImmediately - Whether to apply the downgrade immediately
4938
+ * @param {string} stripeSubscriptionId - ID of the Stripe subscription to downgrade
4939
+ * @returns {Promise<Object>} Updated subscription details
4940
+ */
4941
+ async downgradeSubscription(planId, stripeSubscriptionId, applyImmediately = false) {
4942
+ this._requireReady();
4943
+ try {
4944
+ return await this.call("subscriptions:downgrade", {
4945
+ planId,
4946
+ applyImmediately,
4947
+ stripeSubscriptionId
4948
+ });
4949
+ } catch (error) {
4950
+ throw new Error(`Failed to downgrade subscription: ${error.message}`);
4951
+ }
4952
+ }
4953
+ /**
4954
+ * Cancel the current subscription
4955
+ * @param {boolean} cancelImmediately - Whether to cancel immediately or at period end
4956
+ * @param {string} reason - Reason for cancellation
4957
+ * @returns {Promise<Object>} Result of cancellation
4958
+ */
4959
+ async cancelSubscription(cancelImmediately = false, reason = "") {
4960
+ this._requireReady();
4961
+ try {
4962
+ return await this.call("subscriptions:cancel", {
4963
+ cancelImmediately,
4964
+ reason
4965
+ });
4966
+ } catch (error) {
4967
+ throw new Error(`Failed to cancel subscription: ${error.message}`);
4968
+ }
4969
+ }
4970
+ /**
4971
+ * Reactivate a subscription that was scheduled for cancellation
4972
+ * @returns {Promise<Object>} Updated subscription details
4973
+ */
4974
+ async reactivateSubscription(stripeSubscriptionId) {
4975
+ this._requireReady();
4976
+ try {
4977
+ return await this.call("subscriptions:reactivate", {
4978
+ stripeSubscriptionId
4979
+ });
4980
+ } catch (error) {
4981
+ throw new Error(`Failed to reactivate subscription: ${error.message}`);
4982
+ }
4983
+ }
4984
+ /**
4985
+ * Generate an invoice for the current subscription
4986
+ * @param {string} subscriptionId - ID of the subscription to generate the invoice for
4987
+ * @param {boolean} forceGenerate - Whether to force the generation of the invoice
4988
+ * @param {Array} customItems - Custom items to add to the invoice
4989
+ * @returns {Promise<Object>} Generated invoice
4990
+ */
4991
+ async generateInvoice(subscriptionId, forceGenerate = false, customItems = []) {
4992
+ this._requireReady();
4993
+ try {
4994
+ return await this.call("billing:generate-invoice", {
4995
+ subscriptionId,
4996
+ forceGenerate,
4997
+ customItems
4998
+ });
4999
+ } catch (error) {
5000
+ throw new Error(`Failed to generate invoice: ${error.message}`);
5001
+ }
5002
+ }
5003
+ /**
5004
+ * Get usage report for the current subscription
5005
+ * @param {string} subscriptionId - ID of the subscription to get the usage report for
5006
+ * @param {boolean} forceRefresh - Whether to force the refresh of the usage report
5007
+ * @returns {Promise<Object>} Usage report
5008
+ */
5009
+ async getUsageReport(subscriptionId, forceRefresh = false) {
5010
+ this._requireReady();
5011
+ try {
5012
+ return await this.call("subscriptions:get-usage-report", {
5013
+ subscriptionId,
5014
+ forceRefresh
5015
+ });
5016
+ } catch (error) {
5017
+ throw new Error(`Failed to get usage report: ${error.message}`);
5018
+ }
5019
+ }
5020
+ /**
5021
+ * Invite a user to be an account owner for the current subscription
5022
+ * @param {string} email - Email of the user to invite
5023
+ * @param {string} name - Name of the user to invite
5024
+ * @param {string} callbackUrl - URL to redirect the user to after accepting the invitation
5025
+ * @returns {Promise<Object>} Result of invitation
5026
+ */
5027
+ async inviteAccountOwner(email, name, callbackUrl) {
5028
+ this._requireReady();
5029
+ try {
5030
+ return await this.call("subscriptions:invite", {
5031
+ email,
5032
+ name,
5033
+ callbackUrl
5034
+ });
5035
+ } catch (error) {
5036
+ throw new Error(`Failed to invite account owner: ${error.message}`);
5037
+ }
5038
+ }
5039
+ /**
5040
+ * Accept an invitation to become an account owner
5041
+ * @param {string} token - Invitation token
5042
+ * @returns {Promise<Object>} Result of accepting invitation
5043
+ */
5044
+ async acceptOwnerInvitation(token) {
5045
+ this._requireReady();
5046
+ try {
5047
+ return await this.call("subscriptions:accept-owner-invitation", {
5048
+ token
5049
+ });
5050
+ } catch (error) {
5051
+ throw new Error(`Failed to accept owner invitation: ${error.message}`);
5052
+ }
5053
+ }
5054
+ /**
5055
+ * Remove an account owner from the current subscription
5056
+ * @param {string} userId - ID of the user to remove
5057
+ * @returns {Promise<Object>} Result of removal
5058
+ */
5059
+ async removeAccountOwner(userId) {
5060
+ this._requireReady();
5061
+ try {
5062
+ return await this.call("subscriptions:remove-account-owner", {
5063
+ targetUserId: userId
5064
+ });
5065
+ } catch (error) {
5066
+ throw new Error(`Failed to remove account owner: ${error.message}`);
5067
+ }
5068
+ }
5069
+ /**
5070
+ * Check if a resource limit has been reached
5071
+ * @param {string} resourceType - Type of resource to check
5072
+ * @param {string} projectId - ID of the project to check the resource limit for
5073
+ * @param {number} quantity - Amount being requested
5074
+ * @param {string} userId - ID of user to check (admin only, defaults to current user)
5075
+ * @returns {Promise<Object>} Result of check
5076
+ */
5077
+ async checkResourceLimit(resourceType, projectId, quantity = 1, userId = "") {
5078
+ this._requireReady();
5079
+ try {
5080
+ return await this.call("subscriptions:check-resource-limit", {
5081
+ resourceType,
5082
+ projectId,
5083
+ quantity,
5084
+ userId
5085
+ });
5086
+ } catch (error) {
5087
+ throw new Error(`Failed to check resource limit: ${error.message}`);
5088
+ }
5089
+ }
5090
+ /**
5091
+ * Check if a user has access to a feature
5092
+ * @param {string} featureKey - Key of the feature to check
5093
+ * @param {string} userId - ID of user to check (admin only, defaults to current user)
5094
+ * @returns {Promise<Object>} Access check result
5095
+ */
5096
+ async checkFeatureAccess(featureKey, userId) {
5097
+ this._requireReady();
5098
+ try {
5099
+ return await this.call("features:check-access", {
5100
+ featureKey,
5101
+ userId
5102
+ });
5103
+ } catch (error) {
5104
+ throw new Error(`Failed to check feature access: ${error.message}`);
5105
+ }
5106
+ }
5107
+ /**
5108
+ * Get all features available to the current user
5109
+ * @returns {Promise<Object>} Available features
5110
+ */
5111
+ async getUserFeatures() {
5112
+ this._requireReady();
5113
+ try {
5114
+ return await this.call("subscriptions:get-user-features", {});
5115
+ } catch (error) {
5116
+ throw new Error(`Failed to get user features: ${error.message}`);
5117
+ }
5118
+ }
5119
+ /**
5120
+ * Get all available features across all plans
5121
+ * @param {string} subscriptionId - ID of the subscription to get the available features for
5122
+ * @param {string} userId - ID of user to get the available features for (admin only, defaults to current user)
5123
+ * @param {boolean} includeDetails - Whether to include details about the features
5124
+ * @returns {Promise<Object>} Available features
5125
+ */
5126
+ async getAvailableFeatures(subscriptionId, userId = "", includeDetails = false) {
5127
+ this._requireReady();
5128
+ try {
5129
+ return await this.call("features:get-available", {
5130
+ subscriptionId,
5131
+ userId,
5132
+ includeDetails
5133
+ });
5134
+ } catch (error) {
5135
+ throw new Error(`Failed to get available features: ${error.message}`);
5136
+ }
5137
+ }
5138
+ /**
5139
+ * List all feature flags (admin only)
5140
+ * @param {Object} options - Options for listing feature flags
5141
+ * @param {number} options.page - Page number
5142
+ * @param {number} options.limit - Number of items per page
5143
+ * @param {string} options.status - Filter by status
5144
+ * @returns {Promise<Object>} List of feature flags
5145
+ */
5146
+ async listFeatureFlags(options = {}) {
5147
+ this._requireReady();
5148
+ try {
5149
+ return await this.call("features:list", options);
5150
+ } catch (error) {
5151
+ throw new Error(`Failed to list feature flags: ${error.message}`);
5152
+ }
5153
+ }
5154
+ /**
5155
+ * Update a feature flag (admin only)
5156
+ * @param {string} flagId - ID of the feature flag to update
5157
+ * @param {Object} options - Update data
5158
+ * @param {string} options.key - Key of the feature flag
5159
+ * @param {string} options.name - Name of the feature flag
5160
+ * @param {string} options.description - Description of the feature flag
5161
+ * @param {string} options.defaultValue - Default value of the feature flag
5162
+ * @param {Object} options.planOverrides - Plan overrides for the feature flag
5163
+ * @param {Object} options.userOverrides - User overrides for the feature flag
5164
+ * @param {string} options.status - Status of the feature flag
5165
+ * @returns {Promise<Object>} Updated feature flag
5166
+ */
5167
+ async updateFeatureFlag(flagId, options) {
5168
+ this._requireReady();
5169
+ try {
5170
+ return await this.call("features:update", {
5171
+ flagId,
5172
+ ...options
5173
+ });
5174
+ } catch (error) {
5175
+ throw new Error(`Failed to update feature flag: ${error.message}`);
5176
+ }
5177
+ }
5178
+ /**
5179
+ * Remove a feature flag (admin only)
5180
+ * @param {string} flagId - ID of the feature flag to remove
5181
+ * @returns {Promise<Object>} Result of removal
5182
+ */
5183
+ async removeFeatureFlag(flagId) {
5184
+ this._requireReady();
5185
+ try {
5186
+ return await this.call("features:remove", {
5187
+ flagId
5188
+ });
5189
+ } catch (error) {
5190
+ throw new Error(`Failed to remove feature flag: ${error.message}`);
5191
+ }
5192
+ }
5193
+ /**
5194
+ * Batch update feature flags (admin only)
5195
+ * @param {Array} operations - Array of feature flag operations
5196
+ * @param {string} operations.flagId - ID of the feature flag to update
5197
+ * @param {string} operations.key - Key of the feature flag
5198
+ * @param {string} operations.name - Name of the feature flag
5199
+ * @param {string} operations.description - Description of the feature flag
5200
+ * @param {boolean} operations.defaultValue - Default value of the feature flag
5201
+ * @param {Object} operations.planOverrides - Plan overrides for the feature flag
5202
+ * @param {Object} operations.userOverrides - User overrides for the feature flag
5203
+ * @param {string} operations.status - Status of the feature flag
5204
+ * @returns {Promise<Object>} Result of batch update
5205
+ */
5206
+ async batchUpdateFeatureFlags(operations) {
5207
+ this._requireReady();
5208
+ try {
5209
+ return await this.call("features:batch-update", {
5210
+ operations
5211
+ });
5212
+ } catch (error) {
5213
+ throw new Error(`Failed to batch update feature flags: ${error.message}`);
5214
+ }
5215
+ }
5216
+ /**
5217
+ * Update plan details (admin only)
5218
+ * @param {string} planId - ID of the plan to update
5219
+ * @param {Object} data - Update data
5220
+ * @param {string} data.name - Display name (e.g., "Pro", "Team")
5221
+ * @param {string} data.description - Marketing description
5222
+ * @param {number} data.price - Monthly price in cents
5223
+ * @param {number} data.annualPrice - Annual price in cents (discounted)
5224
+ * @param {number} data.lifetimePrice - One-time lifetime price in cents
5225
+ * @param {string} data.billingType - Payment type
5226
+ * @param {string} data.status - Status
5227
+ * @param {Object} data.features - Detailed feature configuration
5228
+ * @returns {Promise<Object>} Updated plan
5229
+ */
5230
+ async updatePlanDetails(planId, data) {
5231
+ this._requireReady();
5232
+ try {
5233
+ return await this.call("plans:update-details", {
5234
+ planId,
5235
+ data
5236
+ });
5237
+ } catch (error) {
5238
+ throw new Error(`Failed to update plan details: ${error.message}`);
5239
+ }
5240
+ }
5241
+ /**
5242
+ * Update plan status (admin only)
5243
+ * @param {string} planId - ID of the plan to update
5244
+ * @param {string} status - New status
5245
+ * @returns {Promise<Object>} Updated plan
5246
+ */
5247
+ async updatePlanStatus(planId, status) {
5248
+ this._requireReady();
5249
+ try {
5250
+ return await this.call("plans:update-status", {
5251
+ planId,
5252
+ status
5253
+ });
5254
+ } catch (error) {
5255
+ throw new Error(`Failed to update plan status: ${error.message}`);
5256
+ }
5257
+ }
4648
5258
  };
4649
5259
  export {
4650
5260
  BasedService
4651
5261
  };
5262
+ // @preserve-env