backend-manager 2.5.3 → 2.5.5
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
package/src/cli/cli.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// https://www.sitepoint.com/javascript-command-line-interface-cli-node-js/
|
|
6
6
|
// https://github.com/sitepoint-editors/ginit
|
|
7
7
|
|
|
8
|
-
let exec = require('child_process').exec;
|
|
9
8
|
const jetpack = require('fs-jetpack');
|
|
10
9
|
const path = require('path');
|
|
11
10
|
const chalk = require('chalk');
|
|
@@ -14,7 +13,7 @@ const log = console.log;
|
|
|
14
13
|
const Npm = require('npm-api');
|
|
15
14
|
const semver = require('semver');
|
|
16
15
|
const inquirer = require('inquirer');
|
|
17
|
-
const { spawn } = require('child_process');
|
|
16
|
+
const { spawn, child, exec, fork } = require('child_process');
|
|
18
17
|
const JSON5 = require('json5');
|
|
19
18
|
const fetch = require('wonderful-fetch');
|
|
20
19
|
const argv = require('yargs').argv;
|
|
@@ -87,6 +86,12 @@ Main.prototype.process = async function (args) {
|
|
|
87
86
|
console.log('cwd: ', self.firebaseProjectPath);
|
|
88
87
|
}
|
|
89
88
|
if (self.options.setup) {
|
|
89
|
+
// console.log(`Running Setup`);
|
|
90
|
+
// console.log(`node:`, process.versions.node);
|
|
91
|
+
// console.log(`pwd:`, await execute('pwd').catch(e => e));
|
|
92
|
+
// console.log(`node:`, await execute('node --version').catch(e => e));
|
|
93
|
+
// console.log(`firebase-tools:`, await execute('firebase --version').catch(e => e));
|
|
94
|
+
// console.log('');
|
|
90
95
|
await cmd_configGet(self).catch(e => log(chalk.red(`Failed to run config:get`)));
|
|
91
96
|
await self.setup();
|
|
92
97
|
}
|
|
@@ -1115,9 +1120,63 @@ async function cmd_indexesGet(self, filePath, log) {
|
|
|
1115
1120
|
});
|
|
1116
1121
|
}
|
|
1117
1122
|
|
|
1123
|
+
async function execute(command, cwd) {
|
|
1124
|
+
cwd = cwd || process.cwd();
|
|
1125
|
+
return new Promise(function(resolve, reject) {
|
|
1126
|
+
exec(command, { cwd: cwd, stdio: 'inherit' })
|
|
1127
|
+
.on('error', function(err) {
|
|
1128
|
+
reject(err);
|
|
1129
|
+
})
|
|
1130
|
+
.on('close', function (one, two, three) {
|
|
1131
|
+
console.log('===', one, two, three);
|
|
1132
|
+
resolve()
|
|
1133
|
+
})
|
|
1134
|
+
// fork(command, function (error, stdout, stderr) {
|
|
1135
|
+
// if (error) {
|
|
1136
|
+
// reject(error);
|
|
1137
|
+
// } else {
|
|
1138
|
+
// resolve(stdout);
|
|
1139
|
+
// }
|
|
1140
|
+
// });
|
|
1141
|
+
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// async function execute(command, args, cwd) {
|
|
1146
|
+
// cwd = cwd || process.cwd();
|
|
1147
|
+
// return new Promise(function(resolve, reject) {
|
|
1148
|
+
// spawn(command, args, { cwd: cwd, stdio: 'inherit' })
|
|
1149
|
+
// .on('error', function(err) {
|
|
1150
|
+
// reject(err);
|
|
1151
|
+
// })
|
|
1152
|
+
// .on('close', function (one, two, three) {
|
|
1153
|
+
// console.log('===', one, two, three);
|
|
1154
|
+
// resolve()
|
|
1155
|
+
// })
|
|
1156
|
+
// // fork(command, function (error, stdout, stderr) {
|
|
1157
|
+
// // if (error) {
|
|
1158
|
+
// // reject(error);
|
|
1159
|
+
// // } else {
|
|
1160
|
+
// // resolve(stdout);
|
|
1161
|
+
// // }
|
|
1162
|
+
// // });
|
|
1163
|
+
|
|
1164
|
+
// });
|
|
1165
|
+
// }
|
|
1166
|
+
|
|
1118
1167
|
async function cmd_configGet(self, filePath) {
|
|
1119
1168
|
return new Promise(function(resolve, reject) {
|
|
1120
1169
|
const finalPath = `${self.firebaseProjectPath}/${filePath || 'functions/.runtimeconfig.json'}`;
|
|
1170
|
+
// execute(`firebase functions:config:get > ${finalPath}`)
|
|
1171
|
+
// .then(r => {
|
|
1172
|
+
// console.log(chalk.green(`Saving config to: ${finalPath}`));
|
|
1173
|
+
// console.log(r);
|
|
1174
|
+
// resolve(require(finalPath));
|
|
1175
|
+
// })
|
|
1176
|
+
// .catch(e => {
|
|
1177
|
+
// console.error(e);
|
|
1178
|
+
// reject(e);
|
|
1179
|
+
// })
|
|
1121
1180
|
let cmd = exec(`firebase functions:config:get > ${finalPath}`, function (error, stdout, stderr) {
|
|
1122
1181
|
if (error) {
|
|
1123
1182
|
console.error(error);
|
|
@@ -79,7 +79,9 @@ Module.prototype.updateStats = function (existingData) {
|
|
|
79
79
|
const sessionsApp = self.libraries.admin.database().ref(`sessions/app`);
|
|
80
80
|
|
|
81
81
|
let error = null;
|
|
82
|
-
let update = {
|
|
82
|
+
let update = {
|
|
83
|
+
app: _.get(self.Manager.config, 'app.id', null),
|
|
84
|
+
};
|
|
83
85
|
|
|
84
86
|
// Fix broken stats
|
|
85
87
|
if (!_.get(existingData, 'users.total', null)) {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
function Utilities(Manager) {
|
|
2
|
+
const self = this;
|
|
3
|
+
|
|
4
|
+
self.Manager = Manager;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Utilities.prototype.iterateCollection = function (callback, options) {
|
|
8
|
+
const self = this;
|
|
9
|
+
const Manager = self.Manager;
|
|
10
|
+
const admin = Manager.libraries.admin;
|
|
11
|
+
|
|
12
|
+
return new Promise(function(resolve, reject) {
|
|
13
|
+
let batch = -1;
|
|
14
|
+
|
|
15
|
+
options = options || {};
|
|
16
|
+
options.collection = options.collection || '';
|
|
17
|
+
options.batchSize = options.batchSize || 1000;
|
|
18
|
+
options.log = options.log;
|
|
19
|
+
|
|
20
|
+
function listAllDocuments(nextPageToken) {
|
|
21
|
+
let query = admin.firestore().collection(options.collection)
|
|
22
|
+
|
|
23
|
+
// Start at next page
|
|
24
|
+
if (nextPageToken) {
|
|
25
|
+
query = query.startAfter(nextPageToken);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// batchSize
|
|
29
|
+
query = query.limit(options.batchSize);
|
|
30
|
+
|
|
31
|
+
query.get()
|
|
32
|
+
.then(async (snap) => {
|
|
33
|
+
const lastVisible = snap.docs[snap.docs.length - 1];
|
|
34
|
+
|
|
35
|
+
batch++;
|
|
36
|
+
|
|
37
|
+
if (options.log) {
|
|
38
|
+
console.log('Processing batch:', batch);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
callback({
|
|
42
|
+
snap: snap, docs: snap.docs.map(x => x)
|
|
43
|
+
}, batch)
|
|
44
|
+
.then(r => {
|
|
45
|
+
// Construct a new query starting at this document
|
|
46
|
+
if (lastVisible) {
|
|
47
|
+
listAllDocuments(lastVisible)
|
|
48
|
+
} else {
|
|
49
|
+
return resolve();
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.catch((e) => {
|
|
53
|
+
console.error('Callback failed', e);
|
|
54
|
+
return reject(e);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
})
|
|
58
|
+
.catch((e) => {
|
|
59
|
+
console.error('Query failed', e);
|
|
60
|
+
return reject(e);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
listAllDocuments();
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
Utilities.prototype.iterateUsers = function (callback, options) {
|
|
69
|
+
const self = this;
|
|
70
|
+
const Manager = self.Manager;
|
|
71
|
+
const admin = Manager.libraries.admin;
|
|
72
|
+
|
|
73
|
+
return new Promise(function(resolve, reject) {
|
|
74
|
+
let batch = -1;
|
|
75
|
+
|
|
76
|
+
options = options || {};
|
|
77
|
+
options.log = options.log;
|
|
78
|
+
|
|
79
|
+
function listAllUsers(nextPageToken) {
|
|
80
|
+
// List batch of users, 1000 at a time.
|
|
81
|
+
admin.auth()
|
|
82
|
+
.listUsers(1000, nextPageToken)
|
|
83
|
+
.then(async (listUsersResult) => {
|
|
84
|
+
|
|
85
|
+
batch++;
|
|
86
|
+
|
|
87
|
+
if (options.log) {
|
|
88
|
+
console.log('Processing batch:', batch);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
callback({
|
|
92
|
+
snap: listUsersResult, users: listUsersResult.users,
|
|
93
|
+
}, batch)
|
|
94
|
+
.then(r => {
|
|
95
|
+
if (listUsersResult.pageToken) {
|
|
96
|
+
listAllUsers(listUsersResult.pageToken);
|
|
97
|
+
} else {
|
|
98
|
+
return resolve();
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.catch((e) => {
|
|
102
|
+
console.error('Callback failed', e);
|
|
103
|
+
return reject(e)
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
})
|
|
107
|
+
.catch((e) => {
|
|
108
|
+
console.error('Query failed', e);
|
|
109
|
+
return reject(e)
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
listAllUsers();
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
module.exports = Utilities;
|
package/src/manager/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { get, merge } = require('lodash');
|
|
4
4
|
const jetpack = require('fs-jetpack');
|
|
5
|
+
const JSON5 = require('json5');
|
|
5
6
|
// const { debug, log, error, warn } = require('firebase-functions/lib/logger');
|
|
6
7
|
// let User;
|
|
7
8
|
// let Analytics;
|
|
@@ -45,6 +46,7 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
45
46
|
options.firebaseConfig = options.firebaseConfig;
|
|
46
47
|
options.useFirebaseLogger = typeof options.useFirebaseLogger === 'undefined' ? true : options.useFirebaseLogger;
|
|
47
48
|
options.serviceAccountPath = typeof options.serviceAccountPath === 'undefined' ? 'service-account.json' : options.serviceAccountPath;
|
|
49
|
+
options.backendManagerConfigPath = typeof options.backendManagerConfigPath === 'undefined' ? 'backend-manager-config.json' : options.backendManagerConfigPath;
|
|
48
50
|
options.uniqueAppName = options.uniqueAppName || undefined;
|
|
49
51
|
options.assistant = options.assistant || {};
|
|
50
52
|
// options.assistant.optionsLogString = options.assistant.optionsLogString || undefined;
|
|
@@ -71,10 +73,11 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
71
73
|
self.project = options.firebaseConfig || JSON.parse(process.env.FIREBASE_CONFIG || '{}');
|
|
72
74
|
self.project.resourceZone = options.resourceZone;
|
|
73
75
|
self.project.serviceAccountPath = path.resolve(self.cwd, options.serviceAccountPath)
|
|
74
|
-
|
|
76
|
+
self.project.backendManagerConfigPath = path.resolve(self.cwd, options.backendManagerConfigPath)
|
|
77
|
+
|
|
75
78
|
self.package = resolveProjectPackage();
|
|
76
79
|
self.config = merge(
|
|
77
|
-
|
|
80
|
+
requireJSON5(self.project.backendManagerConfigPath),
|
|
78
81
|
self.libraries.functions.config()
|
|
79
82
|
);
|
|
80
83
|
|
|
@@ -119,6 +122,8 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
119
122
|
|
|
120
123
|
if (options.log) {
|
|
121
124
|
self.assistant.log('process.env', process.env, {environment: 'production'})
|
|
125
|
+
console.log('Resolved serviceAccountPath', self.project.serviceAccountPath);
|
|
126
|
+
console.log('Resolved backendManagerConfigPath', self.project.backendManagerConfigPath);
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
// Setup sentry
|
|
@@ -154,13 +159,19 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
154
159
|
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
155
160
|
self.libraries.initializedAdmin = self.libraries.admin.initializeApp();
|
|
156
161
|
} else {
|
|
162
|
+
const serviceAccount = require(self.project.serviceAccountPath);
|
|
157
163
|
self.libraries.initializedAdmin = self.libraries.admin.initializeApp({
|
|
158
|
-
credential: self.libraries.admin.credential.cert(
|
|
159
|
-
require(self.project.serviceAccountPath)
|
|
160
|
-
),
|
|
164
|
+
credential: self.libraries.admin.credential.cert(serviceAccount),
|
|
161
165
|
databaseURL: self.project.databaseURL,
|
|
162
166
|
}, options.uniqueAppName);
|
|
167
|
+
|
|
168
|
+
// const loadedProjectId = get(self.libraries.initializedAdmin, 'options_.credential.projectId', null);
|
|
169
|
+
const loadedProjectId = serviceAccount.project_id;
|
|
170
|
+
if (!loadedProjectId || !loadedProjectId.includes(self.config.app.id)) {
|
|
171
|
+
self.assistant.error(`Loaded app may have wrong service account: ${loadedProjectId} =/= ${self.config.app.id}`, {environment: 'production'});
|
|
172
|
+
}
|
|
163
173
|
}
|
|
174
|
+
|
|
164
175
|
} catch (e) {
|
|
165
176
|
self.assistant.error('Failed to call .initializeApp()', e, {environment: 'production'});
|
|
166
177
|
}
|
|
@@ -393,6 +404,18 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
393
404
|
self.storage();
|
|
394
405
|
}
|
|
395
406
|
|
|
407
|
+
if (self.assistant.meta.environment === 'development') {
|
|
408
|
+
setTimeout(function () {
|
|
409
|
+
console.log('Fetching meta/stats...');
|
|
410
|
+
self.libraries.admin
|
|
411
|
+
.firestore().doc('meta/stats')
|
|
412
|
+
.get()
|
|
413
|
+
.then(doc => {
|
|
414
|
+
console.log('meta/stats', doc.data());
|
|
415
|
+
})
|
|
416
|
+
}, 3000);
|
|
417
|
+
}
|
|
418
|
+
|
|
396
419
|
return self;
|
|
397
420
|
};
|
|
398
421
|
|
|
@@ -532,6 +555,12 @@ Manager.prototype.ApiManager = function () {
|
|
|
532
555
|
return new self.libraries.ApiManager(self, ...arguments);
|
|
533
556
|
};
|
|
534
557
|
|
|
558
|
+
Manager.prototype.Utilities = function () {
|
|
559
|
+
const self = this;
|
|
560
|
+
self.libraries.Utilities = self.libraries.Utilities || require('./helpers/utilities.js');
|
|
561
|
+
return new self.libraries.Utilities(self, ...arguments);
|
|
562
|
+
};
|
|
563
|
+
|
|
535
564
|
Manager.prototype.storage = function (options) {
|
|
536
565
|
const self = this;
|
|
537
566
|
options = options || {};
|
|
@@ -631,4 +660,8 @@ function resolveProjectPackage() {
|
|
|
631
660
|
} catch (e) {}
|
|
632
661
|
}
|
|
633
662
|
|
|
663
|
+
function requireJSON5(p) {
|
|
664
|
+
return JSON5.parse(jetpack.read(p))
|
|
665
|
+
}
|
|
666
|
+
|
|
634
667
|
module.exports = Manager;
|