backend-manager 3.1.12 → 3.2.0
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/CHANGELOG.md +5 -0
- package/package.json +4 -4
- package/src/manager/helpers/assistant.js +1 -0
- package/src/manager/helpers/middleware.js +13 -15
- package/src/manager/helpers/settings.js +63 -13
- package/src/manager/helpers/subscription-resolver.js +3 -2
- package/src/manager/helpers/usage.js +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
|
+
## [3.2.0] - 2023-12-19
|
|
19
|
+
### Added
|
|
20
|
+
- Added `.settings()` API. Put your settings in `./schema/*.js` and access them with `assistant.settings.*`.
|
|
21
|
+
|
|
22
|
+
|
|
18
23
|
## [3.1.0] - 2023-12-19
|
|
19
24
|
### Added
|
|
20
25
|
- Added `.analytics()` API GA4 support.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"busboy": "^1.6.0",
|
|
41
41
|
"chalk": "^4.1.2",
|
|
42
42
|
"cors": "^2.8.5",
|
|
43
|
-
"dotenv": "^16.3.
|
|
43
|
+
"dotenv": "^16.3.2",
|
|
44
44
|
"firebase-admin": "^11.11.1",
|
|
45
45
|
"firebase-functions": "^4.6.0",
|
|
46
46
|
"fs-jetpack": "^5.1.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"moment": "^2.30.1",
|
|
56
56
|
"nanoid": "^3.3.7",
|
|
57
57
|
"node-fetch": "^2.7.0",
|
|
58
|
-
"node-powertools": "^1.1.
|
|
58
|
+
"node-powertools": "^1.1.2",
|
|
59
59
|
"npm-api": "^1.0.1",
|
|
60
60
|
"paypal-server-api": "^1.0.3",
|
|
61
61
|
"pushid": "^1.0.0",
|
|
@@ -70,4 +70,4 @@
|
|
|
70
70
|
"wonderful-log": "^1.0.5",
|
|
71
71
|
"yargs": "^17.7.2"
|
|
72
72
|
}
|
|
73
|
-
}
|
|
73
|
+
}
|
|
@@ -26,10 +26,11 @@ Middleware.prototype.run = function (library, req, res, options) {
|
|
|
26
26
|
|
|
27
27
|
// Set options
|
|
28
28
|
options = options || {};
|
|
29
|
+
options.authenticate = typeof options.authenticate === 'boolean' ? options.authenticate : true;
|
|
29
30
|
options.setupAnalytics = typeof options.setupAnalytics === 'boolean' ? options.setupAnalytics : true;
|
|
30
31
|
options.setupUsage = typeof options.setupUsage === 'boolean' ? options.setupUsage : true;
|
|
31
|
-
options.authenticate = typeof options.authenticate === 'boolean' ? options.authenticate : true;
|
|
32
32
|
options.setupSettings = typeof options.setupSettings === 'undefined' ? true : options.setupSettings;
|
|
33
|
+
options.schema = typeof options.schema === 'undefined' ? '' : options.schema;
|
|
33
34
|
|
|
34
35
|
// Log
|
|
35
36
|
assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city})`, JSON.stringify(data));
|
|
@@ -44,16 +45,16 @@ Middleware.prototype.run = function (library, req, res, options) {
|
|
|
44
45
|
return assistant.errorify(`Unable to load library @ (${library}): ${e.message}`, {sentry: true, send: true, log: true});
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
// Setup usage
|
|
48
|
-
if (options.setupUsage) {
|
|
49
|
-
assistant.usage = await Manager.Usage().init(assistant);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
48
|
// Setup user
|
|
53
49
|
if (!options.setupUsage && options.authenticate) {
|
|
54
50
|
await assistant.authenticate();
|
|
55
51
|
}
|
|
56
52
|
|
|
53
|
+
// Setup usage
|
|
54
|
+
if (options.setupUsage) {
|
|
55
|
+
assistant.usage = await Manager.Usage().init(assistant);
|
|
56
|
+
}
|
|
57
|
+
|
|
57
58
|
// Setup analytics
|
|
58
59
|
if (options.setupAnalytics) {
|
|
59
60
|
const uuid = assistant?.usage?.user?.auth?.uid
|
|
@@ -63,19 +64,16 @@ Middleware.prototype.run = function (library, req, res, options) {
|
|
|
63
64
|
assistant.analytics = Manager.Analytics({
|
|
64
65
|
assistant: assistant,
|
|
65
66
|
uuid: uuid,
|
|
66
|
-
})
|
|
67
|
+
});
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
// Resolve settings
|
|
70
71
|
if (options.setupSettings) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// } catch (e) {
|
|
77
|
-
// return assistant.errorify(`Unable to resolve settings @ (${library}): ${e.message}`, {sentry: true, send: true, log: true});
|
|
78
|
-
// }
|
|
72
|
+
try {
|
|
73
|
+
assistant.settings = Manager.Settings().resolve(assistant, options.schema, assistant.request.data);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
return assistant.errorify(`Unable to resolve settings @ (${options.schema}): ${e.message}`, {sentry: true, send: true, log: true});
|
|
76
|
+
}
|
|
79
77
|
}
|
|
80
78
|
|
|
81
79
|
// Process
|
|
@@ -2,31 +2,81 @@
|
|
|
2
2
|
* Settings
|
|
3
3
|
*
|
|
4
4
|
*/
|
|
5
|
+
// const jetpack = require('fs-jetpack');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const powertools = require('node-powertools');
|
|
8
|
+
const _ = require('lodash');
|
|
9
|
+
const moment = require('moment');
|
|
10
|
+
|
|
5
11
|
function Settings(m) {
|
|
6
12
|
const self = this;
|
|
7
13
|
|
|
8
14
|
self.Manager = m;
|
|
9
15
|
|
|
10
|
-
self.
|
|
11
|
-
|
|
12
|
-
self.initialized = false;
|
|
16
|
+
self.settings = null;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
Settings.prototype.resolve = function (assistant,
|
|
19
|
+
Settings.prototype.resolve = function (assistant, schema, settings) {
|
|
16
20
|
const self = this;
|
|
21
|
+
const Manager = self.Manager;
|
|
22
|
+
|
|
23
|
+
// Set settings
|
|
24
|
+
schema = schema || {};
|
|
25
|
+
settings = settings || {};
|
|
26
|
+
|
|
27
|
+
// Reset settings
|
|
28
|
+
self.settings = null;
|
|
29
|
+
|
|
30
|
+
assistant.log('Resolving settings for', schema, settings);
|
|
31
|
+
|
|
32
|
+
if (typeof schema === 'string') {
|
|
33
|
+
const schemaPath = path.resolve(process.cwd(), `schemas/${schema.replace('.js', '')}.js`);
|
|
34
|
+
|
|
35
|
+
schema = loadSchema(assistant, schemaPath, settings);
|
|
36
|
+
}
|
|
17
37
|
|
|
18
|
-
|
|
19
|
-
const Manager = self.Manager;
|
|
38
|
+
self.settings = powertools.defaults(settings, schema);
|
|
20
39
|
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
// Resolve
|
|
41
|
+
return self.settings;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
Settings.prototype.constant = function (name, options) {
|
|
45
|
+
const self = this;
|
|
46
|
+
const Manager = self.Manager;
|
|
23
47
|
|
|
24
|
-
|
|
25
|
-
|
|
48
|
+
options = options || {};
|
|
49
|
+
options.date = typeof options.date === 'undefined' ? moment() : moment(options.date);
|
|
26
50
|
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
|
|
51
|
+
if (name === 'timestamp') {
|
|
52
|
+
return {
|
|
53
|
+
types: ['string'],
|
|
54
|
+
value: undefined,
|
|
55
|
+
default: options.date.toISOString(),
|
|
56
|
+
}
|
|
57
|
+
} else if (name === 'timestampUNIX') {
|
|
58
|
+
return {
|
|
59
|
+
types: ['number'],
|
|
60
|
+
value: undefined,
|
|
61
|
+
default: options.date.unix(),
|
|
62
|
+
}
|
|
63
|
+
} else if (name === 'timestampFULL') {
|
|
64
|
+
return {
|
|
65
|
+
timestamp: self.constant('timestamp', options),
|
|
66
|
+
timestampUNIX: self.constant('timestampUNIX', options),
|
|
67
|
+
}
|
|
68
|
+
}
|
|
30
69
|
};
|
|
31
70
|
|
|
71
|
+
function loadSchema(assistant, schema, settings) {
|
|
72
|
+
const planId = assistant.request.user.plan.id;
|
|
73
|
+
|
|
74
|
+
const lib = require(schema)(assistant);
|
|
75
|
+
const def = lib.defaults;
|
|
76
|
+
const plan = lib[planId];
|
|
77
|
+
|
|
78
|
+
// Merge
|
|
79
|
+
return _.merge({}, def, plan);
|
|
80
|
+
}
|
|
81
|
+
|
|
32
82
|
module.exports = Settings;
|
|
@@ -224,8 +224,9 @@ SubscriptionResolver.prototype.resolve = function (options) {
|
|
|
224
224
|
resolved.details.message = 'Pre-payment authorization failed because there is no working payment method on file.'
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
// If they got a refund, set the expiration to 0
|
|
228
|
-
|
|
227
|
+
// If they got a refund (AND cancelled), set the expiration to 0
|
|
228
|
+
// This allows for partial refunds without disabling the subscription
|
|
229
|
+
if (resolved.payment.refunded && resolved.status === 'cancelled') {
|
|
229
230
|
resolved.expires.timestamp = moment(0);
|
|
230
231
|
resolved.details.message = 'Refund was issued so subscription is inactive.'
|
|
231
232
|
}
|
|
@@ -84,9 +84,7 @@ Usage.prototype.init = function (assistant, options) {
|
|
|
84
84
|
// TODO: Make it request using .where() query so it doesnt use a read if it doesnt have to
|
|
85
85
|
foundUsage = await Manager.libraries.admin.firestore().doc(`temporary/usage`)
|
|
86
86
|
.get()
|
|
87
|
-
.then((r) =>
|
|
88
|
-
return r.data()?.[`${self.key}`];
|
|
89
|
-
})
|
|
87
|
+
.then((r) => _.get(r.data(), self.key))
|
|
90
88
|
.catch((e) => {
|
|
91
89
|
assistant.errorify(`Usage.init(): Error fetching usage data: ${e}`, {sentry: true, send: false, log: true});
|
|
92
90
|
});
|