@ztimson/momentum 0.51.0 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.d.ts +46 -4
- package/dist/actions.d.ts.map +1 -1
- package/dist/ai.d.ts +20 -2
- package/dist/ai.d.ts.map +1 -1
- package/dist/analytics.d.ts +54 -24
- package/dist/analytics.d.ts.map +1 -1
- package/dist/api.d.ts +31 -8
- package/dist/api.d.ts.map +1 -1
- package/dist/auth.d.ts +103 -4
- package/dist/auth.d.ts.map +1 -1
- package/dist/client.d.ts +24 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/core.d.ts +16 -3
- package/dist/core.d.ts.map +1 -1
- package/dist/data.d.ts +13 -7
- package/dist/data.d.ts.map +1 -1
- package/dist/email.d.ts +16 -5
- package/dist/email.d.ts.map +1 -1
- package/dist/index.cjs +347 -181
- package/dist/index.mjs +347 -181
- package/dist/momentum.d.ts +2 -4
- package/dist/momentum.d.ts.map +1 -1
- package/dist/momentum.worker.js +16 -0
- package/dist/payments.d.ts +55 -4
- package/dist/payments.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -285,7 +285,7 @@ class Cache {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
function blackOrWhite(background) {
|
|
288
|
-
const exploded = background.match(background.length >= 6 ? /\w\w/g : /\w/g);
|
|
288
|
+
const exploded = background == null ? void 0 : background.match(background.length >= 6 ? /\w\w/g : /\w/g);
|
|
289
289
|
if (!exploded) return "black";
|
|
290
290
|
const [r2, g, b2] = exploded.map((hex) => parseInt(hex, 16));
|
|
291
291
|
const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b2) / 255;
|
|
@@ -663,31 +663,13 @@ __publicField2(_Http, "interceptors", {});
|
|
|
663
663
|
__publicField2(_Http, "headers", {});
|
|
664
664
|
let Http = _Http;
|
|
665
665
|
const CliEffects = {
|
|
666
|
-
CLEAR: "\x1B[0m"
|
|
667
|
-
BRIGHT: "\x1B[1m",
|
|
668
|
-
DIM: "\x1B[2m",
|
|
669
|
-
UNDERSCORE: "\x1B[4m",
|
|
670
|
-
BLINK: "\x1B[5m",
|
|
671
|
-
REVERSE: "\x1B[7m",
|
|
672
|
-
HIDDEN: "\x1B[8m"
|
|
666
|
+
CLEAR: "\x1B[0m"
|
|
673
667
|
};
|
|
674
668
|
const CliForeground = {
|
|
675
|
-
BLACK: "\x1B[30m",
|
|
676
669
|
RED: "\x1B[31m",
|
|
677
|
-
GREEN: "\x1B[32m",
|
|
678
670
|
YELLOW: "\x1B[33m",
|
|
679
671
|
BLUE: "\x1B[34m",
|
|
680
|
-
|
|
681
|
-
CYAN: "\x1B[36m",
|
|
682
|
-
LIGHT_GREY: "\x1B[37m",
|
|
683
|
-
GREY: "\x1B[90m",
|
|
684
|
-
LIGHT_RED: "\x1B[91m",
|
|
685
|
-
LIGHT_GREEN: "\x1B[92m",
|
|
686
|
-
LIGHT_YELLOW: "\x1B[93m",
|
|
687
|
-
LIGHT_BLUE: "\x1B[94m",
|
|
688
|
-
LIGHT_MAGENTA: "\x1B[95m",
|
|
689
|
-
LIGHT_CYAN: "\x1B[96m",
|
|
690
|
-
WHITE: "\x1B[97m"
|
|
672
|
+
LIGHT_GREY: "\x1B[37m"
|
|
691
673
|
};
|
|
692
674
|
var LOG_LEVEL = /* @__PURE__ */ ((LOG_LEVEL2) => {
|
|
693
675
|
LOG_LEVEL2[LOG_LEVEL2["ERROR"] = 0] = "ERROR";
|
|
@@ -986,6 +968,7 @@ class Api extends Http {
|
|
|
986
968
|
if (token) this.token = token;
|
|
987
969
|
}
|
|
988
970
|
}
|
|
971
|
+
/** Current API token */
|
|
989
972
|
get token() {
|
|
990
973
|
return this._token;
|
|
991
974
|
}
|
|
@@ -999,12 +982,21 @@ class Api extends Http {
|
|
|
999
982
|
}
|
|
1000
983
|
this.emit(PES`api/token:${token ? "u" : "d"}`, token);
|
|
1001
984
|
}
|
|
985
|
+
/**
|
|
986
|
+
* Fetch current Momentum status
|
|
987
|
+
* @return {Promise<Health>}
|
|
988
|
+
*/
|
|
1002
989
|
healthcheck() {
|
|
1003
990
|
return this.request({ url: "/api/healthcheck" }).then((resp) => {
|
|
1004
991
|
this.emit(PES`api/healthcheck:r`, resp);
|
|
1005
992
|
return resp;
|
|
1006
993
|
});
|
|
1007
994
|
}
|
|
995
|
+
/**
|
|
996
|
+
* Create API request
|
|
997
|
+
* @param {HttpRequestOptions} options Request options
|
|
998
|
+
* @return {Promise} Response
|
|
999
|
+
*/
|
|
1008
1000
|
request(options) {
|
|
1009
1001
|
const key = JSONSanitize(options);
|
|
1010
1002
|
const method = options.method == "GET" ? "r" : options.method == "POST" ? "c" : options.method == "DELETE" ? "d" : "u";
|
|
@@ -1038,6 +1030,11 @@ class Actions extends PathEventEmitter {
|
|
|
1038
1030
|
__publicField(this, "cache", new Cache("_id"));
|
|
1039
1031
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1040
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* All saved actions
|
|
1035
|
+
* @param {boolean} reload Will use cached response if false
|
|
1036
|
+
* @return {Promise<Action[]>} List of saved actions
|
|
1037
|
+
*/
|
|
1041
1038
|
async all(reload) {
|
|
1042
1039
|
if (!reload && this.cache.complete) return this.cache.all();
|
|
1043
1040
|
return this.api.request({ url: `/api/` + PES`actions` }).then((resp) => {
|
|
@@ -1046,6 +1043,11 @@ class Actions extends PathEventEmitter {
|
|
|
1046
1043
|
return resp;
|
|
1047
1044
|
});
|
|
1048
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Delete an existing action
|
|
1048
|
+
* @param {string} id Action ID
|
|
1049
|
+
* @return {Promise<void>} Delete complete
|
|
1050
|
+
*/
|
|
1049
1051
|
delete(id) {
|
|
1050
1052
|
if (!id) throw new Error("Cannot delete action, missing ID");
|
|
1051
1053
|
return this.api.request({ url: `/api/` + PES`actions/${id}`, method: "DELETE" }).then(() => {
|
|
@@ -1053,7 +1055,13 @@ class Actions extends PathEventEmitter {
|
|
|
1053
1055
|
this.emit(PES`actions/${id}:d`, id);
|
|
1054
1056
|
});
|
|
1055
1057
|
}
|
|
1056
|
-
|
|
1058
|
+
/**
|
|
1059
|
+
* Fetch action info
|
|
1060
|
+
* @param {string} id Action ID
|
|
1061
|
+
* @param {boolean} reload Will use cached response if false
|
|
1062
|
+
* @return {Promise<Action | null>} Requested action
|
|
1063
|
+
*/
|
|
1064
|
+
read(id, reload) {
|
|
1057
1065
|
if (!id) throw new Error("Cannot read action, missing ID");
|
|
1058
1066
|
const cached = this.cache.get(id);
|
|
1059
1067
|
if (!reload && cached) return Promise.resolve(cached);
|
|
@@ -1063,15 +1071,20 @@ class Actions extends PathEventEmitter {
|
|
|
1063
1071
|
return action;
|
|
1064
1072
|
});
|
|
1065
1073
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1074
|
+
/**
|
|
1075
|
+
* Manually trigger an actions execution
|
|
1076
|
+
* @param {string} id Action ID
|
|
1077
|
+
* @param {HttpRequestOptions} opts Additional arguments
|
|
1078
|
+
* @return {Promise<ActionResult>} Result of action
|
|
1079
|
+
*/
|
|
1080
|
+
runById(id, opts = {}) {
|
|
1073
1081
|
return this.api.request({ url: "/api/" + PES`actions/run-by-id/${id}`, method: "POST", ...opts });
|
|
1074
1082
|
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Update an action
|
|
1085
|
+
* @param {Action} action The new action
|
|
1086
|
+
* @return {Promise<Action>} Saved action
|
|
1087
|
+
*/
|
|
1075
1088
|
update(action) {
|
|
1076
1089
|
return this.api.request({
|
|
1077
1090
|
url: `/api/` + PES`actions/${action._id}`,
|
|
@@ -1090,6 +1103,12 @@ class Ai extends PathEventEmitter {
|
|
|
1090
1103
|
__publicField(this, "api");
|
|
1091
1104
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1092
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Ask the AI assistant a question
|
|
1108
|
+
* @param {string} question Users question
|
|
1109
|
+
* @param {any} context Additional data to aid response
|
|
1110
|
+
* @return {Promise<string>} AI's response
|
|
1111
|
+
*/
|
|
1093
1112
|
ask(question, context) {
|
|
1094
1113
|
if (!question) throw new Error("Cannot ask AI, missing question");
|
|
1095
1114
|
return this.api.request({ url: `/api/` + PES`ai`, method: "POST", body: {
|
|
@@ -1100,9 +1119,17 @@ class Ai extends PathEventEmitter {
|
|
|
1100
1119
|
return response;
|
|
1101
1120
|
});
|
|
1102
1121
|
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Clear AI assistant memory & context
|
|
1124
|
+
* @return {Promise<void>} Resolves once complete
|
|
1125
|
+
*/
|
|
1103
1126
|
clear() {
|
|
1104
1127
|
return this.api.request({ url: "/api/" + PES`ai`, method: "DELETE" }).then(() => this.emit(PES`ai:d`, this.api.token));
|
|
1105
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Current chat history
|
|
1131
|
+
* @return {Promise<{role: string, content: string}[]>}
|
|
1132
|
+
*/
|
|
1106
1133
|
history() {
|
|
1107
1134
|
return this.api.request({ url: "/api/" + PES`ai` }).then((resp) => {
|
|
1108
1135
|
this.emit(PES`ai:r`, resp);
|
|
@@ -1116,6 +1143,11 @@ class Analytics extends PathEventEmitter {
|
|
|
1116
1143
|
__publicField(this, "api");
|
|
1117
1144
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1118
1145
|
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Perform IP trace
|
|
1148
|
+
* @param {string} ip IP address to trace
|
|
1149
|
+
* @return {Promise<IpTrace>} Trace results
|
|
1150
|
+
*/
|
|
1119
1151
|
ipTrace(ip) {
|
|
1120
1152
|
if (!ip) throw new Error("Cannot trace, missing IP");
|
|
1121
1153
|
return this.api.request({ url: `/api/` + PES`analytics/trace/${ip}` }).then((resp) => {
|
|
@@ -1129,33 +1161,70 @@ class Token extends PathEventEmitter {
|
|
|
1129
1161
|
super();
|
|
1130
1162
|
this.api = api;
|
|
1131
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Fetch all tokens for user
|
|
1166
|
+
* @param {string} username User to search
|
|
1167
|
+
* @return {Promise<UserToken[]>} List of tokens
|
|
1168
|
+
*/
|
|
1132
1169
|
all(username) {
|
|
1133
1170
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${username}` }).then((resp) => {
|
|
1134
1171
|
this.emit(PES`token/${username}:r`, resp);
|
|
1135
1172
|
return resp;
|
|
1136
1173
|
});
|
|
1137
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Create a new user token
|
|
1177
|
+
* @param {{name: string, owner: string, expire: null | Date}} token Token settings
|
|
1178
|
+
* @return {Promise<UserToken>} Crated token
|
|
1179
|
+
*/
|
|
1138
1180
|
create(token) {
|
|
1139
1181
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${token.owner}`, body: token }).then((resp) => {
|
|
1140
1182
|
this.emit(PES`token/${token.owner}:c`, token);
|
|
1141
1183
|
return resp;
|
|
1142
1184
|
});
|
|
1143
1185
|
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Delete an existing user token
|
|
1188
|
+
* @param {string} id Token ID
|
|
1189
|
+
* @return {Promise<void>} Resolves once complete
|
|
1190
|
+
*/
|
|
1144
1191
|
delete(id) {
|
|
1145
1192
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${id}`, method: "DELETE" }).then(() => this.emit(PES`token/${id}:d`, id));
|
|
1146
1193
|
}
|
|
1147
1194
|
}
|
|
1148
1195
|
class Totp {
|
|
1149
1196
|
constructor(api) {
|
|
1197
|
+
/**
|
|
1198
|
+
* Enable 2FA for user
|
|
1199
|
+
* @param {string} username User to reset
|
|
1200
|
+
* @return {Promise<void>} Resolves once complete
|
|
1201
|
+
*/
|
|
1150
1202
|
__publicField(this, "enable", this.reset);
|
|
1151
1203
|
this.api = api;
|
|
1152
1204
|
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Disable 2FA for user
|
|
1207
|
+
* @param {string} username User to disable 2FA for
|
|
1208
|
+
* @return {Promise<void>} Resolves once complete
|
|
1209
|
+
*/
|
|
1153
1210
|
disable(username) {
|
|
1154
1211
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "DELETE" });
|
|
1155
1212
|
}
|
|
1213
|
+
/**
|
|
1214
|
+
* Reset users 2FA
|
|
1215
|
+
* @param {string} username User to reset
|
|
1216
|
+
* @return {Promise<void>} Resolves once complete
|
|
1217
|
+
*/
|
|
1156
1218
|
reset(username) {
|
|
1157
1219
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "POST" });
|
|
1158
1220
|
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Setup 2FA authentication method
|
|
1223
|
+
* @param {string} username User to setup
|
|
1224
|
+
* @param {string} method Authenticator type
|
|
1225
|
+
* @param {string | null} totp null to being process, 2FA code to validate method
|
|
1226
|
+
* @return {Promise<void>} Resolves once complete
|
|
1227
|
+
*/
|
|
1159
1228
|
setup(username, method = "app", totp) {
|
|
1160
1229
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, body: clean({
|
|
1161
1230
|
method,
|
|
@@ -1167,7 +1236,9 @@ class Auth extends PathEventEmitter {
|
|
|
1167
1236
|
constructor(api, opts = {}) {
|
|
1168
1237
|
super();
|
|
1169
1238
|
__publicField(this, "api");
|
|
1239
|
+
/** Manage user tokens */
|
|
1170
1240
|
__publicField(this, "token");
|
|
1241
|
+
/** Manage user 2FA */
|
|
1171
1242
|
__publicField(this, "totp");
|
|
1172
1243
|
__publicField(this, "_permissions", []);
|
|
1173
1244
|
__publicField(this, "_user");
|
|
@@ -1204,6 +1275,7 @@ class Auth extends PathEventEmitter {
|
|
|
1204
1275
|
else this.user = null;
|
|
1205
1276
|
});
|
|
1206
1277
|
}
|
|
1278
|
+
/** Get current user permissions */
|
|
1207
1279
|
get permissions() {
|
|
1208
1280
|
return this._permissions;
|
|
1209
1281
|
}
|
|
@@ -1211,19 +1283,33 @@ class Auth extends PathEventEmitter {
|
|
|
1211
1283
|
this._permissions = perms;
|
|
1212
1284
|
this.emit(PES`auth/permissions:u`, this._permissions);
|
|
1213
1285
|
}
|
|
1286
|
+
/** Get current user, undefined if not yet initialized */
|
|
1214
1287
|
get user() {
|
|
1215
1288
|
return this._user;
|
|
1216
1289
|
}
|
|
1290
|
+
/** Update user info without changing the session */
|
|
1217
1291
|
set user(user) {
|
|
1218
1292
|
if (!isEqual(this.user, user)) {
|
|
1219
1293
|
this._user = user ? user : null;
|
|
1220
1294
|
this.emit(PES`auth/user:u`, this._user);
|
|
1221
1295
|
}
|
|
1222
1296
|
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Check if origin is recognized & whitelisted
|
|
1299
|
+
* @param {string} host Origin to check
|
|
1300
|
+
* @return {Promise<void>} Resolves in known, 401 code otherwise
|
|
1301
|
+
*/
|
|
1223
1302
|
knownHost(host = location.origin) {
|
|
1224
1303
|
if (host.startsWith("/")) return Promise.resolve();
|
|
1225
1304
|
return this.api.request({ url: `/api/auth/known-host?host=${encodeURI(new URL(host).origin)}` });
|
|
1226
1305
|
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Login a user & return the account
|
|
1308
|
+
* @param {string} username username
|
|
1309
|
+
* @param {string} password user's password
|
|
1310
|
+
* @param {{totp: string, expire: null | number | Date}} opts 2FA code and expiry options (null to never expire)
|
|
1311
|
+
* @return {Promise<User | null>} User account on success
|
|
1312
|
+
*/
|
|
1227
1313
|
login(username, password, opts) {
|
|
1228
1314
|
if (!username || !password) throw new Error("Cannot login, missing username or password");
|
|
1229
1315
|
return this.api.request({
|
|
@@ -1242,34 +1328,55 @@ class Auth extends PathEventEmitter {
|
|
|
1242
1328
|
return user;
|
|
1243
1329
|
});
|
|
1244
1330
|
}
|
|
1331
|
+
/**
|
|
1332
|
+
* Login via Momentum single sign on
|
|
1333
|
+
* @param {string} host Host origin attempting to login
|
|
1334
|
+
* @return {Promise<string>} Token on success
|
|
1335
|
+
*/
|
|
1245
1336
|
loginRedirect(host = location.origin) {
|
|
1246
1337
|
return new Promise((res, rej) => {
|
|
1247
1338
|
var _a;
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
const origin = new URL(this.opts.loginUrl).origin;
|
|
1251
|
-
win.addEventListener("message", (event) => {
|
|
1339
|
+
let origin = new URL(this.opts.loginUrl).origin, done = false, listener, win;
|
|
1340
|
+
window.addEventListener("message", listener = (event) => {
|
|
1252
1341
|
const data = (event == null ? void 0 : event.data) || {};
|
|
1253
|
-
if (event.origin !=
|
|
1342
|
+
if (event.origin != origin || data.sender != origin) return;
|
|
1254
1343
|
if (!data.token) return rej("Unknown response from login");
|
|
1255
|
-
|
|
1256
|
-
|
|
1344
|
+
done = true;
|
|
1345
|
+
this.api.token = data.token;
|
|
1346
|
+
window.removeEventListener("message", listener);
|
|
1257
1347
|
win.close();
|
|
1348
|
+
res(data.token);
|
|
1349
|
+
});
|
|
1350
|
+
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.loginUrl}?redirect=postmessage&host=${host}`), "_blank");
|
|
1351
|
+
if (!win) {
|
|
1352
|
+
window.removeEventListener("message", listener);
|
|
1353
|
+
return rej("Unable to open login");
|
|
1354
|
+
}
|
|
1355
|
+
win.addEventListener("close", () => {
|
|
1356
|
+
if (!done) rej("Window closed before logging in");
|
|
1258
1357
|
});
|
|
1259
1358
|
});
|
|
1260
1359
|
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Logout current user
|
|
1362
|
+
*/
|
|
1261
1363
|
logout() {
|
|
1262
1364
|
this.emit(PES`auth/logout:d`, this.user);
|
|
1263
1365
|
this.api.token = null;
|
|
1264
1366
|
this.user = null;
|
|
1265
1367
|
}
|
|
1266
|
-
|
|
1368
|
+
/**
|
|
1369
|
+
* Create a new user with login
|
|
1370
|
+
* @param {Partial<User> & {password: string}} user User data with password
|
|
1371
|
+
* @return {Promise<User>} Registered user data
|
|
1372
|
+
*/
|
|
1373
|
+
async register(user) {
|
|
1267
1374
|
var _a;
|
|
1268
|
-
if (!
|
|
1269
|
-
const
|
|
1270
|
-
if ((_a =
|
|
1271
|
-
this.emit(PES`auth/register:c`,
|
|
1272
|
-
return
|
|
1375
|
+
if (!user.username || !user.password) throw new Error("Cannot register user, missing username or password");
|
|
1376
|
+
const u = await this.api.request({ url: "/api/auth/register", body: { ...user } });
|
|
1377
|
+
if ((_a = u == null ? void 0 : u.image) == null ? void 0 : _a.startsWith("/")) u.image = `${this.api.url}${u.image}?token=${this.api.token}`;
|
|
1378
|
+
this.emit(PES`auth/register:c`, u);
|
|
1379
|
+
return u;
|
|
1273
1380
|
}
|
|
1274
1381
|
reset(emailOrPass, token) {
|
|
1275
1382
|
if (!emailOrPass) throw new Error("Cannot reset password, missing email or token");
|
|
@@ -1284,6 +1391,12 @@ class Auth extends PathEventEmitter {
|
|
|
1284
1391
|
this.emit(PES`auth/reset:${token ? "u" : "c"}`, token || emailOrPass);
|
|
1285
1392
|
});
|
|
1286
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Get session information
|
|
1396
|
+
* @param {string} token Token to fetch session info for
|
|
1397
|
+
* @param {boolean} set Set as current active session
|
|
1398
|
+
* @return {Promise<{token: string, user: User, permissions: string[], custom: any} | null>} Session information
|
|
1399
|
+
*/
|
|
1287
1400
|
async session(token, set = false) {
|
|
1288
1401
|
if (!token) token = this.api.token;
|
|
1289
1402
|
const session = await this.api.request({
|
|
@@ -1300,6 +1413,13 @@ class Auth extends PathEventEmitter {
|
|
|
1300
1413
|
}
|
|
1301
1414
|
return session;
|
|
1302
1415
|
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Update password for user
|
|
1418
|
+
* @param {string} username User to reset
|
|
1419
|
+
* @param {string} password New user password
|
|
1420
|
+
* @param {string} oldPassword Old password for validation
|
|
1421
|
+
* @return {Promise<void>} Resolves once complete
|
|
1422
|
+
*/
|
|
1303
1423
|
async updatePassword(username, password, oldPassword) {
|
|
1304
1424
|
if (!username || !password) throw new Error("Cannot update password, missing username or password");
|
|
1305
1425
|
return this.api.request({
|
|
@@ -1321,9 +1441,11 @@ class Client extends PathEventEmitter {
|
|
|
1321
1441
|
this.settings = settings;
|
|
1322
1442
|
this.pushSubscription.then((resp) => this.notifications = !!resp);
|
|
1323
1443
|
}
|
|
1444
|
+
/** Check if mobile device */
|
|
1324
1445
|
get mobile() {
|
|
1325
1446
|
return ["android", "ios"].includes(this.platform);
|
|
1326
1447
|
}
|
|
1448
|
+
/** Are notifications enabled */
|
|
1327
1449
|
get notifications() {
|
|
1328
1450
|
return this._notifications;
|
|
1329
1451
|
}
|
|
@@ -1331,6 +1453,7 @@ class Client extends PathEventEmitter {
|
|
|
1331
1453
|
this._notifications = enabled;
|
|
1332
1454
|
this.emit(PES`client/notifications:${enabled ? "c" : "d"}`, enabled);
|
|
1333
1455
|
}
|
|
1456
|
+
/** Get the current platform type */
|
|
1334
1457
|
get platform() {
|
|
1335
1458
|
if (!this._platform) {
|
|
1336
1459
|
const userAgent = navigator.userAgent || navigator.vendor;
|
|
@@ -1343,6 +1466,7 @@ class Client extends PathEventEmitter {
|
|
|
1343
1466
|
}
|
|
1344
1467
|
return this._platform;
|
|
1345
1468
|
}
|
|
1469
|
+
/** Get Push Subscription info */
|
|
1346
1470
|
get pushSubscription() {
|
|
1347
1471
|
var _a;
|
|
1348
1472
|
if (!((_a = navigator.serviceWorker) == null ? void 0 : _a.controller)) return Promise.resolve(null);
|
|
@@ -1351,115 +1475,77 @@ class Client extends PathEventEmitter {
|
|
|
1351
1475
|
return (_a2 = sw == null ? void 0 : sw.pushManager) == null ? void 0 : _a2.getSubscription();
|
|
1352
1476
|
});
|
|
1353
1477
|
}
|
|
1478
|
+
/** Check if running as a PWA */
|
|
1354
1479
|
get pwa() {
|
|
1355
1480
|
if (this._pwa == null)
|
|
1356
1481
|
this._pwa = matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
1357
1482
|
return this._pwa;
|
|
1358
1483
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1484
|
+
/**
|
|
1485
|
+
* Inject the client theme settings, meta tags & PWA prompt
|
|
1486
|
+
* @param {boolean} reload Reload settings
|
|
1487
|
+
* @return {Promise<void>} Resolves on completion
|
|
1488
|
+
*/
|
|
1489
|
+
async inject(reload) {
|
|
1490
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1491
|
+
const meta = (key, name, value) => {
|
|
1492
|
+
const exists = document.querySelector(`meta[${key}="${name}"]`);
|
|
1493
|
+
if (value === void 0 || exists) return exists;
|
|
1494
|
+
const meta2 = document.createElement("meta");
|
|
1495
|
+
meta2.setAttribute(key, name);
|
|
1496
|
+
meta2.content = value;
|
|
1497
|
+
document.head.append(meta2);
|
|
1498
|
+
};
|
|
1361
1499
|
let settings = this.settings.cache;
|
|
1362
|
-
if (firstLoad) this.settings.all(false, reload).then(() => this.inject(false, false)).catch(() => {
|
|
1363
|
-
});
|
|
1364
|
-
if (settings["title"] && !document.head.querySelector('meta[property="og:title"]')) {
|
|
1365
|
-
const meta = document.createElement("meta");
|
|
1366
|
-
meta.setAttribute("property", "og:title");
|
|
1367
|
-
meta.content = settings["title"];
|
|
1368
|
-
document.head.append(meta);
|
|
1369
|
-
}
|
|
1370
|
-
if (!document.querySelector('meta[property="og:type"]')) {
|
|
1371
|
-
const meta = document.createElement("meta");
|
|
1372
|
-
meta.setAttribute("property", "og:type");
|
|
1373
|
-
meta.content = "article";
|
|
1374
|
-
document.head.append(meta);
|
|
1375
|
-
}
|
|
1376
|
-
if (settings["public_url"] && !document.querySelector('meta[property="og:url"]')) {
|
|
1377
|
-
const meta = document.createElement("meta");
|
|
1378
|
-
meta.setAttribute("property", "og:url");
|
|
1379
|
-
meta.content = settings["public_url"];
|
|
1380
|
-
document.head.append(meta);
|
|
1381
|
-
}
|
|
1382
|
-
if (settings["description"]) {
|
|
1383
|
-
if (!document.querySelector('meta[property="og:description"]')) {
|
|
1384
|
-
const meta = document.createElement("meta");
|
|
1385
|
-
meta.setAttribute("property", "og:description");
|
|
1386
|
-
meta.content = settings["description"];
|
|
1387
|
-
document.head.append(meta);
|
|
1388
|
-
}
|
|
1389
|
-
if (!document.querySelector('meta[property="description"]')) {
|
|
1390
|
-
const meta = document.createElement("meta");
|
|
1391
|
-
meta.setAttribute("property", "description");
|
|
1392
|
-
meta.content = settings["description"];
|
|
1393
|
-
document.head.append(meta);
|
|
1394
|
-
}
|
|
1395
|
-
if (!document.querySelector('meta[property="twitter:card"]')) {
|
|
1396
|
-
const meta = document.createElement("meta");
|
|
1397
|
-
meta.setAttribute("property", "twitter:card");
|
|
1398
|
-
meta.content = settings["description"];
|
|
1399
|
-
document.head.append(meta);
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
if (settings["public_url"] && !document.querySelector('meta[property="og:image"]')) {
|
|
1403
|
-
const meta = document.createElement("meta");
|
|
1404
|
-
meta.setAttribute("property", "og:image");
|
|
1405
|
-
meta.content = settings["public_url"] + "/favicon.ico";
|
|
1406
|
-
document.head.append(meta);
|
|
1407
|
-
}
|
|
1408
|
-
if (!document.querySelector('meta[name="mobile-web-app-capable"]')) {
|
|
1409
|
-
const meta = document.createElement("meta");
|
|
1410
|
-
meta.name = "mobile-web-app-capable";
|
|
1411
|
-
meta.content = "yes";
|
|
1412
|
-
document.head.append(meta);
|
|
1413
|
-
}
|
|
1414
|
-
if (!document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]')) {
|
|
1415
|
-
const meta = document.createElement("meta");
|
|
1416
|
-
meta.name = "apple-mobile-web-app-status-bar-style";
|
|
1417
|
-
meta.content = "default";
|
|
1418
|
-
document.head.append(meta);
|
|
1419
|
-
}
|
|
1420
|
-
if (settings["title"] && !document.querySelector('meta[name="apple-mobile-web-app-title"]')) {
|
|
1421
|
-
const meta = document.createElement("meta");
|
|
1422
|
-
meta.name = "apple-mobile-web-app-title";
|
|
1423
|
-
meta.content = settings["title"];
|
|
1424
|
-
document.head.append(meta);
|
|
1425
|
-
}
|
|
1426
|
-
if (settings["public_url"] && !document.querySelector('link[rel="apple-touch-icon"]')) {
|
|
1427
|
-
const meta = document.createElement("link");
|
|
1428
|
-
meta.rel = "apple-touch-icon";
|
|
1429
|
-
meta.href = settings["public_url"] + "/favicon.ico";
|
|
1430
|
-
document.head.append(meta);
|
|
1431
|
-
}
|
|
1432
|
-
if (settings["public_url"] && !document.querySelector('link[rel="apple-touch-startup-image"]')) {
|
|
1433
|
-
const meta = document.createElement("link");
|
|
1434
|
-
meta.rel = "apple-touch-startup-image";
|
|
1435
|
-
meta.href = settings["public_url"] + "/favicon.ico";
|
|
1436
|
-
document.head.append(meta);
|
|
1437
|
-
}
|
|
1438
1500
|
if (settings["title"]) document.querySelectorAll(".momentum-title").forEach((el) => el.innerText = settings["title"]);
|
|
1439
1501
|
if (settings["description"]) document.querySelectorAll(".momentum-description").forEach((el) => el.innerText = settings["description"]);
|
|
1440
1502
|
if (settings["version"]) document.querySelectorAll(".momentum-version").forEach((el) => el.innerText = settings["version"]);
|
|
1441
1503
|
if (settings["logo"]) document.querySelectorAll(".momentum-logo").forEach((el) => el.src = settings["logo"]);
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1504
|
+
meta("name", "theme-color", (_a = settings["theme"]) == null ? void 0 : _a.background);
|
|
1505
|
+
document.body.classList.add(((_b = settings["theme"]) == null ? void 0 : _b.darkMode) ? "theme-dark" : "theme-light");
|
|
1506
|
+
document.body.classList.remove(((_c = settings["theme"]) == null ? void 0 : _c.darkMode) ? "theme-light" : "theme-dark");
|
|
1507
|
+
document.body.style.setProperty("--theme-backdrop", (_d = settings["theme"]) == null ? void 0 : _d.background);
|
|
1508
|
+
document.body.style.setProperty("--theme-primary", (_e = settings["theme"]) == null ? void 0 : _e.primary);
|
|
1509
|
+
document.body.style.setProperty("--theme-accent", (_f = settings["theme"]) == null ? void 0 : _f.accent);
|
|
1510
|
+
document.body.style.setProperty("--theme-contrast", blackOrWhite((_g = settings["theme"]) == null ? void 0 : _g.background));
|
|
1511
|
+
meta("name", "description", settings["description"]);
|
|
1512
|
+
meta("itemprop", "name", settings["title"]);
|
|
1513
|
+
meta("itemprop", "description", settings["description"]);
|
|
1514
|
+
meta("itemprop", "image", `${settings["public_url"]}/favicon.png`);
|
|
1515
|
+
meta("property", "og:type", "website");
|
|
1516
|
+
meta("property", "og:url", settings["public_url"]);
|
|
1517
|
+
meta("property", "og:image", `${settings["public_url"]}/favicon.png`);
|
|
1518
|
+
meta("property", "og:title", settings["title"]);
|
|
1519
|
+
meta("property", "og:description", settings["description"]);
|
|
1520
|
+
meta("name", "twitter:card", "summary_large_image");
|
|
1521
|
+
meta("name", "twitter:title", settings["title"]);
|
|
1522
|
+
meta("name", "twitter:description", settings["description"]);
|
|
1523
|
+
meta("name", "twitter:image", `${settings["public_url"]}/favicon.png`);
|
|
1524
|
+
meta("name", "mobile-web-app-capable", "yes");
|
|
1525
|
+
meta("name", "apple-mobile-web-app-status-bar-style", "default");
|
|
1526
|
+
meta("name", "apple-mobile-web-app-title", settings["title"]);
|
|
1527
|
+
meta("name", "apple-touch-icon", `${settings["public_url"]}/favicon.png`);
|
|
1528
|
+
meta("name", "apple-touch-startup-image", `${settings["public_url"]}/favicon.png`);
|
|
1450
1529
|
if (settings["pwa"]) {
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1530
|
+
if (!document.querySelector('link[rel="manifest"]')) {
|
|
1531
|
+
const link = document.createElement("link");
|
|
1532
|
+
link.setAttribute("rel", "manifest");
|
|
1533
|
+
link.setAttribute("href", this.settings.api.url + "/manifest.json");
|
|
1534
|
+
document.head.append(link);
|
|
1535
|
+
}
|
|
1455
1536
|
setTimeout(() => {
|
|
1456
1537
|
const dismissed = !!localStorage.getItem("momentum:install-prompt");
|
|
1457
1538
|
if (!dismissed && !this.pwa && this.mobile) this.pwaPrompt();
|
|
1458
|
-
},
|
|
1539
|
+
}, 6e4);
|
|
1459
1540
|
}
|
|
1460
1541
|
this.emit(PES`client/inject:c`, this.platform);
|
|
1461
1542
|
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Create UI prompt for user to install as PWA
|
|
1545
|
+
* @param platform Platform prompt, leave blank to auto-detect
|
|
1546
|
+
*/
|
|
1462
1547
|
pwaPrompt(platform) {
|
|
1548
|
+
if (document.querySelector(".momentum-pwa-prompt")) return;
|
|
1463
1549
|
const url = this.settings.api.url;
|
|
1464
1550
|
const settings = this.settings.cache;
|
|
1465
1551
|
const android = (platform || this.platform) == "android";
|
|
@@ -1566,7 +1652,7 @@ class Client extends PathEventEmitter {
|
|
|
1566
1652
|
</div>`;
|
|
1567
1653
|
const close = document.createElement("button");
|
|
1568
1654
|
close.classList.add("momentum-pwa-prompt-close");
|
|
1569
|
-
close.innerText = "
|
|
1655
|
+
close.innerText = "x";
|
|
1570
1656
|
close.onclick = () => {
|
|
1571
1657
|
prompt.classList.add("exit");
|
|
1572
1658
|
backdrop.classList.add("exit");
|
|
@@ -1582,6 +1668,10 @@ class Client extends PathEventEmitter {
|
|
|
1582
1668
|
document.body.append(backdrop);
|
|
1583
1669
|
this.emit(PES`client/pwa:c`, platform);
|
|
1584
1670
|
}
|
|
1671
|
+
/**
|
|
1672
|
+
* Enable device notifications
|
|
1673
|
+
* @return {Promise<null>} Resolves on success
|
|
1674
|
+
*/
|
|
1585
1675
|
async enableNotifications() {
|
|
1586
1676
|
const granted = await Notification.requestPermission();
|
|
1587
1677
|
if (!granted) return null;
|
|
@@ -1592,6 +1682,10 @@ class Client extends PathEventEmitter {
|
|
|
1592
1682
|
})).toJSON();
|
|
1593
1683
|
return this.api.request({ url: "/api/notifications", body: subscription }).then(() => this.notifications = true);
|
|
1594
1684
|
}
|
|
1685
|
+
/**
|
|
1686
|
+
* Disable device notifications
|
|
1687
|
+
* @return {Promise<void>} Resolves on success
|
|
1688
|
+
*/
|
|
1595
1689
|
async disableNotifications() {
|
|
1596
1690
|
var _a;
|
|
1597
1691
|
const subscription = await this.pushSubscription;
|
|
@@ -1601,11 +1695,36 @@ class Client extends PathEventEmitter {
|
|
|
1601
1695
|
} }).then(() => this.notifications = false);
|
|
1602
1696
|
}
|
|
1603
1697
|
}
|
|
1698
|
+
class Schemas extends PathEventEmitter {
|
|
1699
|
+
constructor(api) {
|
|
1700
|
+
super();
|
|
1701
|
+
this.api = api;
|
|
1702
|
+
}
|
|
1703
|
+
delete(path) {
|
|
1704
|
+
if (!path) throw new Error("Cannot delete schema, missing collection path");
|
|
1705
|
+
return this.api.request({ url: `/api/` + PES`schema/${path}`, method: "DELETE" }).then(() => this.emit(PES`schema/${path}:d`, path));
|
|
1706
|
+
}
|
|
1707
|
+
read(pathOrTree) {
|
|
1708
|
+
return this.api.request({ url: "/api/" + PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
1709
|
+
this.emit(PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
1710
|
+
return resp;
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
update(schema) {
|
|
1714
|
+
if (!schema.path) throw new Error("Cannot update schema, missing collection path");
|
|
1715
|
+
return this.api.request({ url: "/api/" + PES`schema/${schema.path}`, body: schema }).then((resp) => {
|
|
1716
|
+
this.emit(PES`schema/${schema.path}:${schema._id ? "u" : "c"}`, resp);
|
|
1717
|
+
return resp;
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1604
1721
|
class Data extends PathEventEmitter {
|
|
1605
1722
|
constructor(api) {
|
|
1606
1723
|
super();
|
|
1607
1724
|
__publicField(this, "api");
|
|
1725
|
+
__publicField(this, "schema");
|
|
1608
1726
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1727
|
+
this.schema = new Schemas(this.api);
|
|
1609
1728
|
}
|
|
1610
1729
|
create(collection, document2) {
|
|
1611
1730
|
if (!collection || !document2) throw new Error("Cannot create document, missing collection or document");
|
|
@@ -1651,24 +1770,6 @@ class Data extends PathEventEmitter {
|
|
|
1651
1770
|
return resp;
|
|
1652
1771
|
});
|
|
1653
1772
|
}
|
|
1654
|
-
// Schema ==========================================================================================================
|
|
1655
|
-
deleteSchema(path) {
|
|
1656
|
-
if (!path) throw new Error("Cannot delete schema, missing collection path");
|
|
1657
|
-
return this.api.request({ url: `/api/` + PES`schema/${path}`, method: "DELETE" }).then(() => this.emit(PES`schema/${path}:d`, path));
|
|
1658
|
-
}
|
|
1659
|
-
readSchema(pathOrTree) {
|
|
1660
|
-
return this.api.request({ url: "/api/" + PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
1661
|
-
this.emit(PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
1662
|
-
return resp;
|
|
1663
|
-
});
|
|
1664
|
-
}
|
|
1665
|
-
updateSchema(schema) {
|
|
1666
|
-
if (!schema.path) throw new Error("Cannot update schema, missing collection path");
|
|
1667
|
-
return this.api.request({ url: "/api/" + PES`schema/${schema.path}`, body: schema }).then((resp) => {
|
|
1668
|
-
this.emit(PES`schema/${schema.path}:${schema._id ? "u" : "c"}`, resp);
|
|
1669
|
-
return resp;
|
|
1670
|
-
});
|
|
1671
|
-
}
|
|
1672
1773
|
}
|
|
1673
1774
|
class Email extends PathEventEmitter {
|
|
1674
1775
|
constructor(api) {
|
|
@@ -1676,6 +1777,11 @@ class Email extends PathEventEmitter {
|
|
|
1676
1777
|
__publicField(this, "api");
|
|
1677
1778
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1678
1779
|
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Send Email
|
|
1782
|
+
* @param {Mail} email Email to send
|
|
1783
|
+
* @return {Promise<any>} Response
|
|
1784
|
+
*/
|
|
1679
1785
|
send(email) {
|
|
1680
1786
|
if (!email.to && !email.bcc || !email.body) throw new Error("Cannot send email, missing address or body");
|
|
1681
1787
|
return this.api.request({ url: "/api/email", body: email }).then((response) => {
|
|
@@ -1886,46 +1992,102 @@ ${log}`;
|
|
|
1886
1992
|
}
|
|
1887
1993
|
}
|
|
1888
1994
|
class Payments extends PathEventEmitter {
|
|
1889
|
-
constructor(api,
|
|
1995
|
+
constructor(api, opts = {}) {
|
|
1890
1996
|
super();
|
|
1891
1997
|
__publicField(this, "api");
|
|
1998
|
+
__publicField(this, "loaded", false);
|
|
1892
1999
|
__publicField(this, "stripe");
|
|
2000
|
+
__publicField(this, "token");
|
|
2001
|
+
this.opts = opts;
|
|
1893
2002
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
this.stripe = Stripe(secret);
|
|
1898
|
-
} catch (err) {
|
|
1899
|
-
if (retry > 0) setTimeout(() => setup(retry--), 250);
|
|
1900
|
-
else console.warn("Stripe failed, did you add the library & setup your API key?", err);
|
|
1901
|
-
}
|
|
2003
|
+
this.opts = {
|
|
2004
|
+
paymentUrl: this.api.url + "/ui/#/payment",
|
|
2005
|
+
...this.opts
|
|
1902
2006
|
};
|
|
1903
|
-
setup();
|
|
1904
2007
|
}
|
|
1905
|
-
async
|
|
1906
|
-
if (!
|
|
2008
|
+
async checkout(cart, invoice, extra = {}) {
|
|
2009
|
+
if (!(cart == null ? void 0 : cart.length)) throw new Error("Please add items to cart`");
|
|
1907
2010
|
const request = await this.api.request({ url: "/api/payments", body: {
|
|
1908
|
-
|
|
1909
|
-
|
|
2011
|
+
cart,
|
|
2012
|
+
invoice,
|
|
2013
|
+
extra
|
|
1910
2014
|
} });
|
|
1911
|
-
this.emit(PES`payments:c`, request.
|
|
1912
|
-
return request.
|
|
2015
|
+
this.emit(PES`payments:c`, request.token);
|
|
2016
|
+
return request.token;
|
|
1913
2017
|
}
|
|
1914
|
-
async
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2018
|
+
async init() {
|
|
2019
|
+
if (!this.stripe) this.stripe = await new Promise((res) => {
|
|
2020
|
+
if (this.loaded || this.stripe) return res(window["Stripe"]);
|
|
2021
|
+
const script = document.createElement("script");
|
|
2022
|
+
script.src = "https://js.stripe.com/v3/";
|
|
2023
|
+
script.setAttribute("crossorigin", "anonymous");
|
|
2024
|
+
script.onload = () => res(window["Stripe"]);
|
|
2025
|
+
document.head.appendChild(script);
|
|
1922
2026
|
});
|
|
2027
|
+
return this.stripe(this.token);
|
|
1923
2028
|
}
|
|
1924
2029
|
async history(username) {
|
|
1925
|
-
const history = await this.api.request({ url: `/api
|
|
2030
|
+
const history = await this.api.request({ url: `/api/payments/${username || ""}` });
|
|
1926
2031
|
this.emit(PES`payments/${username}:r`, history);
|
|
1927
2032
|
return history;
|
|
1928
2033
|
}
|
|
2034
|
+
async products(id) {
|
|
2035
|
+
return this.api.request({ url: `/api/payments/products/${id || ""}` }).then((resp) => {
|
|
2036
|
+
this.emit(PES`products/${id}:r`, resp);
|
|
2037
|
+
return resp;
|
|
2038
|
+
});
|
|
2039
|
+
}
|
|
2040
|
+
async payment(card, token) {
|
|
2041
|
+
const client = await this.init();
|
|
2042
|
+
return client.confirmPayment({
|
|
2043
|
+
clientSecret: token,
|
|
2044
|
+
confirmParams: {
|
|
2045
|
+
payment_method: {
|
|
2046
|
+
card: { ...card, details: void 0 },
|
|
2047
|
+
billing_details: card.details || {}
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
async paymentForm(element, token) {
|
|
2053
|
+
const client = await this.init();
|
|
2054
|
+
const form = client.elements({ clientSecret: token });
|
|
2055
|
+
form.create("payment").mount(element);
|
|
2056
|
+
return (redirect = location.href) => client.confirmPayment({
|
|
2057
|
+
elements: form,
|
|
2058
|
+
redirect: "if_required",
|
|
2059
|
+
confirmParams: { return_url: redirect + "?payment_status=success" }
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
/**
|
|
2063
|
+
* Complete payment via Momentum's payment page
|
|
2064
|
+
* @param {string} token Stripe payment intent secret
|
|
2065
|
+
* @param {string} host Host origin attempting to login
|
|
2066
|
+
* @return {Promise<string>} Token on success
|
|
2067
|
+
*/
|
|
2068
|
+
paymentRedirect(token, host = location.origin) {
|
|
2069
|
+
return new Promise(async (res, rej) => {
|
|
2070
|
+
var _a;
|
|
2071
|
+
let origin = new URL(this.opts.paymentUrl).origin, done = false, listener, win;
|
|
2072
|
+
window.addEventListener("message", listener = (event) => {
|
|
2073
|
+
const data = (event == null ? void 0 : event.data) || {};
|
|
2074
|
+
if (event.origin != origin || data.sender != origin) return;
|
|
2075
|
+
if (!data.response) return rej("Unknown response from payment page");
|
|
2076
|
+
done = true;
|
|
2077
|
+
window.removeEventListener("message", listener);
|
|
2078
|
+
win.close();
|
|
2079
|
+
res(data.response);
|
|
2080
|
+
});
|
|
2081
|
+
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.paymentUrl}?token=${token}&host=${host}`), "_blank");
|
|
2082
|
+
if (!win) {
|
|
2083
|
+
window.removeEventListener("message", listener);
|
|
2084
|
+
return rej("Unable to open payment page");
|
|
2085
|
+
}
|
|
2086
|
+
win.addEventListener("close", () => {
|
|
2087
|
+
if (!done) rej("Window closed before payment was complete");
|
|
2088
|
+
});
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
1929
2091
|
}
|
|
1930
2092
|
class Pdf extends PathEventEmitter {
|
|
1931
2093
|
constructor(api) {
|
|
@@ -2246,7 +2408,7 @@ class Momentum extends PathEventEmitter {
|
|
|
2246
2408
|
this.forms = new Forms(this.api);
|
|
2247
2409
|
this.groups = new Groups(this.api);
|
|
2248
2410
|
this.logger = new Logger(this.api, (opts == null ? void 0 : opts.app) || "client", opts == null ? void 0 : opts.logLevel);
|
|
2249
|
-
|
|
2411
|
+
this.payments = new Payments(this.api);
|
|
2250
2412
|
this.pdf = new Pdf(this.api);
|
|
2251
2413
|
this.phone = new Phone(this.api);
|
|
2252
2414
|
this.settings = new Settings(this.api);
|
|
@@ -2265,7 +2427,7 @@ class Momentum extends PathEventEmitter {
|
|
|
2265
2427
|
this.relayEvents(this.email);
|
|
2266
2428
|
this.relayEvents(this.groups);
|
|
2267
2429
|
this.relayEvents(this.logger);
|
|
2268
|
-
|
|
2430
|
+
this.relayEvents(this.payments);
|
|
2269
2431
|
this.relayEvents(this.pdf);
|
|
2270
2432
|
this.relayEvents(this.phone);
|
|
2271
2433
|
this.relayEvents(this.settings);
|
|
@@ -2277,8 +2439,12 @@ class Momentum extends PathEventEmitter {
|
|
|
2277
2439
|
const cached = this.users.cache.get(this.auth.user.username);
|
|
2278
2440
|
if (cached) this.auth.user = cached;
|
|
2279
2441
|
});
|
|
2280
|
-
|
|
2281
|
-
|
|
2442
|
+
this.settings.on("settings:r", (event, value) => {
|
|
2443
|
+
var _a;
|
|
2444
|
+
this.payments.token = ((_a = value["stripe_token"]) == null ? void 0 : _a.value) || value["stripe_token"];
|
|
2445
|
+
});
|
|
2446
|
+
if ((opts == null ? void 0 : opts.worker) !== false && "serviceWorker" in navigator) {
|
|
2447
|
+
navigator.serviceWorker.register((opts == null ? void 0 : opts.worker) || "/momentum.worker.js").catch(() => console.warn("Unable to load momentum worker, some features may be limited."));
|
|
2282
2448
|
}
|
|
2283
2449
|
}
|
|
2284
2450
|
}
|