@symbo.ls/sdk 3.2.3 → 3.2.7
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/README.md +141 -0
- package/dist/cjs/config/environment.js +94 -10
- package/dist/cjs/index.js +152 -12
- package/dist/cjs/services/AdminService.js +351 -0
- package/dist/cjs/services/AuthService.js +738 -305
- package/dist/cjs/services/BaseService.js +158 -6
- package/dist/cjs/services/BranchService.js +484 -0
- package/dist/cjs/services/CollabService.js +439 -116
- package/dist/cjs/services/DnsService.js +340 -0
- package/dist/cjs/services/FeatureFlagService.js +175 -0
- package/dist/cjs/services/FileService.js +201 -0
- package/dist/cjs/services/IntegrationService.js +538 -0
- package/dist/cjs/services/MetricsService.js +62 -0
- package/dist/cjs/services/PaymentService.js +271 -0
- package/dist/cjs/services/PlanService.js +426 -0
- package/dist/cjs/services/ProjectService.js +1207 -0
- package/dist/cjs/services/PullRequestService.js +503 -0
- package/dist/cjs/services/ScreenshotService.js +304 -0
- package/dist/cjs/services/SubscriptionService.js +396 -0
- package/dist/cjs/services/TrackingService.js +661 -0
- package/dist/cjs/services/WaitlistService.js +148 -0
- package/dist/cjs/services/index.js +60 -4
- package/dist/cjs/state/RootStateManager.js +2 -23
- package/dist/cjs/state/rootEventBus.js +9 -0
- package/dist/cjs/utils/CollabClient.js +78 -12
- package/dist/cjs/utils/TokenManager.js +16 -3
- package/dist/cjs/utils/changePreprocessor.js +199 -0
- package/dist/cjs/utils/jsonDiff.js +46 -4
- package/dist/cjs/utils/ordering.js +309 -0
- package/dist/cjs/utils/services.js +285 -128
- package/dist/cjs/utils/validation.js +0 -3
- package/dist/esm/config/environment.js +94 -10
- package/dist/esm/index.js +47862 -18248
- package/dist/esm/services/AdminService.js +1132 -0
- package/dist/esm/services/AuthService.js +1493 -386
- package/dist/esm/services/BaseService.js +757 -6
- package/dist/esm/services/BranchService.js +1265 -0
- package/dist/esm/services/CollabService.js +24956 -16089
- package/dist/esm/services/DnsService.js +1121 -0
- package/dist/esm/services/FeatureFlagService.js +956 -0
- package/dist/esm/services/FileService.js +982 -0
- package/dist/esm/services/IntegrationService.js +1319 -0
- package/dist/esm/services/MetricsService.js +843 -0
- package/dist/esm/services/PaymentService.js +1052 -0
- package/dist/esm/services/PlanService.js +1207 -0
- package/dist/esm/services/ProjectService.js +2526 -0
- package/dist/esm/services/PullRequestService.js +1284 -0
- package/dist/esm/services/ScreenshotService.js +1085 -0
- package/dist/esm/services/SubscriptionService.js +1177 -0
- package/dist/esm/services/TrackingService.js +18454 -0
- package/dist/esm/services/WaitlistService.js +929 -0
- package/dist/esm/services/index.js +47373 -18027
- package/dist/esm/state/RootStateManager.js +11 -23
- package/dist/esm/state/rootEventBus.js +9 -0
- package/dist/esm/utils/CollabClient.js +17526 -16120
- package/dist/esm/utils/TokenManager.js +16 -3
- package/dist/esm/utils/changePreprocessor.js +542 -0
- package/dist/esm/utils/jsonDiff.js +958 -43
- package/dist/esm/utils/ordering.js +291 -0
- package/dist/esm/utils/services.js +285 -128
- package/dist/esm/utils/validation.js +116 -50
- package/dist/node/config/environment.js +94 -10
- package/dist/node/index.js +183 -16
- package/dist/node/services/AdminService.js +332 -0
- package/dist/node/services/AuthService.js +742 -310
- package/dist/node/services/BaseService.js +148 -6
- package/dist/node/services/BranchService.js +465 -0
- package/dist/node/services/CollabService.js +439 -116
- package/dist/node/services/DnsService.js +321 -0
- package/dist/node/services/FeatureFlagService.js +156 -0
- package/dist/node/services/FileService.js +182 -0
- package/dist/node/services/IntegrationService.js +519 -0
- package/dist/node/services/MetricsService.js +43 -0
- package/dist/node/services/PaymentService.js +252 -0
- package/dist/node/services/PlanService.js +407 -0
- package/dist/node/services/ProjectService.js +1188 -0
- package/dist/node/services/PullRequestService.js +484 -0
- package/dist/node/services/ScreenshotService.js +285 -0
- package/dist/node/services/SubscriptionService.js +377 -0
- package/dist/node/services/TrackingService.js +632 -0
- package/dist/node/services/WaitlistService.js +129 -0
- package/dist/node/services/index.js +60 -4
- package/dist/node/state/RootStateManager.js +2 -23
- package/dist/node/state/rootEventBus.js +9 -0
- package/dist/node/utils/CollabClient.js +77 -11
- package/dist/node/utils/TokenManager.js +16 -3
- package/dist/node/utils/changePreprocessor.js +180 -0
- package/dist/node/utils/jsonDiff.js +46 -4
- package/dist/node/utils/ordering.js +290 -0
- package/dist/node/utils/services.js +285 -128
- package/dist/node/utils/validation.js +0 -3
- package/package.json +30 -18
- package/src/config/environment.js +95 -10
- package/src/index.js +190 -23
- package/src/services/AdminService.js +374 -0
- package/src/services/AuthService.js +874 -328
- package/src/services/BaseService.js +166 -6
- package/src/services/BranchService.js +536 -0
- package/src/services/CollabService.js +557 -148
- package/src/services/DnsService.js +366 -0
- package/src/services/FeatureFlagService.js +174 -0
- package/src/services/FileService.js +213 -0
- package/src/services/IntegrationService.js +548 -0
- package/src/services/MetricsService.js +40 -0
- package/src/services/PaymentService.js +287 -0
- package/src/services/PlanService.js +468 -0
- package/src/services/ProjectService.js +1366 -0
- package/src/services/PullRequestService.js +537 -0
- package/src/services/ScreenshotService.js +258 -0
- package/src/services/SubscriptionService.js +425 -0
- package/src/services/TrackingService.js +853 -0
- package/src/services/WaitlistService.js +130 -0
- package/src/services/index.js +79 -5
- package/src/services/tests/BranchService/createBranch.test.js +153 -0
- package/src/services/tests/BranchService/deleteBranch.test.js +173 -0
- package/src/services/tests/BranchService/getBranchChanges.test.js +146 -0
- package/src/services/tests/BranchService/listBranches.test.js +87 -0
- package/src/services/tests/BranchService/mergeBranch.test.js +210 -0
- package/src/services/tests/BranchService/publishVersion.test.js +183 -0
- package/src/services/tests/BranchService/renameBranch.test.js +240 -0
- package/src/services/tests/BranchService/resetBranch.test.js +152 -0
- package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +67 -0
- package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +75 -0
- package/src/services/tests/FileService/createFileFormData.test.js +74 -0
- package/src/services/tests/FileService/getFileUrl.test.js +69 -0
- package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
- package/src/services/tests/FileService/uploadDocument.test.js +36 -0
- package/src/services/tests/FileService/uploadFile.test.js +78 -0
- package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
- package/src/services/tests/FileService/uploadImage.test.js +36 -0
- package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
- package/src/services/tests/FileService/validateFile.test.js +63 -0
- package/src/services/tests/PlanService/createPlan.test.js +104 -0
- package/src/services/tests/PlanService/createPlanWithValidation.test.js +523 -0
- package/src/services/tests/PlanService/deletePlan.test.js +92 -0
- package/src/services/tests/PlanService/getActivePlans.test.js +123 -0
- package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
- package/src/services/tests/PlanService/getPlan.test.js +50 -0
- package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
- package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
- package/src/services/tests/PlanService/getPlans.test.js +53 -0
- package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
- package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
- package/src/services/tests/PlanService/initializePlans.test.js +75 -0
- package/src/services/tests/PlanService/updatePlan.test.js +111 -0
- package/src/services/tests/PlanService/updatePlanWithValidation.test.js +556 -0
- package/src/state/RootStateManager.js +37 -32
- package/src/state/rootEventBus.js +19 -0
- package/src/utils/CollabClient.js +99 -12
- package/src/utils/TokenManager.js +20 -3
- package/src/utils/changePreprocessor.js +239 -0
- package/src/utils/jsonDiff.js +40 -5
- package/src/utils/ordering.js +271 -0
- package/src/utils/services.js +306 -139
- package/src/utils/validation.js +0 -3
- package/dist/cjs/services/AIService.js +0 -155
- package/dist/cjs/services/BasedService.js +0 -1185
- package/dist/cjs/services/CoreService.js +0 -2295
- package/dist/cjs/services/SocketService.js +0 -309
- package/dist/cjs/services/SymstoryService.js +0 -571
- package/dist/cjs/utils/basedQuerys.js +0 -181
- package/dist/cjs/utils/symstoryClient.js +0 -259
- package/dist/esm/services/AIService.js +0 -185
- package/dist/esm/services/BasedService.js +0 -5262
- package/dist/esm/services/CoreService.js +0 -2827
- package/dist/esm/services/SocketService.js +0 -456
- package/dist/esm/services/SymstoryService.js +0 -7025
- package/dist/esm/utils/basedQuerys.js +0 -163
- package/dist/esm/utils/symstoryClient.js +0 -354
- package/dist/node/services/AIService.js +0 -136
- package/dist/node/services/BasedService.js +0 -1156
- package/dist/node/services/CoreService.js +0 -2266
- package/dist/node/services/SocketService.js +0 -280
- package/dist/node/services/SymstoryService.js +0 -542
- package/dist/node/utils/basedQuerys.js +0 -162
- package/dist/node/utils/symstoryClient.js +0 -230
- package/src/services/AIService.js +0 -150
- package/src/services/BasedService.js +0 -1302
- package/src/services/CoreService.js +0 -2548
- package/src/services/SocketService.js +0 -336
- package/src/services/SymstoryService.js +0 -649
- package/src/utils/basedQuerys.js +0 -164
- package/src/utils/symstoryClient.js +0 -252
|
@@ -1,1185 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var BasedService_exports = {};
|
|
29
|
-
__export(BasedService_exports, {
|
|
30
|
-
BasedService: () => BasedService
|
|
31
|
-
});
|
|
32
|
-
module.exports = __toCommonJS(BasedService_exports);
|
|
33
|
-
var import_BaseService = require("./BaseService.js");
|
|
34
|
-
var import_basedQuerys = require("../utils/basedQuerys.js");
|
|
35
|
-
var import_client = __toESM(require("@based/client"), 1);
|
|
36
|
-
var import_utils = require("@domql/utils");
|
|
37
|
-
var import_environment = __toESM(require("../config/environment.js"), 1);
|
|
38
|
-
class BasedService extends import_BaseService.BaseService {
|
|
39
|
-
constructor(config) {
|
|
40
|
-
super(config);
|
|
41
|
-
this._client = null;
|
|
42
|
-
this._subscriptions = /* @__PURE__ */ new Map();
|
|
43
|
-
}
|
|
44
|
-
init({ context }) {
|
|
45
|
-
try {
|
|
46
|
-
const { env, org, project } = context.based || {
|
|
47
|
-
env: import_environment.default.basedEnv,
|
|
48
|
-
org: import_environment.default.basedOrg,
|
|
49
|
-
project: import_environment.default.basedProject
|
|
50
|
-
};
|
|
51
|
-
if (!env || !org || !project) {
|
|
52
|
-
throw new Error("Based configuration missing required parameters");
|
|
53
|
-
}
|
|
54
|
-
this._client = new import_client.default({
|
|
55
|
-
env,
|
|
56
|
-
org,
|
|
57
|
-
project
|
|
58
|
-
});
|
|
59
|
-
this._info = {
|
|
60
|
-
config: {
|
|
61
|
-
env,
|
|
62
|
-
org: this._maskString(org),
|
|
63
|
-
project: this._maskString(project)
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
this._setReady();
|
|
67
|
-
} catch (error) {
|
|
68
|
-
this._setError(error);
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Helper method to mask sensitive strings
|
|
73
|
-
_maskString(str) {
|
|
74
|
-
if (!str) {
|
|
75
|
-
return "";
|
|
76
|
-
}
|
|
77
|
-
return `${str.substr(0, 4)}...${str.substr(-4)}`;
|
|
78
|
-
}
|
|
79
|
-
updateContext(context) {
|
|
80
|
-
var _a;
|
|
81
|
-
this._context = { ...this._context, ...context };
|
|
82
|
-
if (this._context.authToken && ((_a = this._context.user) == null ? void 0 : _a.id)) {
|
|
83
|
-
this.setAuthState(this._context.authToken, this._context.user.id);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async setAuthState(authState) {
|
|
87
|
-
this._requireReady();
|
|
88
|
-
const newAuthState = {
|
|
89
|
-
...authState,
|
|
90
|
-
persistent: true
|
|
91
|
-
};
|
|
92
|
-
try {
|
|
93
|
-
return await this._client.setAuthState(newAuthState);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
throw new Error(`Failed to set auth state: ${error.message}`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
async setBucket(bucketId, callback) {
|
|
99
|
-
this._requireReady();
|
|
100
|
-
if (!(0, import_utils.isString)(bucketId)) {
|
|
101
|
-
throw new Error("Invalid type of bucket ID", bucketId);
|
|
102
|
-
}
|
|
103
|
-
if (!this._context.project) {
|
|
104
|
-
throw new Error("Project is undefined");
|
|
105
|
-
}
|
|
106
|
-
try {
|
|
107
|
-
const obj = {
|
|
108
|
-
$id: this._context.project.id,
|
|
109
|
-
// TODO: change to getProjectId
|
|
110
|
-
bucket: bucketId
|
|
111
|
-
};
|
|
112
|
-
if ((0, import_utils.isFunction)(callback)) {
|
|
113
|
-
const data = await this._client.call("db:set", obj);
|
|
114
|
-
return callback(data);
|
|
115
|
-
}
|
|
116
|
-
return await this._client.call("db:set", obj);
|
|
117
|
-
} catch (error) {
|
|
118
|
-
throw new Error(`Failed to set bucket: ${error.message}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async setUserForced(userId, obj) {
|
|
122
|
-
this._requireReady();
|
|
123
|
-
try {
|
|
124
|
-
await this._client.query("db", {
|
|
125
|
-
$id: obj.projectId,
|
|
126
|
-
members: {
|
|
127
|
-
$list: true,
|
|
128
|
-
user: {
|
|
129
|
-
id: true
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}).get();
|
|
133
|
-
const { id: membershipId } = await this._client.call("db:set", {
|
|
134
|
-
type: "projectMember",
|
|
135
|
-
user: userId,
|
|
136
|
-
project: obj.projectId,
|
|
137
|
-
role: obj.role,
|
|
138
|
-
joinedAt: Date.now()
|
|
139
|
-
});
|
|
140
|
-
return await Promise.all([
|
|
141
|
-
this._client.call("db:set", {
|
|
142
|
-
$id: userId,
|
|
143
|
-
memberProjects: { $add: membershipId }
|
|
144
|
-
}),
|
|
145
|
-
this._client.call("db:set", {
|
|
146
|
-
$id: obj.projectId,
|
|
147
|
-
members: { $add: membershipId }
|
|
148
|
-
})
|
|
149
|
-
]);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
throw new Error(`Failed to set bucket: ${error.message}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async query(collection, query, options = {}) {
|
|
155
|
-
this._requireReady();
|
|
156
|
-
try {
|
|
157
|
-
return await this._client.query(collection, query, {
|
|
158
|
-
...options,
|
|
159
|
-
context: this._context
|
|
160
|
-
}).get();
|
|
161
|
-
} catch (error) {
|
|
162
|
-
throw new Error(`Query failed: ${error.message}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
async setProject(params) {
|
|
166
|
-
this._requireReady();
|
|
167
|
-
try {
|
|
168
|
-
return await this._client.call("db:set", {
|
|
169
|
-
type: "project",
|
|
170
|
-
...params
|
|
171
|
-
});
|
|
172
|
-
} catch (error) {
|
|
173
|
-
throw new Error(`Query failed: ${error.message}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
async setUser(params) {
|
|
177
|
-
this._requireReady();
|
|
178
|
-
try {
|
|
179
|
-
return await this._client.call("db:set", {
|
|
180
|
-
type: "user",
|
|
181
|
-
...params
|
|
182
|
-
});
|
|
183
|
-
} catch (error) {
|
|
184
|
-
throw new Error(`Query failed: ${error.message}`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
// DEPRECATED
|
|
188
|
-
async fetchUser(userId) {
|
|
189
|
-
if (!userId) {
|
|
190
|
-
throw new Error("User Id is required");
|
|
191
|
-
}
|
|
192
|
-
return await this.query("db", (0, import_basedQuerys.buildUserQuery)(userId));
|
|
193
|
-
}
|
|
194
|
-
async getUser(userId) {
|
|
195
|
-
if (!userId) {
|
|
196
|
-
throw new Error("UserId is required");
|
|
197
|
-
}
|
|
198
|
-
const userData = await this._client.query("db", (0, import_basedQuerys.buildGetUserDataQuery)(userId)).get();
|
|
199
|
-
const user = {
|
|
200
|
-
id: userData.id,
|
|
201
|
-
name: userData.name,
|
|
202
|
-
email: userData.email,
|
|
203
|
-
username: userData.username,
|
|
204
|
-
globalRole: userData.globalRole,
|
|
205
|
-
createdAt: userData.createdAt,
|
|
206
|
-
updatedAt: userData.updatedAt
|
|
207
|
-
};
|
|
208
|
-
if (!user) {
|
|
209
|
-
throw new Error("User not found");
|
|
210
|
-
}
|
|
211
|
-
let memberProjects = [];
|
|
212
|
-
if (userData.memberProjects && userData.memberProjects.length > 0) {
|
|
213
|
-
const projectKeys = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => membership.project.key);
|
|
214
|
-
if (projectKeys.length > 0) {
|
|
215
|
-
const allProjects = await this._fetchProjectsByKeysInChunks(projectKeys);
|
|
216
|
-
memberProjects = userData.memberProjects.filter((membership) => membership.project && membership.project.key).map((membership) => {
|
|
217
|
-
const projectKey = membership.project.key;
|
|
218
|
-
const correctProject = allProjects.find(
|
|
219
|
-
(p) => p.key === projectKey
|
|
220
|
-
);
|
|
221
|
-
return {
|
|
222
|
-
project: correctProject || membership.project,
|
|
223
|
-
role: membership.role,
|
|
224
|
-
updatedAt: membership.updatedAt,
|
|
225
|
-
createdAt: membership.createdAt
|
|
226
|
-
};
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
} else {
|
|
230
|
-
console.log(`[getUser] No member projects found with ID: ${userId}`);
|
|
231
|
-
}
|
|
232
|
-
const formattedProjects = memberProjects.filter((membership) => membership.project).map((membership) => ({
|
|
233
|
-
id: membership.project.id,
|
|
234
|
-
name: membership.project.name,
|
|
235
|
-
key: membership.project.key,
|
|
236
|
-
thumbnail: membership.project.thumbnail,
|
|
237
|
-
icon: membership.project.icon,
|
|
238
|
-
tier: membership.project.tier,
|
|
239
|
-
visibility: membership.project.visibility,
|
|
240
|
-
access: membership.project.access,
|
|
241
|
-
role: membership.role,
|
|
242
|
-
joinedAt: membership.createdAt,
|
|
243
|
-
updatedAt: membership.updatedAt,
|
|
244
|
-
members: membership.project.members
|
|
245
|
-
})) || [];
|
|
246
|
-
return {
|
|
247
|
-
id: userId,
|
|
248
|
-
name: user.name,
|
|
249
|
-
email: user.email,
|
|
250
|
-
username: user.username,
|
|
251
|
-
globalRole: user.globalRole,
|
|
252
|
-
projects: formattedProjects,
|
|
253
|
-
createdAt: user.createdAt,
|
|
254
|
-
updatedAt: user.updatedAt
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Fetches projects by keys in chunks with adaptive chunk sizing
|
|
259
|
-
* @param {Array<string>} allKeys - All project keys to fetch
|
|
260
|
-
* @returns {Promise<Array>} - All projects found
|
|
261
|
-
*/
|
|
262
|
-
async _fetchProjectsByKeysInChunks(allKeys) {
|
|
263
|
-
if (!allKeys.length) {
|
|
264
|
-
return [];
|
|
265
|
-
}
|
|
266
|
-
const INITIAL_CHUNK_SIZE = 50;
|
|
267
|
-
const MAX_CHUNK_SIZE = 1e3;
|
|
268
|
-
const MIN_CHUNK_SIZE = 10;
|
|
269
|
-
const optimalChunkSize = INITIAL_CHUNK_SIZE;
|
|
270
|
-
const processChunks = async (keys, size) => {
|
|
271
|
-
if (!keys.length) {
|
|
272
|
-
return [];
|
|
273
|
-
}
|
|
274
|
-
const chunks = [];
|
|
275
|
-
for (let i = 0; i < keys.length; i += size) {
|
|
276
|
-
chunks.push(keys.slice(i, i + size));
|
|
277
|
-
}
|
|
278
|
-
try {
|
|
279
|
-
const result = await this._client.query("db", (0, import_basedQuerys.buildGetProjectsByKeysQuery)(chunks[0])).get();
|
|
280
|
-
const newSize = Math.min(Math.floor(size * 1.5), MAX_CHUNK_SIZE);
|
|
281
|
-
const firstChunkProjects = result.projects || [];
|
|
282
|
-
const remainingKeys = keys.slice(chunks[0].length);
|
|
283
|
-
const remainingProjects = await processChunks(remainingKeys, newSize);
|
|
284
|
-
return [...firstChunkProjects, ...remainingProjects];
|
|
285
|
-
} catch (error) {
|
|
286
|
-
if (error.message && error.message.includes("PayloadTooLarge")) {
|
|
287
|
-
const newSize = Math.max(Math.floor(size / 2), MIN_CHUNK_SIZE);
|
|
288
|
-
console.warn(`Reducing chunk size to ${newSize} due to PayloadTooLarge error`);
|
|
289
|
-
if (newSize === MIN_CHUNK_SIZE && chunks[0].length <= MIN_CHUNK_SIZE) {
|
|
290
|
-
console.error(`Cannot process chunk, skipping ${chunks[0].length} keys`);
|
|
291
|
-
const remainingKeys2 = keys.slice(chunks[0].length);
|
|
292
|
-
return processChunks(remainingKeys2, newSize);
|
|
293
|
-
}
|
|
294
|
-
return processChunks(keys, newSize);
|
|
295
|
-
}
|
|
296
|
-
console.error(`Error fetching projects: ${error.message}`);
|
|
297
|
-
const remainingKeys = keys.slice(chunks[0].length);
|
|
298
|
-
return processChunks(remainingKeys, size);
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
return await processChunks(allKeys, optimalChunkSize);
|
|
302
|
-
}
|
|
303
|
-
async getUserByEmail(email) {
|
|
304
|
-
this._requireReady();
|
|
305
|
-
if (!email) {
|
|
306
|
-
throw new Error("Email is required");
|
|
307
|
-
}
|
|
308
|
-
try {
|
|
309
|
-
return await this.call("users:get-by", { email });
|
|
310
|
-
} catch (error) {
|
|
311
|
-
throw new Error(`Failed to get user: ${error.message}`);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
async setProjectDomains(projectId, domains) {
|
|
315
|
-
this._requireReady();
|
|
316
|
-
if (!projectId) {
|
|
317
|
-
throw new Error("Project ID is required");
|
|
318
|
-
}
|
|
319
|
-
try {
|
|
320
|
-
return await this.call("projects:update-domains", { projectId, domains });
|
|
321
|
-
} catch (error) {
|
|
322
|
-
throw new Error(`Failed to set project domains: ${error.message}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
async checkProjectKeyAvailability(key) {
|
|
326
|
-
this._requireReady();
|
|
327
|
-
try {
|
|
328
|
-
return await this.call("projects:check-key", { key });
|
|
329
|
-
} catch (error) {
|
|
330
|
-
throw new Error(
|
|
331
|
-
`Failed to check project key availability: ${error.message}`
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
async removeProject(projectId) {
|
|
336
|
-
this._requireReady();
|
|
337
|
-
if (!projectId) {
|
|
338
|
-
throw new Error("Project ID is required");
|
|
339
|
-
}
|
|
340
|
-
try {
|
|
341
|
-
return await this.call("projects:remove", { projectId });
|
|
342
|
-
} catch (error) {
|
|
343
|
-
throw new Error(`Failed to remove project: ${error.message}`);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
async getAvailableLibraries(params) {
|
|
347
|
-
this._requireReady();
|
|
348
|
-
const defaultParams = {
|
|
349
|
-
page: 1,
|
|
350
|
-
limit: 20,
|
|
351
|
-
search: "",
|
|
352
|
-
framework: "",
|
|
353
|
-
language: ""
|
|
354
|
-
};
|
|
355
|
-
try {
|
|
356
|
-
return await this.call("projects:get-available-libraries", {
|
|
357
|
-
...defaultParams,
|
|
358
|
-
...params
|
|
359
|
-
});
|
|
360
|
-
} catch (error) {
|
|
361
|
-
throw new Error(`Failed to get available libraries: ${error.message}`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
async addProjectLibraries(projectId, libraryIds) {
|
|
365
|
-
this._requireReady();
|
|
366
|
-
if (!projectId) {
|
|
367
|
-
throw new Error("Project ID is required");
|
|
368
|
-
}
|
|
369
|
-
try {
|
|
370
|
-
return await this.call("projects:add-libraries", {
|
|
371
|
-
projectId,
|
|
372
|
-
libraryIds
|
|
373
|
-
});
|
|
374
|
-
} catch (error) {
|
|
375
|
-
throw new Error(`Failed to add project libraries: ${error.message}`);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
async removeProjectLibraries(projectId, libraryIds) {
|
|
379
|
-
this._requireReady();
|
|
380
|
-
if (!projectId) {
|
|
381
|
-
throw new Error("Project ID is required");
|
|
382
|
-
}
|
|
383
|
-
try {
|
|
384
|
-
return await this.call("projects:remove-libraries", {
|
|
385
|
-
projectId,
|
|
386
|
-
libraryIds
|
|
387
|
-
});
|
|
388
|
-
} catch (error) {
|
|
389
|
-
throw new Error(`Failed to remove project libraries: ${error.message}`);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
async getProjectLibraries(projectId) {
|
|
393
|
-
this._requireReady();
|
|
394
|
-
if (!projectId) {
|
|
395
|
-
throw new Error("Project ID is required");
|
|
396
|
-
}
|
|
397
|
-
try {
|
|
398
|
-
return await this.call("projects:get-libraries", { projectId });
|
|
399
|
-
} catch (error) {
|
|
400
|
-
throw new Error(`Failed to get project libraries: ${error.message}`);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
subscribe(collection, query, callback, options = {}) {
|
|
404
|
-
this._requireReady();
|
|
405
|
-
const subscriptionKey = JSON.stringify({ collection, query });
|
|
406
|
-
if (this._subscriptions.has(subscriptionKey)) {
|
|
407
|
-
return this._subscriptions.get(subscriptionKey);
|
|
408
|
-
}
|
|
409
|
-
try {
|
|
410
|
-
const unsubscribe = this._client.query(collection, query, {
|
|
411
|
-
...options,
|
|
412
|
-
context: this._context
|
|
413
|
-
}).subscribe(callback);
|
|
414
|
-
this._subscriptions.set(subscriptionKey, unsubscribe);
|
|
415
|
-
return () => {
|
|
416
|
-
unsubscribe();
|
|
417
|
-
this._subscriptions.delete(subscriptionKey);
|
|
418
|
-
};
|
|
419
|
-
} catch (error) {
|
|
420
|
-
throw new Error(`Subscription failed: ${error.message}`);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
subscribeChannel(name, params, callback) {
|
|
424
|
-
this._requireReady();
|
|
425
|
-
try {
|
|
426
|
-
return this._client.channel(name, params).subscribe(callback);
|
|
427
|
-
} catch (error) {
|
|
428
|
-
throw new Error(`Channel subscription failed: ${error.message}`);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
publishToChannel(name, params, data) {
|
|
432
|
-
this._requireReady();
|
|
433
|
-
try {
|
|
434
|
-
return this._client.channel(name, params).publish(data);
|
|
435
|
-
} catch (error) {
|
|
436
|
-
throw new Error(`Channel publish failed: ${error.message}`);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
async call(functionName, params = {}) {
|
|
440
|
-
this._requireReady();
|
|
441
|
-
try {
|
|
442
|
-
return await this._client.call(functionName, params);
|
|
443
|
-
} catch (error) {
|
|
444
|
-
throw new Error(`Function call failed: ${error.message}`);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
async updateSchema(schema) {
|
|
448
|
-
this._requireReady();
|
|
449
|
-
try {
|
|
450
|
-
return await this._client.call("db:update-schema", schema);
|
|
451
|
-
} catch (error) {
|
|
452
|
-
throw new Error(`Schema update failed: ${error.message}`);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
async createProject(projectData) {
|
|
456
|
-
this._requireReady();
|
|
457
|
-
try {
|
|
458
|
-
return await this.call("projects:create", projectData);
|
|
459
|
-
} catch (error) {
|
|
460
|
-
throw new Error(`Failed to create project: ${error.message}`);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
async getProject(projectId) {
|
|
464
|
-
this._requireReady();
|
|
465
|
-
if (!projectId) {
|
|
466
|
-
throw new Error("Project ID is required");
|
|
467
|
-
}
|
|
468
|
-
try {
|
|
469
|
-
return await this._client.query("db", (0, import_basedQuerys.buildGetProjectDataQuery)(projectId)).get();
|
|
470
|
-
} catch (error) {
|
|
471
|
-
throw new Error(`Failed to get project: ${error.message}`);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
async getProjectByKey(key) {
|
|
475
|
-
this._requireReady();
|
|
476
|
-
try {
|
|
477
|
-
return await this._client.query("db", (0, import_basedQuerys.buildGetProjectByKeyDataQuery)(key)).get();
|
|
478
|
-
} catch (error) {
|
|
479
|
-
throw new Error(`Failed to get project by key: ${error.message}`);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
// DEPRECATED
|
|
483
|
-
async fetchProject(projectId) {
|
|
484
|
-
this._requireReady();
|
|
485
|
-
if (!projectId) {
|
|
486
|
-
throw new Error("Project ID is required");
|
|
487
|
-
}
|
|
488
|
-
return await this.query("db", (0, import_basedQuerys.buildProjectQuery)(projectId));
|
|
489
|
-
}
|
|
490
|
-
async chooseProject({
|
|
491
|
-
username = ((_a) => (_a = this._context.user) == null ? void 0 : _a.username)(),
|
|
492
|
-
projectId,
|
|
493
|
-
activeProject
|
|
494
|
-
}) {
|
|
495
|
-
this._requireReady();
|
|
496
|
-
try {
|
|
497
|
-
await this.call("fetchProject", {
|
|
498
|
-
username,
|
|
499
|
-
projectId,
|
|
500
|
-
activeProject
|
|
501
|
-
});
|
|
502
|
-
await this._client.call("setCookie", "activeProject", activeProject);
|
|
503
|
-
} catch (error) {
|
|
504
|
-
throw new Error(`Failed to choose project: ${error.message}`);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
destroy() {
|
|
508
|
-
for (const unsubscribe of this._subscriptions.values()) {
|
|
509
|
-
unsubscribe();
|
|
510
|
-
}
|
|
511
|
-
this._subscriptions.clear();
|
|
512
|
-
this._client = null;
|
|
513
|
-
this._setReady(false);
|
|
514
|
-
}
|
|
515
|
-
// New helper methods for state management
|
|
516
|
-
async updateState(changes) {
|
|
517
|
-
if (!changes || Object.keys(changes).length === 0) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
try {
|
|
521
|
-
await this._client.call("state:update", changes);
|
|
522
|
-
} catch (error) {
|
|
523
|
-
throw new Error(`Failed to update state: ${error.message}`);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
async getState() {
|
|
527
|
-
try {
|
|
528
|
-
return await this._client.call("state:get");
|
|
529
|
-
} catch (error) {
|
|
530
|
-
throw new Error(`Failed to get state: ${error.message}`);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Upload a file to the database
|
|
535
|
-
* @param {File} file - The file to upload
|
|
536
|
-
* @param {Object} options - The options for the upload
|
|
537
|
-
* @returns {Promise<string>} The source of the uploaded file
|
|
538
|
-
* @example
|
|
539
|
-
* const fileInput = document.querySelector('input[type="file"]')
|
|
540
|
-
* const file = fileInput.files[0]
|
|
541
|
-
* const { id, src } = await basedService.uploadFile(file)
|
|
542
|
-
*/
|
|
543
|
-
async uploadFile(file, options = {}) {
|
|
544
|
-
this._requireReady();
|
|
545
|
-
if (!file) {
|
|
546
|
-
throw new Error("File is required for upload");
|
|
547
|
-
}
|
|
548
|
-
try {
|
|
549
|
-
const { id, src } = await this._client.stream("db:file-upload", {
|
|
550
|
-
contents: file,
|
|
551
|
-
...options
|
|
552
|
-
});
|
|
553
|
-
return { id, src };
|
|
554
|
-
} catch (error) {
|
|
555
|
-
throw new Error(`File upload failed: ${error.message}`);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
async checkout({
|
|
559
|
-
projectId,
|
|
560
|
-
pkg = 2,
|
|
561
|
-
seats = 1,
|
|
562
|
-
interval = "monthly",
|
|
563
|
-
plan = "startup",
|
|
564
|
-
successUrl = `${window.location.origin}/success`,
|
|
565
|
-
cancelUrl = `${window.location.origin}/pricing`
|
|
566
|
-
}) {
|
|
567
|
-
this._requireReady();
|
|
568
|
-
const prices = {
|
|
569
|
-
999: { startup: "unlimited_startup", agency: "unlimited_agency" },
|
|
570
|
-
2: { monthly: "starter_monthly", yearly: "starter_yearly" },
|
|
571
|
-
3: { monthly: "growth_monthly", yearly: "growth_yearly" }
|
|
572
|
-
};
|
|
573
|
-
if (!projectId) {
|
|
574
|
-
throw new Error("Project ID is required for checkout");
|
|
575
|
-
}
|
|
576
|
-
if (!prices[pkg]) {
|
|
577
|
-
throw new Error(`Invalid package type: ${pkg}`);
|
|
578
|
-
}
|
|
579
|
-
try {
|
|
580
|
-
const price = prices[pkg][interval] || prices[pkg][plan];
|
|
581
|
-
if (!price) {
|
|
582
|
-
throw new Error(`Invalid interval/plan combination for package ${pkg}`);
|
|
583
|
-
}
|
|
584
|
-
return await this.call("checkout", {
|
|
585
|
-
price,
|
|
586
|
-
seats,
|
|
587
|
-
projectId,
|
|
588
|
-
successUrl,
|
|
589
|
-
cancelUrl
|
|
590
|
-
});
|
|
591
|
-
} catch (error) {
|
|
592
|
-
throw new Error(`Failed to checkout: ${error.message}`);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
async updateProject(projectId, data) {
|
|
596
|
-
this._requireReady();
|
|
597
|
-
try {
|
|
598
|
-
return await this.call("projects:update", { projectId, data });
|
|
599
|
-
} catch (error) {
|
|
600
|
-
throw new Error(`Failed to update project: ${error.message}`);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
async updateProjectComponents(projectId, components) {
|
|
604
|
-
this._requireReady();
|
|
605
|
-
try {
|
|
606
|
-
return await this.call("projects:update-components", {
|
|
607
|
-
projectId,
|
|
608
|
-
components
|
|
609
|
-
});
|
|
610
|
-
} catch (error) {
|
|
611
|
-
throw new Error(`Failed to update project components: ${error.message}`);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
async updateProjectSettings(projectId, settings) {
|
|
615
|
-
this._requireReady();
|
|
616
|
-
try {
|
|
617
|
-
return await this.call("projects:update-settings", {
|
|
618
|
-
projectId,
|
|
619
|
-
settings
|
|
620
|
-
});
|
|
621
|
-
} catch (error) {
|
|
622
|
-
throw new Error(`Failed to update project settings: ${error.message}`);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
async updateProjectName(projectId, name) {
|
|
626
|
-
this._requireReady();
|
|
627
|
-
try {
|
|
628
|
-
return await this.call("projects:update", { projectId, name });
|
|
629
|
-
} catch (error) {
|
|
630
|
-
throw new Error(`Failed to update project name: ${error.message}`);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
async updateProjectPackage(projectId, pkg) {
|
|
634
|
-
this._requireReady();
|
|
635
|
-
try {
|
|
636
|
-
return await this.call("projects:update", {
|
|
637
|
-
projectId,
|
|
638
|
-
data: { package: pkg }
|
|
639
|
-
});
|
|
640
|
-
} catch (error) {
|
|
641
|
-
throw new Error(`Failed to update project package: ${error.message}`);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Update the icon of a project
|
|
646
|
-
* @param {string} projectId - The ID of the project to update
|
|
647
|
-
* @param {id, src} icon - The icon to update the project with
|
|
648
|
-
* @returns {Promise<Object>} The updated project
|
|
649
|
-
*/
|
|
650
|
-
async updateProjectIcon(projectId, icon) {
|
|
651
|
-
this._requireReady();
|
|
652
|
-
try {
|
|
653
|
-
return await this.call("projects:update", {
|
|
654
|
-
projectId,
|
|
655
|
-
data: {
|
|
656
|
-
icon: {
|
|
657
|
-
$id: icon.id,
|
|
658
|
-
src: icon.src
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
} catch (error) {
|
|
663
|
-
throw new Error(`Failed to update project icon: ${error.message}`);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
async createDnsRecord(domain) {
|
|
667
|
-
this._requireReady();
|
|
668
|
-
try {
|
|
669
|
-
return await this.call("dns:create-record", { domain });
|
|
670
|
-
} catch (error) {
|
|
671
|
-
throw new Error(`Failed to create DNS record: ${error.message}`);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
async getDnsRecord(domain) {
|
|
675
|
-
this._requireReady();
|
|
676
|
-
try {
|
|
677
|
-
return await this.call("dns:get-record", { domain });
|
|
678
|
-
} catch (error) {
|
|
679
|
-
throw new Error(`Failed to get DNS records: ${error.message}`);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
async removeDnsRecord(domain) {
|
|
683
|
-
this._requireReady();
|
|
684
|
-
try {
|
|
685
|
-
return await this.call("dns:remove-record", { domain });
|
|
686
|
-
} catch (error) {
|
|
687
|
-
throw new Error(`Failed to delete DNS record: ${error.message}`);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
async createStorageBucket(key) {
|
|
691
|
-
this._requireReady();
|
|
692
|
-
try {
|
|
693
|
-
const randomString = Math.random().toString(36).slice(2, 15);
|
|
694
|
-
const bucket = `symbols-bucket-${key}-${randomString}`;
|
|
695
|
-
return await this.call("storage:create-bucket", {
|
|
696
|
-
bucketName: bucket,
|
|
697
|
-
clientName: key.split(".")[0]
|
|
698
|
-
});
|
|
699
|
-
} catch (error) {
|
|
700
|
-
throw new Error(`Failed to create storage bucket: ${error.message}`);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
async getStorageBucket(bucketName) {
|
|
704
|
-
this._requireReady();
|
|
705
|
-
try {
|
|
706
|
-
return await this.call("storage:get-bucket", { bucketName });
|
|
707
|
-
} catch (error) {
|
|
708
|
-
throw new Error(`Failed to get storage bucket: ${error.message}`);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
async removeStorageBucket(bucketName) {
|
|
712
|
-
this._requireReady();
|
|
713
|
-
try {
|
|
714
|
-
return await this.call("storage:remove-bucket", { bucketName });
|
|
715
|
-
} catch (error) {
|
|
716
|
-
throw new Error(`Failed to remove storage bucket: ${error.message}`);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Request a password change
|
|
721
|
-
* @returns {Promise<boolean>} True if the request was successful, false otherwise
|
|
722
|
-
*/
|
|
723
|
-
async requestPasswordChange() {
|
|
724
|
-
this._requireReady();
|
|
725
|
-
try {
|
|
726
|
-
return await this.call("users:request-password-change", {});
|
|
727
|
-
} catch (error) {
|
|
728
|
-
throw new Error(`Failed to request password change: ${error.message}`);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Confirm a password change
|
|
733
|
-
* @param {string} verificationCode - The verification code
|
|
734
|
-
* @param {string} newPassword - The new password
|
|
735
|
-
* @param {string} confirmPassword - The confirmation password
|
|
736
|
-
* @returns {Promise<boolean>} True if the password was changed, false otherwise
|
|
737
|
-
*/
|
|
738
|
-
async confirmPasswordChange(verificationCode, newPassword, confirmPassword) {
|
|
739
|
-
try {
|
|
740
|
-
return await this.call("users:confirm-password-change", {
|
|
741
|
-
verificationCode,
|
|
742
|
-
newPassword,
|
|
743
|
-
confirmPassword
|
|
744
|
-
});
|
|
745
|
-
} catch (error) {
|
|
746
|
-
throw new Error(`Failed to confirm password change: ${error.message}`);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
async updateUserProfile(profileData) {
|
|
750
|
-
this._requireReady();
|
|
751
|
-
try {
|
|
752
|
-
return await this.call("users:update-profile", profileData);
|
|
753
|
-
} catch (error) {
|
|
754
|
-
throw new Error(`Failed to update user profile: ${error.message}`);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Duplicate a project
|
|
759
|
-
* @param {string} projectId - The ID of the project to duplicate
|
|
760
|
-
* @param {string} newName - The new name of the project (optional)
|
|
761
|
-
* @param {string} newKey - The new key of the project (optional)
|
|
762
|
-
* @returns {Promise<Object>} The duplicated project
|
|
763
|
-
*/
|
|
764
|
-
async duplicateProject(projectId, newName, newKey, targetUserId) {
|
|
765
|
-
this._requireReady();
|
|
766
|
-
try {
|
|
767
|
-
return await this.call("projects:duplicate", {
|
|
768
|
-
projectId,
|
|
769
|
-
newName,
|
|
770
|
-
newKey,
|
|
771
|
-
targetUserId
|
|
772
|
-
});
|
|
773
|
-
} catch (error) {
|
|
774
|
-
throw new Error(`Failed to duplicate project: ${error.message}`);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* List available subscription plans
|
|
779
|
-
* @param {Object} options - Options for filtering plans
|
|
780
|
-
* @param {number} options.page - Page number (default: 1)
|
|
781
|
-
* @param {number} options.limit - Number of plans per page (default: 20)
|
|
782
|
-
* @param {string} options.status - Filter plans by status (admin only)
|
|
783
|
-
* @param {boolean} options.includeSubscriptionCounts - Include subscription counts (admin only)
|
|
784
|
-
* @param {string} options.sortBy - Field to sort by (default: 'displayOrder')
|
|
785
|
-
* @param {string} options.sortOrder - Sort order ('asc' or 'desc', default: 'asc')
|
|
786
|
-
* @returns {Promise<Object>} List of plans with pagination info
|
|
787
|
-
*/
|
|
788
|
-
async listPlans(options = {}) {
|
|
789
|
-
this._requireReady();
|
|
790
|
-
try {
|
|
791
|
-
return await this.call("plans:list", options);
|
|
792
|
-
} catch (error) {
|
|
793
|
-
throw new Error(`Failed to list plans: ${error.message}`);
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* Subscribe to a plan
|
|
798
|
-
* @param {string} planId - ID of the plan to subscribe to
|
|
799
|
-
* @param {Object} options - Options for the subscription
|
|
800
|
-
* @param {string} options.paymentMethod - Payment method
|
|
801
|
-
* @param {Object} options.billingAddress - Billing address
|
|
802
|
-
* @param {string} options.stripeCustomerId - Stripe customer ID
|
|
803
|
-
* @param {string} options.stripeSubscriptionId - Stripe subscription ID
|
|
804
|
-
* @returns {Promise<Object>} Subscription details
|
|
805
|
-
*/
|
|
806
|
-
async subscribeToPlan(planId, options = {}) {
|
|
807
|
-
this._requireReady();
|
|
808
|
-
try {
|
|
809
|
-
return await this.call("subscriptions:create", { planId, ...options });
|
|
810
|
-
} catch (error) {
|
|
811
|
-
throw new Error(`Failed to subscribe to plan: ${error.message}`);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
/**
|
|
815
|
-
* Get details of user's current subscription
|
|
816
|
-
* @param {string} subscriptionId - ID of the subscription to get details for
|
|
817
|
-
* @returns {Promise<Object>} Subscription details
|
|
818
|
-
*/
|
|
819
|
-
async getSubscriptionDetails(subscriptionId) {
|
|
820
|
-
this._requireReady();
|
|
821
|
-
try {
|
|
822
|
-
return await this.call("subscriptions:details", {
|
|
823
|
-
subscriptionId
|
|
824
|
-
});
|
|
825
|
-
} catch (error) {
|
|
826
|
-
throw new Error(`Failed to get subscription details: ${error.message}`);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Check if the current subscription is active
|
|
831
|
-
* @param {string} subscriptionId - ID of the subscription to check
|
|
832
|
-
* @returns {Promise<Object>} Subscription status info
|
|
833
|
-
*/
|
|
834
|
-
async checkSubscriptionStatus(subscriptionId) {
|
|
835
|
-
this._requireReady();
|
|
836
|
-
try {
|
|
837
|
-
return await this.call("subscriptions:check-status", {
|
|
838
|
-
subscriptionId
|
|
839
|
-
});
|
|
840
|
-
} catch (error) {
|
|
841
|
-
throw new Error(`Failed to check subscription status: ${error.message}`);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
/**
|
|
845
|
-
* Upgrade the current subscription to a new plan
|
|
846
|
-
* @param {string} planId - ID of the plan to upgrade to
|
|
847
|
-
* @param {string} stripeSubscriptionId - ID of the Stripe subscription to upgrade
|
|
848
|
-
* @returns {Promise<Object>} Updated subscription details
|
|
849
|
-
*/
|
|
850
|
-
async upgradeSubscription(planId, stripeSubscriptionId) {
|
|
851
|
-
this._requireReady();
|
|
852
|
-
try {
|
|
853
|
-
return await this.call("subscriptions:upgrade", {
|
|
854
|
-
planId,
|
|
855
|
-
stripeSubscriptionId
|
|
856
|
-
});
|
|
857
|
-
} catch (error) {
|
|
858
|
-
throw new Error(`Failed to upgrade subscription: ${error.message}`);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
/**
|
|
862
|
-
* Downgrade the current subscription to a new plan
|
|
863
|
-
* @param {string} planId - ID of the plan to downgrade to
|
|
864
|
-
* @param {boolean} applyImmediately - Whether to apply the downgrade immediately
|
|
865
|
-
* @param {string} stripeSubscriptionId - ID of the Stripe subscription to downgrade
|
|
866
|
-
* @returns {Promise<Object>} Updated subscription details
|
|
867
|
-
*/
|
|
868
|
-
async downgradeSubscription(planId, stripeSubscriptionId, applyImmediately = false) {
|
|
869
|
-
this._requireReady();
|
|
870
|
-
try {
|
|
871
|
-
return await this.call("subscriptions:downgrade", {
|
|
872
|
-
planId,
|
|
873
|
-
applyImmediately,
|
|
874
|
-
stripeSubscriptionId
|
|
875
|
-
});
|
|
876
|
-
} catch (error) {
|
|
877
|
-
throw new Error(`Failed to downgrade subscription: ${error.message}`);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Cancel the current subscription
|
|
882
|
-
* @param {boolean} cancelImmediately - Whether to cancel immediately or at period end
|
|
883
|
-
* @param {string} reason - Reason for cancellation
|
|
884
|
-
* @returns {Promise<Object>} Result of cancellation
|
|
885
|
-
*/
|
|
886
|
-
async cancelSubscription(cancelImmediately = false, reason = "") {
|
|
887
|
-
this._requireReady();
|
|
888
|
-
try {
|
|
889
|
-
return await this.call("subscriptions:cancel", {
|
|
890
|
-
cancelImmediately,
|
|
891
|
-
reason
|
|
892
|
-
});
|
|
893
|
-
} catch (error) {
|
|
894
|
-
throw new Error(`Failed to cancel subscription: ${error.message}`);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
/**
|
|
898
|
-
* Reactivate a subscription that was scheduled for cancellation
|
|
899
|
-
* @returns {Promise<Object>} Updated subscription details
|
|
900
|
-
*/
|
|
901
|
-
async reactivateSubscription(stripeSubscriptionId) {
|
|
902
|
-
this._requireReady();
|
|
903
|
-
try {
|
|
904
|
-
return await this.call("subscriptions:reactivate", {
|
|
905
|
-
stripeSubscriptionId
|
|
906
|
-
});
|
|
907
|
-
} catch (error) {
|
|
908
|
-
throw new Error(`Failed to reactivate subscription: ${error.message}`);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
/**
|
|
912
|
-
* Generate an invoice for the current subscription
|
|
913
|
-
* @param {string} subscriptionId - ID of the subscription to generate the invoice for
|
|
914
|
-
* @param {boolean} forceGenerate - Whether to force the generation of the invoice
|
|
915
|
-
* @param {Array} customItems - Custom items to add to the invoice
|
|
916
|
-
* @returns {Promise<Object>} Generated invoice
|
|
917
|
-
*/
|
|
918
|
-
async generateInvoice(subscriptionId, forceGenerate = false, customItems = []) {
|
|
919
|
-
this._requireReady();
|
|
920
|
-
try {
|
|
921
|
-
return await this.call("billing:generate-invoice", {
|
|
922
|
-
subscriptionId,
|
|
923
|
-
forceGenerate,
|
|
924
|
-
customItems
|
|
925
|
-
});
|
|
926
|
-
} catch (error) {
|
|
927
|
-
throw new Error(`Failed to generate invoice: ${error.message}`);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
/**
|
|
931
|
-
* Get usage report for the current subscription
|
|
932
|
-
* @param {string} subscriptionId - ID of the subscription to get the usage report for
|
|
933
|
-
* @param {boolean} forceRefresh - Whether to force the refresh of the usage report
|
|
934
|
-
* @returns {Promise<Object>} Usage report
|
|
935
|
-
*/
|
|
936
|
-
async getUsageReport(subscriptionId, forceRefresh = false) {
|
|
937
|
-
this._requireReady();
|
|
938
|
-
try {
|
|
939
|
-
return await this.call("subscriptions:get-usage-report", {
|
|
940
|
-
subscriptionId,
|
|
941
|
-
forceRefresh
|
|
942
|
-
});
|
|
943
|
-
} catch (error) {
|
|
944
|
-
throw new Error(`Failed to get usage report: ${error.message}`);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
/**
|
|
948
|
-
* Invite a user to be an account owner for the current subscription
|
|
949
|
-
* @param {string} email - Email of the user to invite
|
|
950
|
-
* @param {string} name - Name of the user to invite
|
|
951
|
-
* @param {string} callbackUrl - URL to redirect the user to after accepting the invitation
|
|
952
|
-
* @returns {Promise<Object>} Result of invitation
|
|
953
|
-
*/
|
|
954
|
-
async inviteAccountOwner(email, name, callbackUrl) {
|
|
955
|
-
this._requireReady();
|
|
956
|
-
try {
|
|
957
|
-
return await this.call("subscriptions:invite", {
|
|
958
|
-
email,
|
|
959
|
-
name,
|
|
960
|
-
callbackUrl
|
|
961
|
-
});
|
|
962
|
-
} catch (error) {
|
|
963
|
-
throw new Error(`Failed to invite account owner: ${error.message}`);
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
/**
|
|
967
|
-
* Accept an invitation to become an account owner
|
|
968
|
-
* @param {string} token - Invitation token
|
|
969
|
-
* @returns {Promise<Object>} Result of accepting invitation
|
|
970
|
-
*/
|
|
971
|
-
async acceptOwnerInvitation(token) {
|
|
972
|
-
this._requireReady();
|
|
973
|
-
try {
|
|
974
|
-
return await this.call("subscriptions:accept-owner-invitation", {
|
|
975
|
-
token
|
|
976
|
-
});
|
|
977
|
-
} catch (error) {
|
|
978
|
-
throw new Error(`Failed to accept owner invitation: ${error.message}`);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Remove an account owner from the current subscription
|
|
983
|
-
* @param {string} userId - ID of the user to remove
|
|
984
|
-
* @returns {Promise<Object>} Result of removal
|
|
985
|
-
*/
|
|
986
|
-
async removeAccountOwner(userId) {
|
|
987
|
-
this._requireReady();
|
|
988
|
-
try {
|
|
989
|
-
return await this.call("subscriptions:remove-account-owner", {
|
|
990
|
-
targetUserId: userId
|
|
991
|
-
});
|
|
992
|
-
} catch (error) {
|
|
993
|
-
throw new Error(`Failed to remove account owner: ${error.message}`);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Check if a resource limit has been reached
|
|
998
|
-
* @param {string} resourceType - Type of resource to check
|
|
999
|
-
* @param {string} projectId - ID of the project to check the resource limit for
|
|
1000
|
-
* @param {number} quantity - Amount being requested
|
|
1001
|
-
* @param {string} userId - ID of user to check (admin only, defaults to current user)
|
|
1002
|
-
* @returns {Promise<Object>} Result of check
|
|
1003
|
-
*/
|
|
1004
|
-
async checkResourceLimit(resourceType, projectId, quantity = 1, userId = "") {
|
|
1005
|
-
this._requireReady();
|
|
1006
|
-
try {
|
|
1007
|
-
return await this.call("subscriptions:check-resource-limit", {
|
|
1008
|
-
resourceType,
|
|
1009
|
-
projectId,
|
|
1010
|
-
quantity,
|
|
1011
|
-
userId
|
|
1012
|
-
});
|
|
1013
|
-
} catch (error) {
|
|
1014
|
-
throw new Error(`Failed to check resource limit: ${error.message}`);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
/**
|
|
1018
|
-
* Check if a user has access to a feature
|
|
1019
|
-
* @param {string} featureKey - Key of the feature to check
|
|
1020
|
-
* @param {string} userId - ID of user to check (admin only, defaults to current user)
|
|
1021
|
-
* @returns {Promise<Object>} Access check result
|
|
1022
|
-
*/
|
|
1023
|
-
async checkFeatureAccess(featureKey, userId) {
|
|
1024
|
-
this._requireReady();
|
|
1025
|
-
try {
|
|
1026
|
-
return await this.call("features:check-access", {
|
|
1027
|
-
featureKey,
|
|
1028
|
-
userId
|
|
1029
|
-
});
|
|
1030
|
-
} catch (error) {
|
|
1031
|
-
throw new Error(`Failed to check feature access: ${error.message}`);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Get all features available to the current user
|
|
1036
|
-
* @returns {Promise<Object>} Available features
|
|
1037
|
-
*/
|
|
1038
|
-
async getUserFeatures() {
|
|
1039
|
-
this._requireReady();
|
|
1040
|
-
try {
|
|
1041
|
-
return await this.call("subscriptions:get-user-features", {});
|
|
1042
|
-
} catch (error) {
|
|
1043
|
-
throw new Error(`Failed to get user features: ${error.message}`);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
/**
|
|
1047
|
-
* Get all available features across all plans
|
|
1048
|
-
* @param {string} subscriptionId - ID of the subscription to get the available features for
|
|
1049
|
-
* @param {string} userId - ID of user to get the available features for (admin only, defaults to current user)
|
|
1050
|
-
* @param {boolean} includeDetails - Whether to include details about the features
|
|
1051
|
-
* @returns {Promise<Object>} Available features
|
|
1052
|
-
*/
|
|
1053
|
-
async getAvailableFeatures(subscriptionId, userId = "", includeDetails = false) {
|
|
1054
|
-
this._requireReady();
|
|
1055
|
-
try {
|
|
1056
|
-
return await this.call("features:get-available", {
|
|
1057
|
-
subscriptionId,
|
|
1058
|
-
userId,
|
|
1059
|
-
includeDetails
|
|
1060
|
-
});
|
|
1061
|
-
} catch (error) {
|
|
1062
|
-
throw new Error(`Failed to get available features: ${error.message}`);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
/**
|
|
1066
|
-
* List all feature flags (admin only)
|
|
1067
|
-
* @param {Object} options - Options for listing feature flags
|
|
1068
|
-
* @param {number} options.page - Page number
|
|
1069
|
-
* @param {number} options.limit - Number of items per page
|
|
1070
|
-
* @param {string} options.status - Filter by status
|
|
1071
|
-
* @returns {Promise<Object>} List of feature flags
|
|
1072
|
-
*/
|
|
1073
|
-
async listFeatureFlags(options = {}) {
|
|
1074
|
-
this._requireReady();
|
|
1075
|
-
try {
|
|
1076
|
-
return await this.call("features:list", options);
|
|
1077
|
-
} catch (error) {
|
|
1078
|
-
throw new Error(`Failed to list feature flags: ${error.message}`);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
/**
|
|
1082
|
-
* Update a feature flag (admin only)
|
|
1083
|
-
* @param {string} flagId - ID of the feature flag to update
|
|
1084
|
-
* @param {Object} options - Update data
|
|
1085
|
-
* @param {string} options.key - Key of the feature flag
|
|
1086
|
-
* @param {string} options.name - Name of the feature flag
|
|
1087
|
-
* @param {string} options.description - Description of the feature flag
|
|
1088
|
-
* @param {string} options.defaultValue - Default value of the feature flag
|
|
1089
|
-
* @param {Object} options.planOverrides - Plan overrides for the feature flag
|
|
1090
|
-
* @param {Object} options.userOverrides - User overrides for the feature flag
|
|
1091
|
-
* @param {string} options.status - Status of the feature flag
|
|
1092
|
-
* @returns {Promise<Object>} Updated feature flag
|
|
1093
|
-
*/
|
|
1094
|
-
async updateFeatureFlag(flagId, options) {
|
|
1095
|
-
this._requireReady();
|
|
1096
|
-
try {
|
|
1097
|
-
return await this.call("features:update", {
|
|
1098
|
-
flagId,
|
|
1099
|
-
...options
|
|
1100
|
-
});
|
|
1101
|
-
} catch (error) {
|
|
1102
|
-
throw new Error(`Failed to update feature flag: ${error.message}`);
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
/**
|
|
1106
|
-
* Remove a feature flag (admin only)
|
|
1107
|
-
* @param {string} flagId - ID of the feature flag to remove
|
|
1108
|
-
* @returns {Promise<Object>} Result of removal
|
|
1109
|
-
*/
|
|
1110
|
-
async removeFeatureFlag(flagId) {
|
|
1111
|
-
this._requireReady();
|
|
1112
|
-
try {
|
|
1113
|
-
return await this.call("features:remove", {
|
|
1114
|
-
flagId
|
|
1115
|
-
});
|
|
1116
|
-
} catch (error) {
|
|
1117
|
-
throw new Error(`Failed to remove feature flag: ${error.message}`);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
/**
|
|
1121
|
-
* Batch update feature flags (admin only)
|
|
1122
|
-
* @param {Array} operations - Array of feature flag operations
|
|
1123
|
-
* @param {string} operations.flagId - ID of the feature flag to update
|
|
1124
|
-
* @param {string} operations.key - Key of the feature flag
|
|
1125
|
-
* @param {string} operations.name - Name of the feature flag
|
|
1126
|
-
* @param {string} operations.description - Description of the feature flag
|
|
1127
|
-
* @param {boolean} operations.defaultValue - Default value of the feature flag
|
|
1128
|
-
* @param {Object} operations.planOverrides - Plan overrides for the feature flag
|
|
1129
|
-
* @param {Object} operations.userOverrides - User overrides for the feature flag
|
|
1130
|
-
* @param {string} operations.status - Status of the feature flag
|
|
1131
|
-
* @returns {Promise<Object>} Result of batch update
|
|
1132
|
-
*/
|
|
1133
|
-
async batchUpdateFeatureFlags(operations) {
|
|
1134
|
-
this._requireReady();
|
|
1135
|
-
try {
|
|
1136
|
-
return await this.call("features:batch-update", {
|
|
1137
|
-
operations
|
|
1138
|
-
});
|
|
1139
|
-
} catch (error) {
|
|
1140
|
-
throw new Error(`Failed to batch update feature flags: ${error.message}`);
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
/**
|
|
1144
|
-
* Update plan details (admin only)
|
|
1145
|
-
* @param {string} planId - ID of the plan to update
|
|
1146
|
-
* @param {Object} data - Update data
|
|
1147
|
-
* @param {string} data.name - Display name (e.g., "Pro", "Team")
|
|
1148
|
-
* @param {string} data.description - Marketing description
|
|
1149
|
-
* @param {number} data.price - Monthly price in cents
|
|
1150
|
-
* @param {number} data.annualPrice - Annual price in cents (discounted)
|
|
1151
|
-
* @param {number} data.lifetimePrice - One-time lifetime price in cents
|
|
1152
|
-
* @param {string} data.billingType - Payment type
|
|
1153
|
-
* @param {string} data.status - Status
|
|
1154
|
-
* @param {Object} data.features - Detailed feature configuration
|
|
1155
|
-
* @returns {Promise<Object>} Updated plan
|
|
1156
|
-
*/
|
|
1157
|
-
async updatePlanDetails(planId, data) {
|
|
1158
|
-
this._requireReady();
|
|
1159
|
-
try {
|
|
1160
|
-
return await this.call("plans:update-details", {
|
|
1161
|
-
planId,
|
|
1162
|
-
data
|
|
1163
|
-
});
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
throw new Error(`Failed to update plan details: ${error.message}`);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* Update plan status (admin only)
|
|
1170
|
-
* @param {string} planId - ID of the plan to update
|
|
1171
|
-
* @param {string} status - New status
|
|
1172
|
-
* @returns {Promise<Object>} Updated plan
|
|
1173
|
-
*/
|
|
1174
|
-
async updatePlanStatus(planId, status) {
|
|
1175
|
-
this._requireReady();
|
|
1176
|
-
try {
|
|
1177
|
-
return await this.call("plans:update-status", {
|
|
1178
|
-
planId,
|
|
1179
|
-
status
|
|
1180
|
-
});
|
|
1181
|
-
} catch (error) {
|
|
1182
|
-
throw new Error(`Failed to update plan status: ${error.message}`);
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
}
|