backend-manager 3.2.169 → 3.2.171
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/cli/cli.js +1534 -0
- package/dist/manager/functions/core/actions/api/admin/backup.js +338 -0
- package/dist/manager/functions/core/actions/api/admin/create-post.js +388 -0
- package/dist/manager/functions/core/actions/api/admin/cron.js +37 -0
- package/dist/manager/functions/core/actions/api/admin/database-read.js +35 -0
- package/dist/manager/functions/core/actions/api/admin/database-write.js +39 -0
- package/dist/manager/functions/core/actions/api/admin/edit-post.js +158 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-query.js +165 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-read.js +38 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-write.js +54 -0
- package/dist/manager/functions/core/actions/api/admin/get-stats.js +269 -0
- package/dist/manager/functions/core/actions/api/admin/payment-processor.js +57 -0
- package/dist/manager/functions/core/actions/api/admin/run-hook.js +95 -0
- package/dist/manager/functions/core/actions/api/admin/send-notification.js +197 -0
- package/dist/manager/functions/core/actions/api/admin/sync-users.js +125 -0
- package/dist/manager/functions/core/actions/api/admin/templates/post.html +16 -0
- package/dist/manager/functions/core/actions/api/firebase/get-providers.js +102 -0
- package/dist/manager/functions/core/actions/api/general/emails/general:download-app-link.js +21 -0
- package/dist/manager/functions/core/actions/api/general/fetch-post.js +99 -0
- package/dist/manager/functions/core/actions/api/general/generate-uuid.js +41 -0
- package/dist/manager/functions/core/actions/api/general/send-email.js +112 -0
- package/dist/manager/functions/core/actions/api/handler/create-post.js +146 -0
- package/dist/manager/functions/core/actions/api/special/setup-electron-manager-client.js +103 -0
- package/dist/manager/functions/core/actions/api/template.js +33 -0
- package/dist/manager/functions/core/actions/api/test/authenticate.js +22 -0
- package/dist/manager/functions/core/actions/api/test/create-test-accounts.js +27 -0
- package/dist/manager/functions/core/actions/api/test/lab.js +55 -0
- package/dist/manager/functions/core/actions/api/test/redirect.js +26 -0
- package/dist/manager/functions/core/actions/api/test/webhook.js +30 -0
- package/dist/manager/functions/core/actions/api/user/create-custom-token.js +32 -0
- package/dist/manager/functions/core/actions/api/user/delete.js +68 -0
- package/dist/manager/functions/core/actions/api/user/get-active-sessions.js +45 -0
- package/dist/manager/functions/core/actions/api/user/get-subscription-info.js +49 -0
- package/dist/manager/functions/core/actions/api/user/oauth2/discord.js +114 -0
- package/dist/manager/functions/core/actions/api/user/oauth2/google.js +99 -0
- package/dist/manager/functions/core/actions/api/user/oauth2.js +476 -0
- package/dist/manager/functions/core/actions/api/user/regenerate-api-keys.js +54 -0
- package/dist/manager/functions/core/actions/api/user/resolve.js +32 -0
- package/dist/manager/functions/core/actions/api/user/sign-out-all-sessions.js +118 -0
- package/dist/manager/functions/core/actions/api/user/sign-up copy.js +544 -0
- package/dist/manager/functions/core/actions/api/user/sign-up.js +99 -0
- package/dist/manager/functions/core/actions/api/user/submit-feedback.js +96 -0
- package/dist/manager/functions/core/actions/api/user/validate-settings.js +86 -0
- package/dist/manager/functions/core/actions/api.js +354 -0
- package/dist/manager/functions/core/actions/create-post-handler.js +184 -0
- package/dist/manager/functions/core/actions/generate-uuid.js +62 -0
- package/dist/manager/functions/core/actions/sign-up-handler.js +205 -0
- package/dist/manager/functions/core/admin/create-post.js +206 -0
- package/dist/manager/functions/core/admin/firestore-write.js +72 -0
- package/dist/manager/functions/core/admin/get-stats.js +218 -0
- package/dist/manager/functions/core/admin/query.js +198 -0
- package/dist/manager/functions/core/admin/send-notification.js +206 -0
- package/dist/manager/functions/core/cron/daily/ghostii-auto-publisher.js +377 -0
- package/dist/manager/functions/core/cron/daily/reset-usage.js +197 -0
- package/dist/manager/functions/core/cron/daily.js +114 -0
- package/dist/manager/functions/core/events/auth/before-create.js +124 -0
- package/dist/manager/functions/core/events/auth/before-signin.js +62 -0
- package/dist/manager/functions/core/events/auth/on-create copy.js +121 -0
- package/dist/manager/functions/core/events/auth/on-create.js +564 -0
- package/dist/manager/functions/core/events/auth/on-delete.js +72 -0
- package/dist/manager/functions/core/events/firestore/on-subscription.js +107 -0
- package/dist/manager/functions/test/authenticate.js +38 -0
- package/dist/manager/functions/test/create-test-accounts.js +144 -0
- package/dist/manager/functions/test/webhook.js +37 -0
- package/dist/manager/functions/wrappers/mailchimp/addToList.js +25 -0
- package/dist/manager/helpers/analytics copy.js +217 -0
- package/dist/manager/helpers/analytics.js +467 -0
- package/dist/manager/helpers/api-manager.js +324 -0
- package/dist/manager/helpers/assistant.js +1043 -0
- package/dist/manager/helpers/metadata.js +32 -0
- package/dist/manager/helpers/middleware.js +154 -0
- package/dist/manager/helpers/roles.js +69 -0
- package/dist/manager/helpers/settings.js +158 -0
- package/dist/manager/helpers/subscription-resolver-new.js +828 -0
- package/dist/manager/helpers/subscription-resolver.js +842 -0
- package/dist/manager/helpers/usage.js +381 -0
- package/dist/manager/helpers/user.js +198 -0
- package/dist/manager/helpers/utilities.js +292 -0
- package/dist/manager/index.js +1076 -0
- package/dist/manager/libraries/openai.js +460 -0
- package/dist/manager/routes/restart/index.js +52 -0
- package/dist/manager/routes/test/index.js +43 -0
- package/dist/manager/schemas/restart.js +13 -0
- package/dist/manager/schemas/test.js +13 -0
- package/dist/require.js +3 -0
- package/package.json +19 -9
|
@@ -0,0 +1,1076 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { get, merge } = require('lodash');
|
|
4
|
+
const jetpack = require('fs-jetpack');
|
|
5
|
+
const JSON5 = require('json5');
|
|
6
|
+
const EventEmitter = require('events');
|
|
7
|
+
// const EventEmitter = require('events').EventEmitter;
|
|
8
|
+
const util = require('util');
|
|
9
|
+
|
|
10
|
+
// const { debug, log, error, warn } = require('firebase-functions/lib/logger');
|
|
11
|
+
// let User;
|
|
12
|
+
// let Analytics;
|
|
13
|
+
// Paths
|
|
14
|
+
const core = './functions/core';
|
|
15
|
+
const wrappers = './functions/wrappers';
|
|
16
|
+
|
|
17
|
+
const BEM_CONFIG_TEMPLATE_PATH = path.resolve(__dirname, '../../templates/backend-manager-config.json');
|
|
18
|
+
|
|
19
|
+
function Manager(exporter, options) {
|
|
20
|
+
const self = this;
|
|
21
|
+
|
|
22
|
+
// Constants
|
|
23
|
+
self.SERVER_UUID = '11111111-1111-1111-1111-111111111111';
|
|
24
|
+
|
|
25
|
+
// Modable
|
|
26
|
+
self.libraries = {};
|
|
27
|
+
self.handlers = {};
|
|
28
|
+
|
|
29
|
+
self._internal = {
|
|
30
|
+
storage: {},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
self.interface = {}
|
|
34
|
+
|
|
35
|
+
// Setup EventEmitter
|
|
36
|
+
EventEmitter.call(self);
|
|
37
|
+
|
|
38
|
+
// Return
|
|
39
|
+
return self;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Inherit from EventEmitter
|
|
43
|
+
util.inherits(Manager, EventEmitter);
|
|
44
|
+
|
|
45
|
+
Manager.prototype.init = function (exporter, options) {
|
|
46
|
+
const self = this;
|
|
47
|
+
|
|
48
|
+
// Set options defaults
|
|
49
|
+
options = options || {};
|
|
50
|
+
options.initialize = typeof options.initialize === 'undefined' ? true : options.initialize;
|
|
51
|
+
options.log = typeof options.log === 'undefined' ? false : options.log;
|
|
52
|
+
options.projectType = typeof options.projectType === 'undefined' ? 'firebase' : options.projectType; // firebase, custom
|
|
53
|
+
options.routes = typeof options.routes === 'undefined' ? '/routes' : options.routes;
|
|
54
|
+
options.schemas = typeof options.schemas === 'undefined' ? '/schemas' : options.schemas;
|
|
55
|
+
options.setupFunctions = typeof options.setupFunctions === 'undefined' ? true : options.setupFunctions;
|
|
56
|
+
options.setupFunctionsLegacy = typeof options.setupFunctionsLegacy === 'undefined' ? false : options.setupFunctionsLegacy;
|
|
57
|
+
options.setupFunctionsIdentity = typeof options.setupFunctionsIdentity === 'undefined' ? true : options.setupFunctionsIdentity;
|
|
58
|
+
options.setupServer = typeof options.setupServer === 'undefined' ? true : options.setupServer;
|
|
59
|
+
options.initializeLocalStorage = typeof options.initializeLocalStorage === 'undefined' ? false : options.initializeLocalStorage;
|
|
60
|
+
options.resourceZone = typeof options.resourceZone === 'undefined' ? 'us-central1' : options.resourceZone;
|
|
61
|
+
options.sentry = typeof options.sentry === 'undefined' ? true : options.sentry;
|
|
62
|
+
options.reportErrorsInDev = typeof options.reportErrorsInDev === 'undefined' ? false : options.reportErrorsInDev;
|
|
63
|
+
options.firebaseConfig = options.firebaseConfig;
|
|
64
|
+
options.useFirebaseLogger = typeof options.useFirebaseLogger === 'undefined' ? true : options.useFirebaseLogger;
|
|
65
|
+
options.serviceAccountPath = typeof options.serviceAccountPath === 'undefined' ? 'service-account.json' : options.serviceAccountPath;
|
|
66
|
+
options.backendManagerConfigPath = typeof options.backendManagerConfigPath === 'undefined' ? 'backend-manager-config.json' : options.backendManagerConfigPath;
|
|
67
|
+
options.fetchStats = typeof options.fetchStats === 'undefined' ? true : options.fetchStats;
|
|
68
|
+
options.checkNodeVersion = typeof options.checkNodeVersion === 'undefined' ? true : options.checkNodeVersion;
|
|
69
|
+
options.uniqueAppName = options.uniqueAppName || undefined;
|
|
70
|
+
options.assistant = options.assistant || {};
|
|
71
|
+
options.cwd = typeof options.cwd === 'undefined' ? process.cwd() : options.cwd;
|
|
72
|
+
options.projectPackageDirectory = typeof options.projectPackageDirectory === 'undefined' ? undefined : options.projectPackageDirectory;
|
|
73
|
+
// options.assistant.optionsLogString = options.assistant.optionsLogString || undefined;
|
|
74
|
+
|
|
75
|
+
// Load libraries
|
|
76
|
+
self.libraries = {
|
|
77
|
+
// Third-party
|
|
78
|
+
functions: options.projectType === 'firebase'
|
|
79
|
+
? require('firebase-functions')
|
|
80
|
+
: null,
|
|
81
|
+
admin: require('firebase-admin'),
|
|
82
|
+
cors: require('cors')({ origin: true }),
|
|
83
|
+
sentry: null,
|
|
84
|
+
|
|
85
|
+
// First-party
|
|
86
|
+
Assistant: require('./helpers/assistant.js'),
|
|
87
|
+
localDatabase: null,
|
|
88
|
+
User: null,
|
|
89
|
+
Analytics: null,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Set properties
|
|
93
|
+
self.cwd = options.cwd;
|
|
94
|
+
self.rootDirectory = __dirname;
|
|
95
|
+
|
|
96
|
+
// Set options
|
|
97
|
+
self.options = options;
|
|
98
|
+
self.project = options.firebaseConfig || JSON.parse(process.env.FIREBASE_CONFIG || '{}');
|
|
99
|
+
self.project.resourceZone = options.resourceZone;
|
|
100
|
+
self.project.serviceAccountPath = path.resolve(self.cwd, options.serviceAccountPath);
|
|
101
|
+
self.project.backendManagerConfigPath = path.resolve(self.cwd, options.backendManagerConfigPath);
|
|
102
|
+
|
|
103
|
+
// Load package.json
|
|
104
|
+
self.package = resolveProjectPackage(options.projectPackageDirectory || self.cwd);
|
|
105
|
+
|
|
106
|
+
// Load config
|
|
107
|
+
self.config = merge(
|
|
108
|
+
// Load basic config
|
|
109
|
+
merge({}, requireJSON5(BEM_CONFIG_TEMPLATE_PATH, true), requireJSON5(self.project.backendManagerConfigPath, true)),
|
|
110
|
+
// Load ENV config as a fallback
|
|
111
|
+
requireJSON5(path.resolve(self.cwd, '.runtimeconfig.json'), options.projectType === 'firebase'),
|
|
112
|
+
// Finally, load the functions config
|
|
113
|
+
self.libraries.functions
|
|
114
|
+
? self.libraries.functions.config()
|
|
115
|
+
: {},
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Get app ID
|
|
119
|
+
const appId = self.config?.app?.id;
|
|
120
|
+
|
|
121
|
+
// Init assistant
|
|
122
|
+
self.assistant = self.Assistant().init(undefined, options.assistant);
|
|
123
|
+
|
|
124
|
+
// Set more properties (need to wait for assistant to determine if DEV)
|
|
125
|
+
self.project.functionsUrl = self.assistant.isDevelopment()
|
|
126
|
+
? `http://localhost:5001/${self.project.projectId}/${self.project.resourceZone}`
|
|
127
|
+
: `https://${self.project.resourceZone}-${self.project.projectId}.cloudfunctions.net`;
|
|
128
|
+
|
|
129
|
+
// Set environment
|
|
130
|
+
process.env.ENVIRONMENT = !process.env.ENVIRONMENT
|
|
131
|
+
? self.assistant.meta.environment
|
|
132
|
+
: process.env.ENVIRONMENT;
|
|
133
|
+
|
|
134
|
+
// Use the working Firebase logger that they disabled for whatever reason
|
|
135
|
+
if (
|
|
136
|
+
process.env.GCLOUD_PROJECT
|
|
137
|
+
&& self.assistant.meta.environment !== 'development'
|
|
138
|
+
&& options.useFirebaseLogger
|
|
139
|
+
) {
|
|
140
|
+
// require('firebase-functions/lib/logger/compat'); // Old way
|
|
141
|
+
require('firebase-functions/logger/compat'); // firebase-functions@4 and above?
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle dev environments
|
|
145
|
+
if (self.assistant.isDevelopment()) {
|
|
146
|
+
const semverMajor = require('semver/functions/major')
|
|
147
|
+
const semverCoerce = require('semver/functions/coerce')
|
|
148
|
+
const semverUsing = semverMajor(semverCoerce(process.versions.node));
|
|
149
|
+
const semverRequired = semverMajor(semverCoerce(self.package?.engines?.node || '0.0.0'));
|
|
150
|
+
|
|
151
|
+
// Fix firebase-tools overwriting console.log
|
|
152
|
+
// https://stackoverflow.com/questions/56026747/firebase-console-log-on-localhost
|
|
153
|
+
if (process.env.GCLOUD_PROJECT) {
|
|
154
|
+
function logFix() {
|
|
155
|
+
console.error(...arguments);
|
|
156
|
+
}
|
|
157
|
+
console.log = logFix;
|
|
158
|
+
console.info = logFix;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Reject if package.json does not exist
|
|
162
|
+
if (semverUsing !== semverRequired) {
|
|
163
|
+
const msg = `Node.js version mismatch: using ${semverUsing} but asked for ${semverRequired}`;
|
|
164
|
+
if (options.checkNodeVersion) {
|
|
165
|
+
self.assistant.error(new Error(msg));
|
|
166
|
+
return process.exit(1);
|
|
167
|
+
} else {
|
|
168
|
+
self.assistant.log(msg);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (options.log) {
|
|
174
|
+
// self.assistant.log('process.env', process.env)
|
|
175
|
+
self.assistant.log('Resolved serviceAccountPath', self.project.serviceAccountPath);
|
|
176
|
+
self.assistant.log('Resolved backendManagerConfigPath', self.project.backendManagerConfigPath);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!appId) {
|
|
180
|
+
self.assistant.warn('⚠️ Missing config.app.id');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Setup sentry
|
|
184
|
+
if (self.options.sentry) {
|
|
185
|
+
const sentryRelease = `${appId || self.project.projectId}@${self.package.version}`;
|
|
186
|
+
const sentryDSN = self.config?.sentry?.dsn || '';
|
|
187
|
+
// self.assistant.log('Sentry', sentryRelease, sentryDSN);
|
|
188
|
+
|
|
189
|
+
self.libraries.sentry = require('@sentry/node');
|
|
190
|
+
self.libraries.sentry.init({
|
|
191
|
+
dsn: sentryDSN,
|
|
192
|
+
release: sentryRelease,
|
|
193
|
+
beforeSend(event, hint) {
|
|
194
|
+
if (self.assistant.isDevelopment() && !self.options.reportErrorsInDev) {
|
|
195
|
+
self.assistant.error(new Error('[Sentry] Skipping Sentry because we\'re in development'), hint)
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
event.tags = event.tags || {};
|
|
199
|
+
event.tags['function.name'] = self.assistant.meta.name;
|
|
200
|
+
event.tags['function.type'] = self.assistant.meta.type;
|
|
201
|
+
event.tags['environment'] = self.assistant.meta.environment;
|
|
202
|
+
return event;
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Setup options features
|
|
208
|
+
if (self.options.initialize) {
|
|
209
|
+
// Initialize Firebase
|
|
210
|
+
try {
|
|
211
|
+
// Initialize Firebase
|
|
212
|
+
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
213
|
+
self.libraries.initializedAdmin = self.libraries.admin.initializeApp();
|
|
214
|
+
// self.app = self.libraries.initializedAdmin;
|
|
215
|
+
} else {
|
|
216
|
+
const serviceAccount = require(self.project.serviceAccountPath);
|
|
217
|
+
self.libraries.initializedAdmin = self.libraries.admin.initializeApp({
|
|
218
|
+
credential: self.libraries.admin.credential.cert(serviceAccount),
|
|
219
|
+
databaseURL: self.project.databaseURL || `https://${self.project.projectId}.firebaseio.com`,
|
|
220
|
+
}, options.uniqueAppName);
|
|
221
|
+
// self.app = self.libraries.initializedAdmin;
|
|
222
|
+
|
|
223
|
+
const loadedProjectId = serviceAccount.project_id;
|
|
224
|
+
if (!loadedProjectId || !loadedProjectId.includes(appId)) {
|
|
225
|
+
self.assistant.error(`Loaded app may have wrong service account: ${loadedProjectId} =/= ${appId}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
} catch (e) {
|
|
230
|
+
self.assistant.error('Failed to call .initializeApp()', e);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Update firebase settings
|
|
234
|
+
try {
|
|
235
|
+
// Update project config
|
|
236
|
+
self.libraries.admin.auth().projectConfigManager().updateProjectConfig({
|
|
237
|
+
emailPrivacyConfig: {
|
|
238
|
+
enableImprovedEmailPrivacy: true,
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
} catch (e) {
|
|
242
|
+
self.assistant.error('Failed to call .updateProjectConfig()', e);
|
|
243
|
+
} finally {
|
|
244
|
+
|
|
245
|
+
}
|
|
246
|
+
// admin.firestore().settings({/* your settings... */ timestampsInSnapshots: true})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Setup main functions
|
|
250
|
+
if (options.projectType === 'firebase' && options.setupFunctions) {
|
|
251
|
+
self.setupFunctions(exporter, options);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Setup custom server
|
|
255
|
+
if (options.projectType === 'custom' && options.setupServer) {
|
|
256
|
+
self.setupCustomServer(exporter, options);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Set dotenv
|
|
260
|
+
try {
|
|
261
|
+
const env = require('dotenv').config();
|
|
262
|
+
} catch (e) {
|
|
263
|
+
self.assistant.error(new Error(`Failed to set up environment variables from .env file: ${e.message}`));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Setup LocalDatabase
|
|
267
|
+
if (options.initializeLocalStorage) {
|
|
268
|
+
self.storage();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Fetch stats
|
|
272
|
+
if (self.assistant.isDevelopment() && options.fetchStats) {
|
|
273
|
+
setTimeout(function () {
|
|
274
|
+
self.assistant.log('Fetching meta/stats...');
|
|
275
|
+
self.libraries.admin
|
|
276
|
+
.firestore().doc('meta/stats')
|
|
277
|
+
.get()
|
|
278
|
+
.then(doc => {
|
|
279
|
+
self.assistant.log('meta/stats', doc.data());
|
|
280
|
+
})
|
|
281
|
+
}, 100);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Send analytics
|
|
285
|
+
self.Analytics({
|
|
286
|
+
assistant: self.assistant,
|
|
287
|
+
uuid: self.SERVER_UUID,
|
|
288
|
+
})
|
|
289
|
+
.event({
|
|
290
|
+
name: 'admin/initialized',
|
|
291
|
+
params: {
|
|
292
|
+
// screen_class: 'MainActivity',
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Return
|
|
297
|
+
return self;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// HELPERS
|
|
301
|
+
Manager.prototype._process = function (mod, options) {
|
|
302
|
+
const self = this;
|
|
303
|
+
|
|
304
|
+
return new Promise(async function(resolve, reject) {
|
|
305
|
+
const name = mod.assistant.meta.name;
|
|
306
|
+
const hook = self.handlers && self.handlers[name];
|
|
307
|
+
const req = mod.req;
|
|
308
|
+
const res = mod.res;
|
|
309
|
+
let error;
|
|
310
|
+
|
|
311
|
+
function _reject(e, log) {
|
|
312
|
+
if (log) {
|
|
313
|
+
// self.assistant.error(e);
|
|
314
|
+
mod.assistant.respond(e, {code: 500, sentry: true});
|
|
315
|
+
}
|
|
316
|
+
// res.status(500).send(e.message);
|
|
317
|
+
return resolve()
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Run pre
|
|
321
|
+
if (hook) {
|
|
322
|
+
await hook(mod, 'pre').catch(e => {error = e});
|
|
323
|
+
}
|
|
324
|
+
if (error) { return _reject(error, true) }
|
|
325
|
+
|
|
326
|
+
// Run main
|
|
327
|
+
await mod.main().catch(e => {error = e});
|
|
328
|
+
if (error) { return _reject(error, false) }
|
|
329
|
+
|
|
330
|
+
// Run post
|
|
331
|
+
if (hook) {
|
|
332
|
+
await hook(mod, 'post').catch(e => {error = e});
|
|
333
|
+
}
|
|
334
|
+
if (error) { return _reject(error, true) }
|
|
335
|
+
|
|
336
|
+
// Fin
|
|
337
|
+
return resolve();
|
|
338
|
+
});
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
Manager.prototype._preProcess = function (mod) {
|
|
342
|
+
const self = this;
|
|
343
|
+
const name = mod.assistant.meta.name;
|
|
344
|
+
return new Promise(async function(resolve, reject) {
|
|
345
|
+
if (self.handlers && self.handlers[name]) {
|
|
346
|
+
let result;
|
|
347
|
+
try {
|
|
348
|
+
result = self.handlers[name](mod)
|
|
349
|
+
} catch (e) {
|
|
350
|
+
mod.assistant.error(e);
|
|
351
|
+
return reject(e);
|
|
352
|
+
}
|
|
353
|
+
if (Promise.resolve(result) == result) {
|
|
354
|
+
result
|
|
355
|
+
.then(r => {
|
|
356
|
+
return resolve(r);
|
|
357
|
+
})
|
|
358
|
+
.catch(e => {
|
|
359
|
+
mod.assistant.error(e);
|
|
360
|
+
return reject(e);
|
|
361
|
+
})
|
|
362
|
+
} else {
|
|
363
|
+
return resolve(result);
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
return resolve(null);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// Manager.prototype.Assistant = function(ref, options) {
|
|
372
|
+
// const self = this;
|
|
373
|
+
// ref = ref || {};
|
|
374
|
+
// options = options || {};
|
|
375
|
+
// return (new self.libraries.Assistant()).init({
|
|
376
|
+
// req: ref.req,
|
|
377
|
+
// res: ref.res,
|
|
378
|
+
// admin: self.libraries.admin,
|
|
379
|
+
// functions: self.libraries.functions,
|
|
380
|
+
// }, {
|
|
381
|
+
// accept: options.accept,
|
|
382
|
+
// })
|
|
383
|
+
// };
|
|
384
|
+
|
|
385
|
+
Manager.prototype.Assistant = function(ref, options) {
|
|
386
|
+
const self = this;
|
|
387
|
+
|
|
388
|
+
// Set options defaults
|
|
389
|
+
ref = ref || {};
|
|
390
|
+
options = options || {};
|
|
391
|
+
|
|
392
|
+
// Create assistant instance
|
|
393
|
+
return (new self.libraries.Assistant()).init({
|
|
394
|
+
req: ref.req,
|
|
395
|
+
res: ref.res,
|
|
396
|
+
admin: self.libraries.admin,
|
|
397
|
+
functions: self.libraries.functions,
|
|
398
|
+
Manager: self,
|
|
399
|
+
}, options)
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
Manager.prototype.User = function () {
|
|
403
|
+
const self = this;
|
|
404
|
+
self.libraries.User = self.libraries.User || require('./helpers/user.js');
|
|
405
|
+
return new self.libraries.User(self, ...arguments);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
Manager.prototype.Analytics = function () {
|
|
409
|
+
const self = this;
|
|
410
|
+
self.libraries.Analytics = self.libraries.Analytics || require('./helpers/analytics.js');
|
|
411
|
+
return new self.libraries.Analytics(self, ...arguments);
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
Manager.prototype.ApiManager = function () {
|
|
415
|
+
const self = this;
|
|
416
|
+
self.libraries.ApiManager = self.libraries.ApiManager || require('./helpers/api-manager.js');
|
|
417
|
+
return new self.libraries.ApiManager(self, ...arguments);
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
Manager.prototype.Roles = function () {
|
|
421
|
+
const self = this;
|
|
422
|
+
self.libraries.Roles = self.libraries.Roles || require('./helpers/roles.js');
|
|
423
|
+
return new self.libraries.Roles(self, ...arguments);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
Manager.prototype.SubscriptionResolver = function () {
|
|
427
|
+
const self = this;
|
|
428
|
+
self.libraries.SubscriptionResolver = self.libraries.SubscriptionResolver || require('./helpers/subscription-resolver.js');
|
|
429
|
+
return new self.libraries.SubscriptionResolver(self, ...arguments);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
Manager.prototype.Usage = function () {
|
|
433
|
+
const self = this;
|
|
434
|
+
self.libraries.Usage = self.libraries.Usage || require('./helpers/usage.js');
|
|
435
|
+
return new self.libraries.Usage(self, ...arguments);
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
Manager.prototype.Middleware = function () {
|
|
439
|
+
const self = this;
|
|
440
|
+
self.libraries.Middleware = self.libraries.Middleware || require('./helpers/middleware.js');
|
|
441
|
+
return new self.libraries.Middleware(self, ...arguments);
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
Manager.prototype.Settings = function () {
|
|
445
|
+
const self = this;
|
|
446
|
+
self.libraries.Settings = self.libraries.Settings || require('./helpers/settings.js');
|
|
447
|
+
return new self.libraries.Settings(self, ...arguments);
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
Manager.prototype.Metadata = function () {
|
|
451
|
+
const self = this;
|
|
452
|
+
self.libraries.Metadata = self.libraries.Metadata || require('./helpers/metadata.js');
|
|
453
|
+
return new self.libraries.Metadata(self, ...arguments);
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
// For importing API libraries
|
|
457
|
+
Manager.prototype.Api = function () {
|
|
458
|
+
const self = this;
|
|
459
|
+
// self.libraries.Api = self.libraries.Api || require('./helpers/subscription-resolver.js');
|
|
460
|
+
// return new self.libraries.Api(...arguments);
|
|
461
|
+
// return self._process((new (require(`${core}/actions/api.js`))()).init(self, { req: req, res: res, }))
|
|
462
|
+
|
|
463
|
+
const Api = (new (require(`${core}/actions/api.js`))()).init(self, { req: {}, res: {}, });
|
|
464
|
+
|
|
465
|
+
return Api;
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
// Manager.prototype.Api = function () {
|
|
469
|
+
// const self = this;
|
|
470
|
+
// // self.libraries.Api = self.libraries.Api || require('./helpers/subscription-resolver.js');
|
|
471
|
+
// // return new self.libraries.Api(...arguments);
|
|
472
|
+
// // return self._process((new (require(`${core}/actions/api.js`))()).init(self, { req: req, res: res, }))
|
|
473
|
+
// return new Promise(function(resolve, reject) {
|
|
474
|
+
// const Api = (new (require(`${core}/actions/api.js`))()).init(self, { req: {}, res: {}, });
|
|
475
|
+
|
|
476
|
+
// Api.main()
|
|
477
|
+
|
|
478
|
+
// return Api;
|
|
479
|
+
// });
|
|
480
|
+
// };
|
|
481
|
+
|
|
482
|
+
// Manager.prototype.Utilities = function () {
|
|
483
|
+
// const self = this;
|
|
484
|
+
// self.libraries.Utilities = self.libraries.Utilities || require('./helpers/utilities.js');
|
|
485
|
+
// return new self.libraries.Utilities(self, ...arguments);
|
|
486
|
+
// };
|
|
487
|
+
|
|
488
|
+
Manager.prototype.Utilities = function () {
|
|
489
|
+
const self = this;
|
|
490
|
+
|
|
491
|
+
if (!self._internal.utilities) {
|
|
492
|
+
self.libraries.Utilities = require('./helpers/utilities.js');
|
|
493
|
+
self._internal.utilities = new self.libraries.Utilities(self, ...arguments);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return self._internal.utilities;
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
Manager.prototype.storage = function (options) {
|
|
500
|
+
const self = this;
|
|
501
|
+
options = options || {};
|
|
502
|
+
options.name = options.name || 'main';
|
|
503
|
+
|
|
504
|
+
if (!self._internal.storage[options.name]) {
|
|
505
|
+
options.temporary = typeof options.temporary === 'undefined' ? false : options.temporary;
|
|
506
|
+
options.clear = typeof options.clear === 'undefined' ? true : options.clear;
|
|
507
|
+
options.log = typeof options.log === 'undefined' ? false : options.log;
|
|
508
|
+
|
|
509
|
+
// Set path
|
|
510
|
+
const subfolder = `storage/${self.options.uniqueAppName || 'primary'}/${options.name}`;
|
|
511
|
+
|
|
512
|
+
// Setup lowdb
|
|
513
|
+
const low = require('lowdb');
|
|
514
|
+
const FileSync = require('lowdb/adapters/FileSync');
|
|
515
|
+
const location = options.temporary
|
|
516
|
+
? `${require('os').tmpdir()}/${subfolder}.json`
|
|
517
|
+
: `./.data/${subfolder}.json`;
|
|
518
|
+
const adapter = new FileSync(location);
|
|
519
|
+
|
|
520
|
+
// Log
|
|
521
|
+
if (options.log) {
|
|
522
|
+
self.assistant.log('storage(): Location', location);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Clear temporary storage
|
|
526
|
+
if (
|
|
527
|
+
options.temporary
|
|
528
|
+
&& self.assistant.isDevelopment()
|
|
529
|
+
&& options.clear
|
|
530
|
+
) {
|
|
531
|
+
self.assistant.log('Removed temporary file @', location);
|
|
532
|
+
jetpack.remove(location);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Setup options
|
|
536
|
+
options.clearInvalid = typeof options.clearInvalid === 'undefined'
|
|
537
|
+
? true
|
|
538
|
+
: options.clearInvalid;
|
|
539
|
+
|
|
540
|
+
function _setup() {
|
|
541
|
+
if (!jetpack.exists(location)) {
|
|
542
|
+
jetpack.write(location, {});
|
|
543
|
+
}
|
|
544
|
+
self._internal.storage[options.name] = low(adapter);
|
|
545
|
+
|
|
546
|
+
self._internal.storage[options.name].set('_location', location)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
try {
|
|
550
|
+
_setup()
|
|
551
|
+
} catch (e) {
|
|
552
|
+
self.assistant.error(`Could not setup storage: ${location}`, e);
|
|
553
|
+
|
|
554
|
+
try {
|
|
555
|
+
if (options.clearInvalid) {
|
|
556
|
+
self.assistant.log(`Clearing invalid storage: ${location}`);
|
|
557
|
+
jetpack.write(location, {});
|
|
558
|
+
}
|
|
559
|
+
_setup()
|
|
560
|
+
} catch (e) {
|
|
561
|
+
self.assistant.error(`Failed to clear invalid storage: ${location}`, e);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return self._internal.storage[options.name]
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
Manager.prototype.getCustomServer = function () {
|
|
570
|
+
const self = this;
|
|
571
|
+
|
|
572
|
+
if (!self._internal.server || !self._internal.app) {
|
|
573
|
+
throw new Error('Server not set up');
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return {
|
|
577
|
+
server: self._internal.server,
|
|
578
|
+
app: self._internal.app,
|
|
579
|
+
};
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
Manager.prototype.install = function (controller, options) {
|
|
583
|
+
const self = this;
|
|
584
|
+
|
|
585
|
+
// Set options defaults
|
|
586
|
+
options = options || {};
|
|
587
|
+
options.prefix = typeof options.prefix === 'undefined' ? null : options.prefix;
|
|
588
|
+
options.dir = typeof options.dir === 'undefined' ? '' : options.dir;
|
|
589
|
+
options.log = typeof options.log === 'undefined' ? false : options.log;
|
|
590
|
+
|
|
591
|
+
// Fix dir
|
|
592
|
+
options.dir = path.resolve(self.cwd, options.dir);
|
|
593
|
+
|
|
594
|
+
// If dir is a single file, install it. if its a directory, install all
|
|
595
|
+
const isDirectory = jetpack.exists(options.dir) === 'dir';
|
|
596
|
+
|
|
597
|
+
if (options.log) {
|
|
598
|
+
self.assistant.log(`Installing from ${options.dir}, prefix=${options.prefix}, isDirectory=${isDirectory}...`);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
function _install(prefix, file) {
|
|
602
|
+
if (!file.includes('.js')) {return}
|
|
603
|
+
const name = file.replace('.js', '');
|
|
604
|
+
const _prefix = prefix ? `${prefix}_${name}` : name;
|
|
605
|
+
|
|
606
|
+
const fullPath = path.resolve(options.dir, file);
|
|
607
|
+
|
|
608
|
+
if (options.log) {
|
|
609
|
+
self.assistant.log(`Installing ${_prefix} from ${fullPath}...`);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
controller[`${_prefix}`] = require(fullPath);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (isDirectory) {
|
|
616
|
+
jetpack.list(options.dir)
|
|
617
|
+
.forEach(file => _install(options.prefix, file))
|
|
618
|
+
} else {
|
|
619
|
+
_install(options.prefix, options.dir);
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
Manager.prototype.require = function (p) {
|
|
624
|
+
return require(p);
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
Manager.prototype.debug = function () {
|
|
628
|
+
return {
|
|
629
|
+
throwException: function () {
|
|
630
|
+
throw new Error('TEST_ERROR');
|
|
631
|
+
},
|
|
632
|
+
throwRejection: function () {
|
|
633
|
+
Promise.reject(new Error('TEST_ERROR'));
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Setup functions
|
|
639
|
+
Manager.prototype.setupFunctions = function (exporter, options) {
|
|
640
|
+
const self = this;
|
|
641
|
+
|
|
642
|
+
// Log
|
|
643
|
+
if (options.log) {
|
|
644
|
+
self.assistant.log('Setting up Firebase functions...');
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Setup functions
|
|
648
|
+
exporter.bm_api =
|
|
649
|
+
self.libraries.functions
|
|
650
|
+
.runWith({memory: '256MB', timeoutSeconds: 60 * 5})
|
|
651
|
+
// TODO: Replace this with new API
|
|
652
|
+
.https.onRequest(async (req, res) => self._process((new (require(`${core}/actions/api.js`))()).init(self, { req: req, res: res, })));
|
|
653
|
+
|
|
654
|
+
// Setup legacy functions
|
|
655
|
+
if (options.setupFunctionsLegacy) {
|
|
656
|
+
exporter.bm_signUpHandler =
|
|
657
|
+
self.libraries.functions
|
|
658
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
659
|
+
.https.onRequest(async (req, res) => {
|
|
660
|
+
const Module = require(`${core}/actions/sign-up-handler.js`);
|
|
661
|
+
Module.init(self, { req: req, res: res, });
|
|
662
|
+
|
|
663
|
+
return self._preProcess(Module)
|
|
664
|
+
.then(r => Module.main())
|
|
665
|
+
.catch(e => {
|
|
666
|
+
self.assistant.error(e);
|
|
667
|
+
return res.status(500).send(e.message);
|
|
668
|
+
});
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// Admin
|
|
672
|
+
exporter.bm_createPost =
|
|
673
|
+
self.libraries.functions
|
|
674
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
675
|
+
.https.onRequest(async (req, res) => {
|
|
676
|
+
const Module = require(`${core}/admin/create-post.js`);
|
|
677
|
+
Module.init(self, { req: req, res: res, });
|
|
678
|
+
|
|
679
|
+
return self._preProcess(Module)
|
|
680
|
+
.then(r => Module.main())
|
|
681
|
+
.catch(e => {
|
|
682
|
+
self.assistant.error(e);
|
|
683
|
+
return res.status(500).send(e.message);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
exporter.bm_firestoreWrite =
|
|
688
|
+
self.libraries.functions
|
|
689
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
690
|
+
.https.onRequest(async (req, res) => {
|
|
691
|
+
const Module = require(`${core}/admin/firestore-write.js`);
|
|
692
|
+
Module.init(self, { req: req, res: res, });
|
|
693
|
+
|
|
694
|
+
return self._preProcess(Module)
|
|
695
|
+
.then(r => Module.main())
|
|
696
|
+
.catch(e => {
|
|
697
|
+
self.assistant.error(e);
|
|
698
|
+
return res.status(500).send(e.message);
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
exporter.bm_getStats =
|
|
703
|
+
self.libraries.functions
|
|
704
|
+
.runWith({memory: '256MB', timeoutSeconds: 420})
|
|
705
|
+
.https.onRequest(async (req, res) => {
|
|
706
|
+
const Module = require(`${core}/admin/get-stats.js`);
|
|
707
|
+
Module.init(self, { req: req, res: res, });
|
|
708
|
+
|
|
709
|
+
return self._preProcess(Module)
|
|
710
|
+
.then(r => Module.main())
|
|
711
|
+
.catch(e => {
|
|
712
|
+
self.assistant.error(e);
|
|
713
|
+
return res.status(500).send(e.message);
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
exporter.bm_sendNotification =
|
|
718
|
+
self.libraries.functions
|
|
719
|
+
.runWith({memory: '1GB', timeoutSeconds: 420})
|
|
720
|
+
.https.onRequest(async (req, res) => {
|
|
721
|
+
const Module = require(`${core}/admin/send-notification.js`);
|
|
722
|
+
Module.init(self, { req: req, res: res, });
|
|
723
|
+
|
|
724
|
+
return self._preProcess(Module)
|
|
725
|
+
.then(r => Module.main())
|
|
726
|
+
.catch(e => {
|
|
727
|
+
self.assistant.error(e);
|
|
728
|
+
return res.status(500).send(e.message);
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
exporter.bm_query =
|
|
733
|
+
self.libraries.functions
|
|
734
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
735
|
+
.https.onRequest(async (req, res) => {
|
|
736
|
+
const Module = require(`${core}/admin/query.js`);
|
|
737
|
+
Module.init(self, { req: req, res: res, });
|
|
738
|
+
|
|
739
|
+
return self._preProcess(Module)
|
|
740
|
+
.then(r => Module.main())
|
|
741
|
+
.catch(e => {
|
|
742
|
+
self.assistant.error(e);
|
|
743
|
+
return res.status(500).send(e.message);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
exporter.bm_createPostHandler =
|
|
748
|
+
self.libraries.functions
|
|
749
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
750
|
+
.https.onRequest(async (req, res) => {
|
|
751
|
+
const Module = require(`${core}/actions/create-post-handler.js`);
|
|
752
|
+
Module.init(self, { req: req, res: res, });
|
|
753
|
+
|
|
754
|
+
return self._preProcess(Module)
|
|
755
|
+
.then(r => Module.main())
|
|
756
|
+
.catch(e => {
|
|
757
|
+
self.assistant.error(e);
|
|
758
|
+
return res.status(500).send(e.message);
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
exporter.bm_generateUuid =
|
|
763
|
+
self.libraries.functions
|
|
764
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
765
|
+
.https.onRequest(async (req, res) => {
|
|
766
|
+
const Module = require(`${core}/actions/generate-uuid.js`);
|
|
767
|
+
Module.init(self, { req: req, res: res, });
|
|
768
|
+
|
|
769
|
+
return self._preProcess(Module)
|
|
770
|
+
.then(r => Module.main())
|
|
771
|
+
.catch(e => {
|
|
772
|
+
self.assistant.error(e);
|
|
773
|
+
return res.status(500).send(e.message);
|
|
774
|
+
});
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
// Test
|
|
778
|
+
exporter.bm_test_authenticate =
|
|
779
|
+
self.libraries.functions
|
|
780
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
781
|
+
.https.onRequest(async (req, res) => {
|
|
782
|
+
const Module = require(`${test}/authenticate.js`);
|
|
783
|
+
Module.init(self, { req: req, res: res, });
|
|
784
|
+
|
|
785
|
+
return self._preProcess(Module)
|
|
786
|
+
.then(r => Module.main())
|
|
787
|
+
.catch(e => {
|
|
788
|
+
self.assistant.error(e);
|
|
789
|
+
return res.status(500).send(e.message);
|
|
790
|
+
});
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
exporter.bm_test_createTestAccounts =
|
|
794
|
+
self.libraries.functions
|
|
795
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
796
|
+
.https.onRequest(async (req, res) => {
|
|
797
|
+
const Module = require(`${test}/create-test-accounts.js`);
|
|
798
|
+
Module.init(self, { req: req, res: res, });
|
|
799
|
+
|
|
800
|
+
return self._preProcess(Module)
|
|
801
|
+
.then(r => Module.main())
|
|
802
|
+
.catch(e => {
|
|
803
|
+
self.assistant.error(e);
|
|
804
|
+
return res.status(500).send(e.message);
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
exporter.bm_test_webhook =
|
|
809
|
+
self.libraries.functions
|
|
810
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
811
|
+
.https.onRequest(async (req, res) => {
|
|
812
|
+
const Module = require(`${test}/webhook.js`);
|
|
813
|
+
Module.init(self, { req: req, res: res, });
|
|
814
|
+
|
|
815
|
+
return self._preProcess(Module)
|
|
816
|
+
.then(r => Module.main())
|
|
817
|
+
.catch(e => {
|
|
818
|
+
self.assistant.error(e);
|
|
819
|
+
return res.status(500).send(e.message);
|
|
820
|
+
});
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Setup identity functions
|
|
825
|
+
if (options.setupFunctionsIdentity) {
|
|
826
|
+
exporter.bm_authBeforeCreate =
|
|
827
|
+
self.libraries.functions
|
|
828
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
829
|
+
.auth.user()
|
|
830
|
+
.beforeCreate(async (user, context) => self._process((new (require(`${core}/events/auth/before-create.js`))()).init(self, { user: user, context: context})));
|
|
831
|
+
|
|
832
|
+
exporter.bm_authBeforeSignIn =
|
|
833
|
+
self.libraries.functions
|
|
834
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
835
|
+
.auth.user()
|
|
836
|
+
.beforeSignIn(async (user, context) => self._process((new (require(`${core}/events/auth/before-signin.js`))()).init(self, { user: user, context: context})));
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Setup events
|
|
840
|
+
exporter.bm_authOnCreate =
|
|
841
|
+
self.libraries.functions
|
|
842
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
843
|
+
.auth.user()
|
|
844
|
+
.onCreate(async (user, context) => self._process((new (require(`${core}/events/auth/on-create.js`))()).init(self, { user: user, context: context})));
|
|
845
|
+
|
|
846
|
+
exporter.bm_authOnDelete =
|
|
847
|
+
self.libraries.functions
|
|
848
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
849
|
+
.auth.user()
|
|
850
|
+
.onDelete(async (user, context) => self._process((new (require(`${core}/events/auth/on-delete.js`))()).init(self, { user: user, context: context})));
|
|
851
|
+
|
|
852
|
+
exporter.bm_subOnWrite =
|
|
853
|
+
self.libraries.functions
|
|
854
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
855
|
+
.firestore.document('notifications/subscriptions/all/{token}')
|
|
856
|
+
.onWrite(async (change, context) => self._process((new (require(`${core}/events/firestore/on-subscription.js`))()).init(self, { change: change, context: context, })));
|
|
857
|
+
|
|
858
|
+
// Setup cron jobs
|
|
859
|
+
exporter.bm_cronDaily =
|
|
860
|
+
self.libraries.functions
|
|
861
|
+
.runWith({ memory: '256MB', timeoutSeconds: 60 * 5})
|
|
862
|
+
.pubsub.schedule('every 24 hours')
|
|
863
|
+
.onRun(async (context) => self._process((new (require(`${core}/cron/daily.js`))()).init(self, { context: context, })));
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// Setup Custom Server
|
|
867
|
+
Manager.prototype.setupCustomServer = function (_library, options) {
|
|
868
|
+
const self = this;
|
|
869
|
+
|
|
870
|
+
// Require
|
|
871
|
+
const glob = require('glob').globSync;
|
|
872
|
+
|
|
873
|
+
// Log
|
|
874
|
+
if (options.log) {
|
|
875
|
+
self.assistant.log('Setting up custom server...');
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// Setup fastify
|
|
879
|
+
// const app = library({
|
|
880
|
+
// logger: true,
|
|
881
|
+
// // querystringParser: str => querystring.parse(str.toLowerCase())
|
|
882
|
+
// });
|
|
883
|
+
|
|
884
|
+
// Setup express
|
|
885
|
+
const app = require('express')({
|
|
886
|
+
logger: true,
|
|
887
|
+
// querystringParser: str => querystring.parse(str.toLowerCase())
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
// Setup body parser
|
|
891
|
+
app.use(require('body-parser').json());
|
|
892
|
+
|
|
893
|
+
// Designate paths
|
|
894
|
+
const managerRoutesPath = path.normalize(`${__dirname}/routes`);
|
|
895
|
+
const managerSchemasPath = path.normalize(`${__dirname}/schemas`);
|
|
896
|
+
const customRoutesPath = path.normalize(`${self.cwd}${options.routes}`);
|
|
897
|
+
const customSchemasPath = path.normalize(`${self.cwd}${options.schemas}`);
|
|
898
|
+
|
|
899
|
+
// Create routes
|
|
900
|
+
const routes = [];
|
|
901
|
+
|
|
902
|
+
// Push function
|
|
903
|
+
function _push(dir, isManager) {
|
|
904
|
+
// Get all files
|
|
905
|
+
glob('**/index.js', { cwd: dir })
|
|
906
|
+
.forEach((file) => {
|
|
907
|
+
// Build the item
|
|
908
|
+
const item = {
|
|
909
|
+
name: file.replace('/index.js', ''),
|
|
910
|
+
namespace: file,
|
|
911
|
+
path: path.resolve(dir, file),
|
|
912
|
+
dir: dir,
|
|
913
|
+
isManager: isManager,
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// If it exists in routes, replace it
|
|
917
|
+
const existing = routes.findIndex(r => r.name === item.name);
|
|
918
|
+
if (existing > -1) {
|
|
919
|
+
routes[existing] = item;
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// Otherwise, push it
|
|
924
|
+
routes.push(item);
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// Push routes
|
|
929
|
+
// _push(`${__dirname}/routes`)
|
|
930
|
+
_push(managerRoutesPath, true)
|
|
931
|
+
_push(customRoutesPath, false)
|
|
932
|
+
|
|
933
|
+
// Log routes
|
|
934
|
+
// if (options.log) {
|
|
935
|
+
// self.assistant.log('Routes:', routes);
|
|
936
|
+
// }
|
|
937
|
+
|
|
938
|
+
// Install process
|
|
939
|
+
routes.forEach((file) => {
|
|
940
|
+
// self.assistant.log('---file', file);
|
|
941
|
+
// Require the file
|
|
942
|
+
const cors = self.libraries.cors;
|
|
943
|
+
|
|
944
|
+
// Log
|
|
945
|
+
if (options.log) {
|
|
946
|
+
self.assistant.log(`Initializing route: ${file.name} @ ${file.path}`);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Register the route
|
|
950
|
+
app.all(`/${file.name}`, async (req, res) => {
|
|
951
|
+
return cors(req, res, async () => {
|
|
952
|
+
// self.Middleware(req, res).run(file.name, {schema: file.name})
|
|
953
|
+
self.Middleware(req, res).run(file.name, {
|
|
954
|
+
schema: file.name,
|
|
955
|
+
routesDir: file.isManager ? managerRoutesPath : customRoutesPath,
|
|
956
|
+
schemasDir: file.isManager ? managerSchemasPath : customSchemasPath,
|
|
957
|
+
})
|
|
958
|
+
});
|
|
959
|
+
})
|
|
960
|
+
|
|
961
|
+
// app.all(`/${name}`, async (req, res) => {
|
|
962
|
+
// return cors(req, res, async () => {
|
|
963
|
+
// // Fix req/res
|
|
964
|
+
// req.body = req.body || {};
|
|
965
|
+
// req.query = Object.assign({}, req.query || {});
|
|
966
|
+
|
|
967
|
+
// // Manager.Middleware(req, res).run('tools/screenshot', {schema: 'screenshot'})
|
|
968
|
+
// const handler = new (require(file.path))();
|
|
969
|
+
// const assistant = self.Assistant({req: req, res: res}, {functionName: name, functionType: 'http'});
|
|
970
|
+
// // const apiUser = await ApiManager.getUser(assistant);
|
|
971
|
+
|
|
972
|
+
// // Set handler properties
|
|
973
|
+
// handler.Manager = self;
|
|
974
|
+
// handler.assistant = assistant;
|
|
975
|
+
// handler.apiUser = null;
|
|
976
|
+
|
|
977
|
+
// // Log
|
|
978
|
+
// if (options.log) {
|
|
979
|
+
// self.assistant.log(`[Request] ${name} @ ${filepath}`, req.body, req.query);
|
|
980
|
+
// }
|
|
981
|
+
|
|
982
|
+
// // Execute the route
|
|
983
|
+
// try {
|
|
984
|
+
// await handler.process(req, res);
|
|
985
|
+
// } catch (e) {
|
|
986
|
+
// assistant.respond(e, {code: e.code});
|
|
987
|
+
// }
|
|
988
|
+
// });
|
|
989
|
+
// })
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
// Run the server!
|
|
993
|
+
const server = app.listen({ port: process.env.PORT || 3000, host: '0.0.0.0' }, () => {
|
|
994
|
+
const address = server.address();
|
|
995
|
+
|
|
996
|
+
// Check if there's an error
|
|
997
|
+
if (server.address() === null) {
|
|
998
|
+
self.assistant.error(e);
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Log
|
|
1003
|
+
if (options.log) {
|
|
1004
|
+
self.assistant.log(`Server listening on ${address.address}:${address.port}`);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Set server and app to internal
|
|
1008
|
+
self._internal.server = server;
|
|
1009
|
+
self._internal.app = app;
|
|
1010
|
+
|
|
1011
|
+
// Emit event
|
|
1012
|
+
self.emit('online', new Event('online'), server, app);
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// Setup Custom Server
|
|
1017
|
+
Manager.prototype.getApp = function (id) {
|
|
1018
|
+
const self = this;
|
|
1019
|
+
|
|
1020
|
+
// Get the app
|
|
1021
|
+
return new Promise(function(resolve, reject) {
|
|
1022
|
+
const fetch = require('wonderful-fetch');
|
|
1023
|
+
|
|
1024
|
+
// Set ID
|
|
1025
|
+
id = id || self.config.app.id;
|
|
1026
|
+
|
|
1027
|
+
// If no ID, reject
|
|
1028
|
+
if (!id) {
|
|
1029
|
+
return reject(new Error('No ID provided'));
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Fetch the app
|
|
1033
|
+
fetch(`https://us-central1-itw-creative-works.cloudfunctions.net/getApp`, {
|
|
1034
|
+
method: 'post',
|
|
1035
|
+
response: 'json',
|
|
1036
|
+
timeout: 30000,
|
|
1037
|
+
tries: 3,
|
|
1038
|
+
body: {
|
|
1039
|
+
id: id,
|
|
1040
|
+
}
|
|
1041
|
+
})
|
|
1042
|
+
.then((r) => resolve(r))
|
|
1043
|
+
.catch((e) => reject(e));
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
function resolveProjectPackage(dir) {
|
|
1048
|
+
try {
|
|
1049
|
+
return require(path.resolve(dir, 'functions', 'package.json'));
|
|
1050
|
+
} catch (e) {}
|
|
1051
|
+
|
|
1052
|
+
try {
|
|
1053
|
+
return require(path.resolve(dir, 'package.json'));
|
|
1054
|
+
} catch (e) {}
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
function requireJSON5(file, throwError) {
|
|
1058
|
+
// Set throwError
|
|
1059
|
+
throwError = typeof throwError === 'undefined' ? true : throwError;
|
|
1060
|
+
|
|
1061
|
+
// Load JSON5
|
|
1062
|
+
try {
|
|
1063
|
+
return JSON5.parse(jetpack.read(file))
|
|
1064
|
+
} catch (e) {
|
|
1065
|
+
// If we're not throwing an error, just return
|
|
1066
|
+
if (!throwError) {
|
|
1067
|
+
return {};
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// Otherwise, throw the error
|
|
1071
|
+
console.error(`Failed to load JSON at ${file}:`, e);
|
|
1072
|
+
throw e;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
module.exports = Manager;
|