backend-manager 3.2.84 → 3.2.86

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": "3.2.84",
3
+ "version": "3.2.86",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
@@ -71,4 +71,4 @@
71
71
  "wonderful-log": "^1.0.5",
72
72
  "yargs": "^17.7.2"
73
73
  }
74
- }
74
+ }
@@ -5,8 +5,16 @@ const uuid = require('uuid');
5
5
  let JSON5;
6
6
 
7
7
  function BackendAssistant() {
8
- this.meta = {};
9
- this.initialized = false;
8
+ const self = this;
9
+
10
+ // Set ref
11
+ self.meta = {};
12
+ self.initialized = false;
13
+
14
+ // Add log methods
15
+ addLogMethods();
16
+
17
+ return self;
10
18
  }
11
19
 
12
20
  function tryParse(input) {
@@ -223,68 +231,21 @@ BackendAssistant.prototype.log = function () {
223
231
  self._log.apply(self, args);
224
232
  };
225
233
 
226
- BackendAssistant.prototype.error = function () {
227
- const self = this;
234
+ function addLogMethods() {
235
+ const levels = ['error', 'warn', 'info', 'debug', 'notice', 'critical', 'emergency'];
228
236
 
229
- const args = Array.prototype.slice.call(arguments);
230
-
231
- args.unshift('error');
232
- self.log.apply(self, args);
233
- };
234
-
235
- BackendAssistant.prototype.warn = function () {
236
- const self = this;
237
-
238
- const args = Array.prototype.slice.call(arguments);
239
-
240
- args.unshift('warn');
241
- self.log.apply(self, args);
242
- };
243
-
244
- BackendAssistant.prototype.info = function () {
245
- const self = this;
246
-
247
- const args = Array.prototype.slice.call(arguments);
248
-
249
- args.unshift('info');
250
- self.log.apply(self, args);
251
- };
252
-
253
- BackendAssistant.prototype.debug = function () {
254
- const self = this;
255
-
256
- const args = Array.prototype.slice.call(arguments);
257
-
258
- args.unshift('debug');
259
- self.log.apply(self, args);
260
- };
237
+ // Add log methods
238
+ levels.forEach((level) => {
239
+ BackendAssistant.prototype[level] = function() {
240
+ const self = this;
241
+ const args = Array.prototype.slice.call(arguments);
261
242
 
262
- BackendAssistant.prototype.notice = function () {
263
- const self = this;
264
-
265
- const args = Array.prototype.slice.call(arguments);
266
-
267
- args.unshift('notice');
268
- self.log.apply(self, args);
269
- };
270
-
271
- BackendAssistant.prototype.critical = function () {
272
- const self = this;
273
-
274
- const args = Array.prototype.slice.call(arguments);
275
-
276
- args.unshift('critical');
277
- self.log.apply(self, args);
278
- };
279
-
280
- BackendAssistant.prototype.emergency = function () {
281
- const self = this;
282
-
283
- const args = Array.prototype.slice.call(arguments);
284
-
285
- args.unshift('emergency');
286
- self.log.apply(self, args);
287
- };
243
+ // Prepend level to args
244
+ args.unshift(level);
245
+ self.log.apply(this, args);
246
+ };
247
+ });
248
+ }
288
249
 
289
250
  BackendAssistant.prototype._log = function () {
290
251
  const self = this;
@@ -388,7 +349,7 @@ BackendAssistant.prototype.errorify = function (e, options) {
388
349
  // Construct error
389
350
  const newError = e instanceof Error
390
351
  ? e
391
- : new Error(stringify(e));
352
+ : new Error(stringifyNonStrings(e));
392
353
 
393
354
  // Fix code
394
355
  // options.code = newError.code || options.code;
@@ -513,7 +474,7 @@ function isBetween(value, min, max) {
513
474
  return value >= min && value <= max;
514
475
  }
515
476
 
516
- function stringify(e) {
477
+ function stringifyNonStrings(e) {
517
478
  if (typeof e === 'string') {
518
479
  return e;
519
480
  } else {
@@ -981,30 +942,33 @@ BackendAssistant.prototype.parseMultipartFormData = function (options) {
981
942
  });
982
943
  }
983
944
 
984
- function stringify(obj, replacer, spaces, cycleReplacer) {
985
- return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
986
- }
987
-
988
- // https://github.com/moll/json-stringify-safe/blob/master/stringify.js
989
- function serializer(replacer, cycleReplacer) {
990
- var stack = [], keys = []
991
-
992
- if (cycleReplacer == null) cycleReplacer = function(key, value) {
993
- if (stack[0] === value) return '[Circular ~]'
994
- return `[Circular ~.${keys.slice(0, stack.indexOf(value)).join('.')}]`;
995
- }
996
-
997
- return function(key, value) {
998
- if (stack.length > 0) {
999
- var thisPos = stack.indexOf(this)
1000
- ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
1001
- ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
1002
- if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
1003
- }
1004
- else stack.push(value)
1005
-
1006
- return replacer == null ? value : replacer.call(this, key, value)
1007
- }
1008
- }
945
+ // Not sure what this is for? But it has a good serializer code
946
+ // Disabled 2024-03-21 because there was another stringify() function that i was intending to use but it was actually using this
947
+ // It was adding escaped quotes to strings
948
+ // function stringify(obj, replacer, spaces, cycleReplacer) {
949
+ // return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
950
+ // }
951
+
952
+ // // https://github.com/moll/json-stringify-safe/blob/master/stringify.js
953
+ // function serializer(replacer, cycleReplacer) {
954
+ // var stack = [], keys = []
955
+
956
+ // if (cycleReplacer == null) cycleReplacer = function(key, value) {
957
+ // if (stack[0] === value) return '[Circular ~]'
958
+ // return `[Circular ~.${keys.slice(0, stack.indexOf(value)).join('.')}]`;
959
+ // }
960
+
961
+ // return function(key, value) {
962
+ // if (stack.length > 0) {
963
+ // var thisPos = stack.indexOf(this)
964
+ // ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
965
+ // ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
966
+ // if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
967
+ // }
968
+ // else stack.push(value)
969
+
970
+ // return replacer == null ? value : replacer.call(this, key, value)
971
+ // }
972
+ // }
1009
973
 
1010
974
  module.exports = BackendAssistant;
@@ -34,6 +34,7 @@ Middleware.prototype.run = function (libPath, options) {
34
34
  options.setupAnalytics = typeof options.setupAnalytics === 'boolean' ? options.setupAnalytics : true;
35
35
  options.setupUsage = typeof options.setupUsage === 'boolean' ? options.setupUsage : true;
36
36
  options.setupSettings = typeof options.setupSettings === 'undefined' ? true : options.setupSettings;
37
+ options.cleanSettings = typeof options.cleanSettings === 'undefined' ? true : options.cleanSettings;
37
38
  options.schema = typeof options.schema === 'undefined' ? undefined : options.schema;
38
39
 
39
40
  // Log
@@ -80,12 +81,19 @@ Middleware.prototype.run = function (libPath, options) {
80
81
  if (options.setupSettings) {
81
82
  // assistant.log(`Middleware.process(): Resolving settings with schema ${options.schema}...`);
82
83
 
84
+ // Resolve settings
83
85
  try {
84
86
  assistant.settings = Manager.Settings().resolve(assistant, options.schema, data);
85
87
  } catch (e) {
86
88
  return assistant.respond(new Error(`Unable to resolve schema ${options.schema}: ${e.message}`), {code: 500, sentry: true});
87
89
  }
88
90
 
91
+ // Clean settings by looping through and trimming all strings
92
+ if (options.cleanSettings) {
93
+ clean(assistant.settings);
94
+ }
95
+
96
+ // Log
89
97
  assistant.log(`Middleware.process(): Resolved settings with schema ${options.schema}`, JSON.stringify(assistant.settings));
90
98
  }
91
99
 
@@ -106,4 +114,15 @@ Middleware.prototype.run = function (libPath, options) {
106
114
  });
107
115
  };
108
116
 
117
+ function clean(obj) {
118
+ for (let key in obj) {
119
+ if (typeof obj[key] === 'object') {
120
+ clean(obj[key]);
121
+ } else if (typeof obj[key] === 'string') {
122
+ obj[key] = obj[key]
123
+ .trim();
124
+ }
125
+ }
126
+ }
127
+
109
128
  module.exports = Middleware;
@@ -42,22 +42,36 @@ Settings.prototype.resolve = function (assistant, schema, settings) {
42
42
  // Resolve settings
43
43
  self.settings = powertools.defaults(settings, schema);
44
44
 
45
- // Check for missing required keys
46
- powertools.getKeys(schema).forEach((key) => {
47
- const isRequired = key.endsWith('.required') ? _.get(schema, key, false) : false;
45
+ // Iterate each key and check for some things
46
+ processSchema(schema, (path, schemaNode) => {
47
+ const originalValue = _.get(settings, path);
48
+ const resolvedValue = _.get(self.settings, path);
49
+ let replaceValue = undefined;
50
+
51
+ // assistant.log('Found:', path, schemaNode);
52
+ // assistant.log('originalValue:', originalValue);
53
+ // assistant.log('resolvedValue:', resolvedValue);
54
+
55
+ // Check if this node is marked as required
56
+ if (schemaNode.required && typeof originalValue === 'undefined') {
57
+ throw assistant.errorify(`Required key {${path}} is missing in settings`, {code: 400});
58
+ }
48
59
 
49
- // Skip if not required
50
- if (!isRequired) {
51
- return;
60
+ // Clean
61
+ if (schemaNode.clean) {
62
+ if (schemaNode.clean instanceof RegExp) {
63
+ replaceValue = resolvedValue.replace(schemaNode.clean, '');
64
+ } else if (typeof schemaNode.clean === 'function') {
65
+ replaceValue = schemaNode.clean(resolvedValue);
66
+ }
52
67
  }
53
68
 
54
- // Use regex to replace '.required' only if it's at the end of the string
55
- const settingsKey = key.replace(/\.required$/, '');
69
+ // assistant.log('replaceValue:', replaceValue);
56
70
 
57
- // Check if the required key is missing
58
- if (typeof _.get(settings, settingsKey, undefined) === 'undefined') {
59
- // Handle the missing required key as needed
60
- throw assistant.errorify(`Required key '${settingsKey}' is missing in settings`, {code: 400});
71
+ // Replace
72
+ if (typeof replaceValue !== 'undefined' && replaceValue !== resolvedValue) {
73
+ assistant.warn(`Replacing ${path}: originalValue=${originalValue}, resolvedValue=${resolvedValue}, replaceValue=${replaceValue}`);
74
+ _.set(self.settings, path, replaceValue);
61
75
  }
62
76
  });
63
77
 
@@ -92,6 +106,23 @@ Settings.prototype.constant = function (name, options) {
92
106
  }
93
107
  };
94
108
 
109
+ function processSchema(schema, fn, path) {
110
+ path = path || '';
111
+
112
+ // Base case: Check if the current level has 'types' and 'default', indicating metadata
113
+ if (schema.hasOwnProperty('types') && schema.hasOwnProperty('default')) {
114
+ // Call the processing function with the current path and schema as arguments
115
+ fn(path, schema);
116
+ return;
117
+ }
118
+
119
+ // Recursive case: Iterate through nested keys if we're not at a metadata node
120
+ Object.keys(schema).forEach(key => {
121
+ const nextPath = path ? `${path}.${key}` : key;
122
+ processSchema(schema[key], fn, nextPath);
123
+ });
124
+ }
125
+
95
126
  function loadSchema(assistant, schema, settings) {
96
127
  const planId = assistant.request.user.plan.id;
97
128
 
@@ -167,6 +167,13 @@ OpenAI.prototype.request = function (options) {
167
167
  return reject(assistant.errorify(`Error loading message: ${message}`, {code: 400}));
168
168
  }
169
169
 
170
+ // Format history
171
+ options.history.messages.forEach((m) => {
172
+ m.role = m.role || 'system';
173
+ m.content = (m.content || '').trim();
174
+ });
175
+
176
+ // Request
170
177
  function _request(mode, options) {
171
178
  return new Promise(async function(resolve, reject) {
172
179
  let resultPath = '';
@@ -190,10 +197,17 @@ OpenAI.prototype.request = function (options) {
190
197
  role: 'system',
191
198
  content: prompt,
192
199
  });
193
- options.history.messages.push({
194
- role: 'user',
195
- content: message,
196
- });
200
+
201
+ // Set last history item
202
+ const lastHistory = options.history.messages[options.history.messages.length - 1];
203
+
204
+ // If message is different than last message in history, add it
205
+ if (lastHistory?.content !== message) {
206
+ options.history.messages.push({
207
+ role: 'user',
208
+ content: message,
209
+ });
210
+ }
197
211
 
198
212
  // Log message
199
213
  _log('Messages', options.history.messages);