backend-manager 2.0.17 → 2.0.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "2.0.17",
3
+ "version": "2.0.20",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
@@ -64,4 +64,4 @@
64
64
  "src/",
65
65
  "templates/"
66
66
  ]
67
- }
67
+ }
@@ -1,4 +1,5 @@
1
1
  const moment = require('moment');
2
+ const fetch = require('node-fetch');
2
3
  const uuidv5 = require('uuid').v5;
3
4
  const { get, set, merge } = require('lodash');
4
5
 
@@ -12,16 +13,20 @@ let sampleUser = {
12
13
  }
13
14
  },
14
15
  authenticated: false,
15
- _meta: {
16
- lastStatsReset: new Date(),
17
- lastUserFetch: new Date(),
16
+ _APIManager: {
17
+ meta: {
18
+ lastStatsReset: new Date(),
19
+ lastUserFetch: new Date(),
20
+ }
18
21
  }
19
22
  }
20
23
 
21
- function ApiManager() {
24
+ function ApiManager(m) {
22
25
  const self = this;
26
+ self.Manager = m;
23
27
  self.options = {
24
- planData: {},
28
+ appId: '',
29
+ plans: {},
25
30
  maxUsersStored: 10000,
26
31
  refetchInterval: 60,
27
32
  resetInterval: 60 * 24,
@@ -33,27 +38,71 @@ function ApiManager() {
33
38
 
34
39
  ApiManager.prototype.init = function (options) {
35
40
  const self = this;
36
- options = options || {};
37
- options.planData = options.planData || {};
38
- options.planData.basic = options.planData.basic || {requests: 93};
41
+ return new Promise(async function(resolve, reject) {
42
+ options = options || {};
43
+ options.app = options.app || '';
44
+ options.plans = options.plans || {};
45
+
46
+ // await self.Manager.libraries.admin.firestore
47
+ // options.plans.basic = options.plans.basic || {requests: 100};
48
+
49
+ options.maxUsersStored = options.maxUsersStored || 10000;
50
+ options.refetchInterval = options.refetchInterval || 60;
51
+ options.resetInterval = options.resetInterval || (60 * 24);
52
+ options.officialAPIKeys = options.officialAPIKeys || [];
53
+ options.whitelistedAPIKeys = options.whitelistedAPIKeys || [];
39
54
 
40
- options.maxUsersStored = options.maxUsersStored || 10000;
41
- options.refetchInterval = options.refetchInterval || 60;
42
- options.resetInterval = options.resetInterval || (60 * 24);
43
- options.officialAPIKeys = options.officialAPIKeys || [];
55
+ await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
56
+ method: 'POST',
57
+ headers: { 'Content-Type': 'application/json' },
58
+ body: JSON.stringify({
59
+ id: options.app,
60
+ }),
61
+ })
62
+ .then(res => {
63
+ res.text()
64
+ .then(text => {
65
+ if (res.ok) {
66
+ const data = JSON.parse(text);
44
67
 
45
- self.options = options;
68
+ options.plans = {};
46
69
 
47
- self.initialized = true;
70
+ Object.keys(data.products)
71
+ .forEach((id, i) => {
72
+ const product = data.products[id]
73
+ options.plans[product.planId] = {}
74
+ options.plans[product.planId].limits = product.limits || {};
75
+ });
48
76
 
49
- return self;
77
+ self.options = options;
78
+ self.initialized = true;
79
+
80
+ return resolve(self);
81
+ } else {
82
+ throw new Error(text || res.statusText || 'Unknown error.')
83
+ }
84
+ })
85
+ })
86
+ .catch(e => {
87
+ return reject(e)
88
+ })
89
+ });
50
90
  };
51
91
 
52
- ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persistentData, isRefetch) {
92
+ ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persistentData, isRefetch, apiKey) {
53
93
  const self = this;
94
+ const _APIManager_default = {
95
+ stats: {
96
+ requests: 0,
97
+ },
98
+ meta: {
99
+ lastStatsReset: new Date(),
100
+ lastUserFetch: new Date(),
101
+ },
102
+ providedAPIKey: apiKey,
103
+ }
54
104
  persistentData = persistentData || {};
55
- persistentData._meta = persistentData._meta || {};
56
- persistentData._stats = persistentData._stats || {};
105
+ persistentData._APIManager = persistentData._APIManager || merge({}, _APIManager_default);
57
106
 
58
107
  let newUser = {
59
108
  api: get(authenticatedUser, 'api', {}),
@@ -61,35 +110,43 @@ ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persi
61
110
  plan: {
62
111
  id: planId,
63
112
  limits: {
64
- requests: get(authenticatedUser, 'plan.limits.requests', get(self.options, `planData.${planId}.limits.requests`, 93)),
65
113
  }
66
114
  },
67
115
  authenticated: authenticatedUser.authenticated,
68
116
  ip: authenticatedUser.ip,
69
117
  country: authenticatedUser.country,
70
- _stats: {
71
- requests: 0,
72
- },
73
- _meta: {
74
- lastStatsReset: new Date(),
75
- lastUserFetch: new Date(),
76
- }
118
+ _APIManager: merge({}, _APIManager_default),
77
119
  }
78
- // console.log('-----MIN', moment().diff(moment(persistentData._meta.lastStatsReset), 'minutes', true), self.options.resetInterval);
79
- if (moment().diff(moment(persistentData._meta.lastStatsReset), 'minutes', true) < self.options.resetInterval) {
80
- newUser._meta.lastStatsReset = persistentData._meta.lastStatsReset || newUser._meta.lastStatsReset;
81
- newUser._meta.lastUserFetch = persistentData._meta.lastUserFetch || newUser._meta.lastUserFetch;
82
- Object.keys(persistentData._stats)
120
+
121
+ // Setup newUser
122
+ const currentPlan = get(self.options, `plans.${planId}.limits`, {})
123
+ Object.keys(currentPlan)
124
+ .forEach((id, i) => {
125
+ // console.log('----id', id);
126
+ // console.log('======currentPlan[id]', currentPlan[id]);
127
+ newUser.plan.limits[id] = get(authenticatedUser, `plan.limits.${id}`, currentPlan[id])
128
+ // const product = data.products[id]
129
+ // options.plans[product.planId] = {}
130
+ // options.plans[product.planId].limits = product.limits || {};
131
+ });
132
+
133
+
134
+
135
+ // console.log('-----MIN', moment().diff(moment(persistentData._APIManager.meta.lastStatsReset), 'minutes', true), self.options.resetInterval);
136
+ if (moment().diff(moment(persistentData._APIManager.meta.lastStatsReset), 'minutes', true) < self.options.resetInterval) {
137
+ newUser._APIManager.meta.lastStatsReset = persistentData._APIManager.meta.lastStatsReset || newUser._APIManager.meta.lastStatsReset;
138
+ newUser._APIManager.meta.lastUserFetch = persistentData._APIManager.meta.lastUserFetch || newUser._APIManager.meta.lastUserFetch;
139
+ Object.keys(persistentData._APIManager.stats)
83
140
  .forEach((key, i) => {
84
- newUser._stats[key] = persistentData._stats[key];
141
+ newUser._APIManager.stats[key] = persistentData._APIManager.stats[key];
85
142
  });
86
143
  } else {
87
144
  // console.log('---RESSET INTERVAL REACHED');
88
- newUser._meta.lastUserFetch = persistentData._meta.lastUserFetch;
145
+ newUser._APIManager.meta.lastUserFetch = persistentData._APIManager.meta.lastUserFetch;
89
146
  }
90
147
 
91
148
  if (isRefetch) {
92
- newUser._meta.lastUserFetch = new Date();
149
+ newUser._APIManager.meta.lastUserFetch = new Date();
93
150
  }
94
151
 
95
152
  return newUser;
@@ -106,14 +163,14 @@ ApiManager.prototype.getUser = async function (assistant) {
106
163
  if (apiKey) {
107
164
  newUser = self.userList.filter(user => user.api.privateKey === apiKey);
108
165
  if (newUser[0]) {
109
- if (newUser.length > 1 || moment().diff(moment(newUser[0]._meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
166
+ if (newUser.length > 1 || moment().diff(moment(newUser[0]._APIManager.meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
110
167
  // console.log('----REFETCHING');
111
- persistentData = {set: true, _stats: merge({}, newUser[0]._stats), _meta: merge({}, newUser[0]._meta)};
168
+ persistentData = {set: true, _APIManager: merge({}, newUser[0]._APIManager)};
112
169
 
113
170
  self.userList = self.userList.filter(user => user.api.privateKey !== apiKey)
114
171
  newUser = null;
115
172
  } else {
116
- persistentData = {set: true, _stats: merge({}, newUser[0]._stats), _meta: merge({}, newUser[0]._meta)};
173
+ persistentData = {set: true, _APIManager: merge({}, newUser[0]._APIManager)};
117
174
 
118
175
  newUser = newUser[0];
119
176
  }
@@ -139,20 +196,20 @@ ApiManager.prototype.getUser = async function (assistant) {
139
196
  let existingUser = self.userList.find(user => user.auth.uid === workingUID);
140
197
  if (existingUser) {
141
198
  // console.log('---actually does exist so setting');
142
- // console.log('----1111 MIN lastUserFetch', moment().diff(moment(existingUser._meta.lastUserFetch), 'minutes', true), self.options.refetchInterval);
143
- persistentData = !persistentData.set ? {set: true, _stats: merge({}, existingUser._stats), _meta: merge({}, existingUser._meta)} : persistentData;
199
+ // console.log('----1111 MIN lastUserFetch', moment().diff(moment(existingUser._APIManager.meta.lastUserFetch), 'minutes', true), self.options.refetchInterval);
200
+ persistentData = !persistentData.set ? {set: true, _APIManager: merge({}, existingUser._APIManager)} : persistentData;
144
201
  // console.log('----persistentData 2', persistentData);
145
- if (moment().diff(moment(existingUser._meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
202
+ if (moment().diff(moment(existingUser._APIManager.meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
146
203
  // console.log('----REFETCHING');
147
204
  self.userList = self.userList.filter(user => user.auth.uid !== workingUID)
148
- existingUser = self._createNewUser(authenticatedUser, planId, persistentData, true);
205
+ existingUser = self._createNewUser(authenticatedUser, planId, persistentData, true, apiKey);
149
206
  existingUser.auth.uid = workingUID;
150
207
  self.userList = self.userList.concat(existingUser);
151
208
  }
152
209
  newUser = existingUser
153
210
  } else {
154
211
  // console.log('---actually doesnt exist making new user');
155
- newUser = self._createNewUser(authenticatedUser, planId, persistentData)
212
+ newUser = self._createNewUser(authenticatedUser, planId, persistentData, false, apiKey)
156
213
  newUser.auth.uid = workingUID;
157
214
  self.userList = self.userList.concat(newUser);
158
215
  }
@@ -164,27 +221,56 @@ ApiManager.prototype.getUser = async function (assistant) {
164
221
 
165
222
  };
166
223
 
167
- ApiManager.prototype.getUserStat = function (user, stat, def) {
224
+ function _getUserStat(self, user, stat, def) {
225
+ const isWhitelistedAPIKey = self.options.whitelistedAPIKeys.includes(
226
+ get(user, `api.privateKey`, get(user, `_APIManager.providedAPIKey`))
227
+ );
228
+ // console.log('----user', user);
229
+ // console.log('----isWhitelistedAPIKey', isWhitelistedAPIKey);
230
+ return {
231
+ current: !isWhitelistedAPIKey ? get(user, `_APIManager.stats.${stat}`, typeof def !== 'undefined' ? def : 0) : 0,
232
+ limit: !isWhitelistedAPIKey ? get(user, `plan.limits.${stat}`, typeof def !== 'undefined' ? def : 0) : Infinity,
233
+ }
234
+ }
235
+
236
+ ApiManager.prototype.isUserOverStat = function (user, stat, def, frame) {
168
237
  const self = this;
169
238
  if (!user || !stat) {
170
239
  throw new Error('<user> and <stat> required')
171
240
  }
172
- return {
173
- current: get(user, `_stats.${stat}`, def || 0),
174
- limit: get(user, `plan.limits.${stat}`, def || 0),
241
+ const result = self.getUserStat(user, stat, def);
242
+ frame = frame || 'daily';
243
+ let limit = result.limit;
244
+ // console.log('---result', result);
245
+ // console.log('---typeof result.current', typeof result.current);
246
+ // console.log('----limit', limit);
247
+ if (typeof result.limit === 'number') {
248
+ if (frame === 'daily') {
249
+ limit = Math.floor(result.limit / 31);
250
+ }
251
+ // console.log('----limit', limit);
252
+ // console.log('-----result.current < limit', result.current < limit);
253
+ return limit >= result.current;
175
254
  }
255
+
256
+ return false;
176
257
  }
177
258
 
178
- ApiManager.prototype.incrementUserStat = function (user, stat, amount) {
259
+ ApiManager.prototype.getUserStat = function (user, stat, def, ) {
179
260
  const self = this;
180
261
  if (!user || !stat) {
181
262
  throw new Error('<user> and <stat> required')
182
263
  }
183
- set(user, `_stats.${stat}`, get(user, `_stats.${stat}`, 0) + amount)
184
- return {
185
- current: get(user, `_stats.${stat}`, 0),
186
- limit: get(user, `plan.limits.${stat}`, 0),
264
+ return _getUserStat(self, user, stat, def);
265
+ }
266
+
267
+ ApiManager.prototype.incrementUserStat = function (user, stat, amount) {
268
+ const self = this;
269
+ if (!user || !stat) {
270
+ throw new Error('<user> and <stat> required')
187
271
  }
272
+ set(user, `_APIManager.stats.${stat}`, get(user, `_APIManager.stats.${stat}`, 0) + amount)
273
+ return _getUserStat(self, user, stat, 0);
188
274
  }
189
275
 
190
276