backend-manager 3.2.171 → 3.2.173
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 +5 -5
- package/src/cli/cli.js +27 -11
- package/dist/cli/cli.js +0 -1534
- package/dist/manager/functions/core/actions/api/admin/backup.js +0 -338
- package/dist/manager/functions/core/actions/api/admin/create-post.js +0 -388
- package/dist/manager/functions/core/actions/api/admin/cron.js +0 -37
- package/dist/manager/functions/core/actions/api/admin/database-read.js +0 -35
- package/dist/manager/functions/core/actions/api/admin/database-write.js +0 -39
- package/dist/manager/functions/core/actions/api/admin/edit-post.js +0 -158
- package/dist/manager/functions/core/actions/api/admin/firestore-query.js +0 -165
- package/dist/manager/functions/core/actions/api/admin/firestore-read.js +0 -38
- package/dist/manager/functions/core/actions/api/admin/firestore-write.js +0 -54
- package/dist/manager/functions/core/actions/api/admin/get-stats.js +0 -269
- package/dist/manager/functions/core/actions/api/admin/payment-processor.js +0 -57
- package/dist/manager/functions/core/actions/api/admin/run-hook.js +0 -95
- package/dist/manager/functions/core/actions/api/admin/send-notification.js +0 -197
- package/dist/manager/functions/core/actions/api/admin/sync-users.js +0 -125
- package/dist/manager/functions/core/actions/api/admin/templates/post.html +0 -16
- package/dist/manager/functions/core/actions/api/firebase/get-providers.js +0 -102
- package/dist/manager/functions/core/actions/api/general/emails/general:download-app-link.js +0 -21
- package/dist/manager/functions/core/actions/api/general/fetch-post.js +0 -99
- package/dist/manager/functions/core/actions/api/general/generate-uuid.js +0 -41
- package/dist/manager/functions/core/actions/api/general/send-email.js +0 -112
- package/dist/manager/functions/core/actions/api/handler/create-post.js +0 -146
- package/dist/manager/functions/core/actions/api/special/setup-electron-manager-client.js +0 -103
- package/dist/manager/functions/core/actions/api/template.js +0 -33
- package/dist/manager/functions/core/actions/api/test/authenticate.js +0 -22
- package/dist/manager/functions/core/actions/api/test/create-test-accounts.js +0 -27
- package/dist/manager/functions/core/actions/api/test/lab.js +0 -55
- package/dist/manager/functions/core/actions/api/test/redirect.js +0 -26
- package/dist/manager/functions/core/actions/api/test/webhook.js +0 -30
- package/dist/manager/functions/core/actions/api/user/create-custom-token.js +0 -32
- package/dist/manager/functions/core/actions/api/user/delete.js +0 -68
- package/dist/manager/functions/core/actions/api/user/get-active-sessions.js +0 -45
- package/dist/manager/functions/core/actions/api/user/get-subscription-info.js +0 -49
- package/dist/manager/functions/core/actions/api/user/oauth2/discord.js +0 -114
- package/dist/manager/functions/core/actions/api/user/oauth2/google.js +0 -99
- package/dist/manager/functions/core/actions/api/user/oauth2.js +0 -476
- package/dist/manager/functions/core/actions/api/user/regenerate-api-keys.js +0 -54
- package/dist/manager/functions/core/actions/api/user/resolve.js +0 -32
- package/dist/manager/functions/core/actions/api/user/sign-out-all-sessions.js +0 -118
- package/dist/manager/functions/core/actions/api/user/sign-up copy.js +0 -544
- package/dist/manager/functions/core/actions/api/user/sign-up.js +0 -99
- package/dist/manager/functions/core/actions/api/user/submit-feedback.js +0 -96
- package/dist/manager/functions/core/actions/api/user/validate-settings.js +0 -86
- package/dist/manager/functions/core/actions/api.js +0 -354
- package/dist/manager/functions/core/actions/create-post-handler.js +0 -184
- package/dist/manager/functions/core/actions/generate-uuid.js +0 -62
- package/dist/manager/functions/core/actions/sign-up-handler.js +0 -205
- package/dist/manager/functions/core/admin/create-post.js +0 -206
- package/dist/manager/functions/core/admin/firestore-write.js +0 -72
- package/dist/manager/functions/core/admin/get-stats.js +0 -218
- package/dist/manager/functions/core/admin/query.js +0 -198
- package/dist/manager/functions/core/admin/send-notification.js +0 -206
- package/dist/manager/functions/core/cron/daily/ghostii-auto-publisher.js +0 -377
- package/dist/manager/functions/core/cron/daily/reset-usage.js +0 -197
- package/dist/manager/functions/core/cron/daily.js +0 -114
- package/dist/manager/functions/core/events/auth/before-create.js +0 -124
- package/dist/manager/functions/core/events/auth/before-signin.js +0 -62
- package/dist/manager/functions/core/events/auth/on-create copy.js +0 -121
- package/dist/manager/functions/core/events/auth/on-create.js +0 -564
- package/dist/manager/functions/core/events/auth/on-delete.js +0 -72
- package/dist/manager/functions/core/events/firestore/on-subscription.js +0 -107
- package/dist/manager/functions/test/authenticate.js +0 -38
- package/dist/manager/functions/test/create-test-accounts.js +0 -144
- package/dist/manager/functions/test/webhook.js +0 -37
- package/dist/manager/functions/wrappers/mailchimp/addToList.js +0 -25
- package/dist/manager/helpers/analytics copy.js +0 -217
- package/dist/manager/helpers/analytics.js +0 -467
- package/dist/manager/helpers/api-manager.js +0 -324
- package/dist/manager/helpers/assistant.js +0 -1043
- package/dist/manager/helpers/metadata.js +0 -32
- package/dist/manager/helpers/middleware.js +0 -154
- package/dist/manager/helpers/roles.js +0 -69
- package/dist/manager/helpers/settings.js +0 -158
- package/dist/manager/helpers/subscription-resolver-new.js +0 -828
- package/dist/manager/helpers/subscription-resolver.js +0 -842
- package/dist/manager/helpers/usage.js +0 -381
- package/dist/manager/helpers/user.js +0 -198
- package/dist/manager/helpers/utilities.js +0 -292
- package/dist/manager/index.js +0 -1076
- package/dist/manager/libraries/openai.js +0 -460
- package/dist/manager/routes/restart/index.js +0 -52
- package/dist/manager/routes/test/index.js +0 -43
- package/dist/manager/schemas/restart.js +0 -13
- package/dist/manager/schemas/test.js +0 -13
- package/dist/require.js +0 -3
package/dist/cli/cli.js
DELETED
|
@@ -1,1534 +0,0 @@
|
|
|
1
|
-
// CLI GUIDE:
|
|
2
|
-
// https://www.twilio.com/blog/how-to-build-a-cli-with-node-js
|
|
3
|
-
// https://www.npmjs.com/package/@dkundel/create-project
|
|
4
|
-
|
|
5
|
-
// https://www.sitepoint.com/javascript-command-line-interface-cli-node-js/
|
|
6
|
-
// https://github.com/sitepoint-editors/ginit
|
|
7
|
-
|
|
8
|
-
const jetpack = require('fs-jetpack');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const chalk = require('chalk');
|
|
11
|
-
const _ = require('lodash');
|
|
12
|
-
const log = console.log;
|
|
13
|
-
const Npm = require('npm-api');
|
|
14
|
-
const semver = require('semver');
|
|
15
|
-
const inquirer = require('inquirer');
|
|
16
|
-
const { spawn, child, exec, fork } = require('child_process');
|
|
17
|
-
const JSON5 = require('json5');
|
|
18
|
-
const fetch = require('wonderful-fetch');
|
|
19
|
-
const argv = require('yargs').argv;
|
|
20
|
-
const powertools = require('node-powertools');
|
|
21
|
-
|
|
22
|
-
// function parseArgumentsIntoOptions(rawArgs) {
|
|
23
|
-
// const args = arg(
|
|
24
|
-
// {
|
|
25
|
-
// '--git': Boolean,
|
|
26
|
-
// '--yes': Boolean,
|
|
27
|
-
// '--install': Boolean,
|
|
28
|
-
// '-g': '--git',
|
|
29
|
-
// '-y': '--yes',
|
|
30
|
-
// '-i': '--install',
|
|
31
|
-
// },
|
|
32
|
-
// {
|
|
33
|
-
// argv: rawArgs.slice(2),
|
|
34
|
-
// }
|
|
35
|
-
// );
|
|
36
|
-
// return {
|
|
37
|
-
// skipPrompts: args['--yes'] || false,
|
|
38
|
-
// git: args['--git'] || false,
|
|
39
|
-
// template: args._[0],
|
|
40
|
-
// runInstall: args['--install'] || false,
|
|
41
|
-
// };
|
|
42
|
-
// }
|
|
43
|
-
|
|
44
|
-
let bem_giRegex = 'Set in .setup()'
|
|
45
|
-
let bem_giRegexOuter = /# BEM>>>(.*\n?)# <<<BEM/sg;
|
|
46
|
-
let bem_allRulesRegex = /(\/\/\/---backend-manager---\/\/\/)(.*?)(\/\/\/---------end---------\/\/\/)/sgm;
|
|
47
|
-
let bem_allRulesDefaultRegex = /(\/\/\/---default-rules---\/\/\/)(.*?)(\/\/\/---------end---------\/\/\/)/sgm;
|
|
48
|
-
let bem_allRulesBackupRegex = /({{\s*?backend-manager\s*?}})/sgm;
|
|
49
|
-
let MOCHA_PKG_SCRIPT = 'mocha ../test/ --recursive --timeout=10000';
|
|
50
|
-
let NPM_CLEAN_SCRIPT = 'rm -fr node_modules && rm -fr package-lock.json && npm cache clean --force && npm install && npm rb';
|
|
51
|
-
let NOFIX_TEXT = chalk.red(`There is no automatic fix for this check.`);
|
|
52
|
-
let runtimeconfigTemplate = loadJSON(`${__dirname}/../../templates/runtimeconfig.json`);
|
|
53
|
-
let bemConfigTemplate = loadJSON(`${__dirname}/../../templates/backend-manager-config.json`);
|
|
54
|
-
|
|
55
|
-
function Main() {
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
Main.prototype.process = async function (args) {
|
|
59
|
-
const self = this;
|
|
60
|
-
self.options = {};
|
|
61
|
-
self.argv = argv;
|
|
62
|
-
self.firebaseProjectPath = process.cwd();
|
|
63
|
-
self.firebaseProjectPath = self.firebaseProjectPath.match(/\/functions$/) ? self.firebaseProjectPath.replace(/\/functions$/, '') : self.firebaseProjectPath;
|
|
64
|
-
self.testCount = 0;
|
|
65
|
-
self.testTotal = 0;
|
|
66
|
-
self.default = {};
|
|
67
|
-
self.packageJSON = require('../../package.json');
|
|
68
|
-
self.default.version = self.packageJSON.version;
|
|
69
|
-
|
|
70
|
-
for (var i = 0; i < args.length; i++) {
|
|
71
|
-
self.options[args[i]] = true;
|
|
72
|
-
}
|
|
73
|
-
// console.log(args);
|
|
74
|
-
// console.log(options);
|
|
75
|
-
if (self.options.v || self.options.version || self.options['-v'] || self.options['-version']) {
|
|
76
|
-
console.log(`Backend manager is version: ${self.default.version}`);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// https://gist.github.com/timneutkens/f2933558b8739bbf09104fb27c5c9664
|
|
80
|
-
if (self.options.clear) {
|
|
81
|
-
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J");
|
|
82
|
-
console.clear();
|
|
83
|
-
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J");
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Log CWD
|
|
87
|
-
if (self.options.cwd) {
|
|
88
|
-
console.log('cwd: ', self.firebaseProjectPath);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Run setup
|
|
92
|
-
if (self.options.setup) {
|
|
93
|
-
// console.log(`Running Setup`);
|
|
94
|
-
// console.log(`node:`, process.versions.node);
|
|
95
|
-
// console.log(`pwd:`, await execute('pwd').catch(e => e));
|
|
96
|
-
// console.log(`node:`, await execute('node --version').catch(e => e));
|
|
97
|
-
// console.log(`firebase-tools:`, await execute('firebase --version').catch(e => e));
|
|
98
|
-
// console.log('');
|
|
99
|
-
await cmd_configGet(self).catch(e => log(chalk.red(`Failed to run config:get`)));
|
|
100
|
-
await self.setup();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Install local BEM
|
|
104
|
-
if ((self.options.i || self.options.install) && (self.options.local || self.options.dev || self.options.development)) {
|
|
105
|
-
await uninstallPkg('backend-manager');
|
|
106
|
-
// return await installPkg('file:../../../ITW-Creative-Works/backend-manager');
|
|
107
|
-
return await installPkg('file:/Users/ian/Developer/Repositories/ITW-Creative-Works/backend-manager');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Install live BEM
|
|
111
|
-
if ((self.options.i || self.options.install) && (self.options.live || self.options.prod || self.options.production)) {
|
|
112
|
-
await uninstallPkg('backend-manager');
|
|
113
|
-
return await installPkg('backend-manager');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Serve firebase
|
|
117
|
-
if (self.options.serve) {
|
|
118
|
-
if (!self.options.quick && !self.options.q) {
|
|
119
|
-
}
|
|
120
|
-
await cmd_configGet(self);
|
|
121
|
-
await self.setup();
|
|
122
|
-
|
|
123
|
-
let port = self.argv.port || _.get(self.argv, '_', [])[1] || '5000';
|
|
124
|
-
let ls = spawn(`firebase serve --port ${port}`, {shell: true});
|
|
125
|
-
|
|
126
|
-
ls.stdout.on('data', (data) => {
|
|
127
|
-
console.log(`${cleanOutput(data)}`);
|
|
128
|
-
});
|
|
129
|
-
ls.stderr.on('data', (data) => {
|
|
130
|
-
console.error(chalk.red(`${cleanOutput(data)}`));
|
|
131
|
-
// ls = null;
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Get indexes
|
|
136
|
-
if (self.options['firestore:indexes:get'] || self.options['firestore:indexes'] || self.options['indexes:get']) {
|
|
137
|
-
return await cmd_indexesGet(self, undefined, true);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Get config
|
|
141
|
-
if (self.options['functions:config:get'] || self.options['config:get']) {
|
|
142
|
-
return await cmd_configGet(self);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Set config
|
|
146
|
-
if (self.options['functions:config:set'] || self.options['config:set']) {
|
|
147
|
-
await cmd_configSet(self);
|
|
148
|
-
return await cmd_configGet(self);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Unset config
|
|
152
|
-
if (self.options['functions:config:unset'] || self.options['config:unset'] || self.options['config:delete'] || self.options['config:remove']) {
|
|
153
|
-
await cmd_configUnset(self);
|
|
154
|
-
return await cmd_configGet(self);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Get rules
|
|
158
|
-
if (self.options['rules:default'] || self.options['rules:getdefault']) {
|
|
159
|
-
self.getRulesFile();
|
|
160
|
-
console.log(self.default.firestoreRulesWhole.match(bem_allRulesDefaultRegex)[0].replace(' ///', '///'));
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Deploy
|
|
165
|
-
if (self.options.deploy) {
|
|
166
|
-
await self.setup();
|
|
167
|
-
|
|
168
|
-
// Quick check that not using local packages
|
|
169
|
-
let deps = JSON.stringify(self.package.dependencies)
|
|
170
|
-
let hasLocal = deps.includes('file:');
|
|
171
|
-
if (hasLocal) {
|
|
172
|
-
log(chalk.red(`Please remove local packages before deploying!`));
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
// let ls = spawn('firebase', ['deploy', '--only', 'functions']);
|
|
176
|
-
// let ls = spawn('firebase', ['deploy', '--only', 'functions,firestore:rules']);
|
|
177
|
-
let ls = spawn('firebase deploy --only functions,firestore:rules', {shell: true});
|
|
178
|
-
ls.stdout.on('data', (data) => {
|
|
179
|
-
// console.log(`${cleanOutput(data)}`);
|
|
180
|
-
console.log(`${cleanOutput(data)}`);
|
|
181
|
-
});
|
|
182
|
-
ls.stderr.on('data', (data) => {
|
|
183
|
-
console.error(chalk.red(`${cleanOutput(data)}`));
|
|
184
|
-
// ls = null;
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Test
|
|
189
|
-
if (self.options['test']) {
|
|
190
|
-
await self.setup();
|
|
191
|
-
// firebase emulators:exec --only firestore 'npm test'
|
|
192
|
-
// let ls = spawn('firebase', ['emulators:exec', '--only', 'firestore', 'npm test']);
|
|
193
|
-
// https://stackoverflow.com/questions/9722407/how-do-you-install-and-run-mocha-the-node-js-testing-module-getting-mocha-co
|
|
194
|
-
let ls = spawn(`firebase emulators:exec --only firestore "npx ${MOCHA_PKG_SCRIPT}"`, {shell: true});
|
|
195
|
-
ls.stdout.on('data', (data) => {
|
|
196
|
-
console.log(`${cleanOutput(data)}`);
|
|
197
|
-
});
|
|
198
|
-
ls.stderr.on('data', (data) => {
|
|
199
|
-
console.error(chalk.red(`${cleanOutput(data)}`));
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Clean
|
|
204
|
-
if (self.options['clean:npm']) {
|
|
205
|
-
// await self.setup();
|
|
206
|
-
// firebase emulators:exec --only firestore 'npm test'
|
|
207
|
-
let ls = spawn(`${NPM_CLEAN_SCRIPT}`, {shell: true});
|
|
208
|
-
ls.stdout.on('data', (data) => {
|
|
209
|
-
console.log(`${cleanOutput(data)}`);
|
|
210
|
-
});
|
|
211
|
-
ls.stderr.on('data', (data) => {
|
|
212
|
-
console.error(chalk.red(`${cleanOutput(data)}`));
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// if (self.options['url']) {
|
|
217
|
-
// // await self.setup();
|
|
218
|
-
// // firebase emulators:exec --only firestore 'npm test'
|
|
219
|
-
// log(self.projectUrl)
|
|
220
|
-
// }
|
|
221
|
-
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
module.exports = Main;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Main.prototype.getRulesFile = function () {
|
|
228
|
-
const self = this;
|
|
229
|
-
self.default.firestoreRulesWhole = (jetpack.read(path.resolve(`${__dirname}/../../templates/firestore.rules`))).replace('=0.0.0-', `=${self.default.version}-`);
|
|
230
|
-
self.default.firestoreRulesCore = self.default.firestoreRulesWhole.match(bem_allRulesRegex)[0];
|
|
231
|
-
|
|
232
|
-
self.default.databaseRulesWhole = (jetpack.read(path.resolve(`${__dirname}/../../templates/database.rules.json`))).replace('=0.0.0-', `=${self.default.version}-`);
|
|
233
|
-
self.default.databaseRulesCore = self.default.databaseRulesWhole.match(bem_allRulesRegex)[0];
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
Main.prototype.setup = async function () {
|
|
237
|
-
const self = this;
|
|
238
|
-
let cwd = jetpack.cwd();
|
|
239
|
-
|
|
240
|
-
log(chalk.green(`\n---- RUNNING SETUP v${self.default.version} ----`));
|
|
241
|
-
|
|
242
|
-
// Load files
|
|
243
|
-
self.package = loadJSON(`${self.firebaseProjectPath}/functions/package.json`);
|
|
244
|
-
self.firebaseJSON = loadJSON(`${self.firebaseProjectPath}/firebase.json`);
|
|
245
|
-
self.firebaseRC = loadJSON(`${self.firebaseProjectPath}/.firebaserc`);
|
|
246
|
-
self.runtimeConfigJSON = loadJSON(`${self.firebaseProjectPath}/functions/.runtimeconfig.json`);
|
|
247
|
-
self.remoteconfigJSON = loadJSON(`${self.firebaseProjectPath}/remoteconfig.template.json`);
|
|
248
|
-
self.projectPackage = loadJSON(`${self.firebaseProjectPath}/package.json`);
|
|
249
|
-
self.bemConfigJSON = loadJSON(`${self.firebaseProjectPath}/functions/backend-manager-config.json`);
|
|
250
|
-
self.gitignore = jetpack.read(`${self.firebaseProjectPath}/functions/.gitignore`) || '';
|
|
251
|
-
|
|
252
|
-
// Check if package exists
|
|
253
|
-
if (!hasContent(self.package)) {
|
|
254
|
-
log(chalk.red(`Missing functions/package.json :(`));
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Check if we're running from the functions folder
|
|
259
|
-
if (!cwd.endsWith('functions') && !cwd.endsWith('functions/')) {
|
|
260
|
-
log(chalk.red(`Please run ${chalk.bold('npx bm setup')} from the ${chalk.bold('functions')} folder. Run ${chalk.bold('cd functions')}.`));
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Load the rules files
|
|
265
|
-
self.getRulesFile();
|
|
266
|
-
|
|
267
|
-
self.default.rulesVersionRegex = new RegExp(`///---version=${self.default.version}---///`)
|
|
268
|
-
// bem_giRegex = new RegExp(jetpack.read(path.resolve(`${__dirname}/../../templates/gitignore.md`)).replace(/\./g, '\\.'), 'm' )
|
|
269
|
-
bem_giRegex = new RegExp(jetpack.read(path.resolve(`${__dirname}/../../templates/gitignore.md`)), 'm' )
|
|
270
|
-
|
|
271
|
-
// tests
|
|
272
|
-
self.projectName = self.firebaseRC.projects.default;
|
|
273
|
-
self.projectUrl = `https://console.firebase.google.com/project/${self.projectName}`;
|
|
274
|
-
|
|
275
|
-
self.bemApiURL = `https://us-central1-${self?.firebaseRC?.projects?.default}.cloudfunctions.net/bm_api?authenticationToken=${self?.runtimeConfigJSON?.backend_manager?.key}`;
|
|
276
|
-
|
|
277
|
-
// Log
|
|
278
|
-
log(`ID: `, chalk.bold(`${self.projectName}`));
|
|
279
|
-
log(`URL:`, chalk.bold(`${self.projectUrl}`));
|
|
280
|
-
|
|
281
|
-
if (!self.package || !self.package.engines || !self.package.engines.node) {
|
|
282
|
-
throw new Error('Missing <engines.node> in package.json')
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Tests
|
|
286
|
-
await self.test('is a firebase project', async function () {
|
|
287
|
-
let exists = jetpack.exists(`${self.firebaseProjectPath}/firebase.json`);
|
|
288
|
-
|
|
289
|
-
return exists;
|
|
290
|
-
}, fix_isFirebase);
|
|
291
|
-
|
|
292
|
-
await self.test(`using at least Node.js v${self.packageJSON.engines.node}`, function () {
|
|
293
|
-
const engineReqMajor = parseInt(self.packageJSON.engines.node.split('.')[0]);
|
|
294
|
-
const engineHasMajor = parseInt(self.package.engines.node.split('.')[0]);
|
|
295
|
-
const processMajor = parseInt(process.versions.node.split('.')[0]);
|
|
296
|
-
|
|
297
|
-
if (processMajor < engineReqMajor) {
|
|
298
|
-
return new Error(`Please use at least version ${engineReqMajor} of Node.js with this project. You need to update your package.json and your .nvmrc file. Then, make sure to run ${chalk.bold(`nvm use ${engineReqMajor}`)}`)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (engineHasMajor !== engineReqMajor) {
|
|
302
|
-
console.log(chalk.yellow(`You are using Node.js version ${processMajor} but this project suggests ${engineReqMajor}.`));
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return engineHasMajor >= engineReqMajor;
|
|
306
|
-
}, fix_nodeVersion);
|
|
307
|
-
|
|
308
|
-
await self.test('.nvmrc file has proper version', async function () {
|
|
309
|
-
const engineReqMajor = parseInt(self.packageJSON.engines.node.split('.')[0]);
|
|
310
|
-
const nvmrc = parseInt((jetpack.read(`${self.firebaseProjectPath}/functions/.nvmrc`) || '0').trim().replace(/v|\/|\*/g, ''));
|
|
311
|
-
|
|
312
|
-
// return nvmrc === `v${self.packageJSON.engines.node}/*`
|
|
313
|
-
return nvmrc >= engineReqMajor;
|
|
314
|
-
}, fix_nvmrc);
|
|
315
|
-
|
|
316
|
-
// await self.test('project level package.json exists', async function () {
|
|
317
|
-
// return !!(self.projectPackage && self.projectPackage.version && self.projectPackage.name);
|
|
318
|
-
// }, fix_projpackage);
|
|
319
|
-
|
|
320
|
-
await self.test('functions level package.json exists', async function () {
|
|
321
|
-
return !!self.package && !!self.package.dependencies && !!self.package.devDependencies && !!self.package.version;
|
|
322
|
-
}, fix_functionspackage);
|
|
323
|
-
|
|
324
|
-
// await self.test('functions level package.json has updated version', async function () {
|
|
325
|
-
// return self.package.version === self.projectPackage.version;
|
|
326
|
-
// }, fix_packageversion);
|
|
327
|
-
|
|
328
|
-
await self.test('using updated firebase-admin', async function () {
|
|
329
|
-
let pkg = 'firebase-admin';
|
|
330
|
-
// let latest = semver.clean(await getPkgVersion(pkg));
|
|
331
|
-
let latest = semver.clean(cleanPackageVersion(self.packageJSON.dependencies['firebase-admin']));
|
|
332
|
-
let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
|
|
333
|
-
const majorVersionMismatch = ((semver.major(latest) > semver.major(mine)));
|
|
334
|
-
let bemv = cleanPackageVersion(self.packageJSON.dependencies[pkg]);
|
|
335
|
-
bemPackageVersionWarning(pkg, bemv, latest);
|
|
336
|
-
|
|
337
|
-
if (majorVersionMismatch) {
|
|
338
|
-
console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
return !(semver.gt(latest, mine)) || majorVersionMismatch;
|
|
342
|
-
}, fix_fba);
|
|
343
|
-
|
|
344
|
-
await self.test('using updated firebase-functions', async function () {
|
|
345
|
-
let pkg = 'firebase-functions';
|
|
346
|
-
// let latest = semver.clean(await getPkgVersion(pkg));
|
|
347
|
-
let latest = semver.clean(cleanPackageVersion(self.packageJSON.dependencies['firebase-functions']));
|
|
348
|
-
let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
|
|
349
|
-
const majorVersionMismatch = ((semver.major(latest) > semver.major(mine)));
|
|
350
|
-
let bemv = cleanPackageVersion(self.packageJSON.dependencies[pkg]);
|
|
351
|
-
bemPackageVersionWarning(pkg, bemv, latest);
|
|
352
|
-
|
|
353
|
-
if (majorVersionMismatch) {
|
|
354
|
-
console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return !(semver.gt(latest, mine)) || majorVersionMismatch;
|
|
358
|
-
}, fix_fbf);
|
|
359
|
-
|
|
360
|
-
await self.test('using updated backend-manager', async function () {
|
|
361
|
-
let pkg = 'backend-manager';
|
|
362
|
-
let latest = semver.clean(await getPkgVersion(pkg));
|
|
363
|
-
let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
|
|
364
|
-
const majorVersionMismatch = !isLocal(mine) && ((semver.major(latest) > semver.major(mine)));
|
|
365
|
-
|
|
366
|
-
if (majorVersionMismatch) {
|
|
367
|
-
console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return isLocal(mine) || !(semver.gt(latest, mine)) || majorVersionMismatch;
|
|
371
|
-
}, fix_bem);
|
|
372
|
-
|
|
373
|
-
// await self.test('using updated ultimate-jekyll-poster', async function () {
|
|
374
|
-
// let pkg = 'ultimate-jekyll-poster';
|
|
375
|
-
// let latest = semver.clean(await getPkgVersion(pkg));
|
|
376
|
-
// let mine = (self.package.dependencies[pkg] || '0.0.0').replace('^', '').replace('~', '');
|
|
377
|
-
// return isLocal(mine) || !(semver.gt(latest, mine));
|
|
378
|
-
// }, fix_ujp);
|
|
379
|
-
|
|
380
|
-
// await self.test('using updated @firebase/testing', async function () {
|
|
381
|
-
// let pkg = '@firebase/testing';
|
|
382
|
-
// let latest = semver.clean(await getPkgVersion(pkg));
|
|
383
|
-
// let mine = (self.package.devDependencies[pkg] || '0.0.0').replace('^', '').replace('~', '');
|
|
384
|
-
// return isLocal(mine) || !(semver.gt(latest, mine));
|
|
385
|
-
// }, fix_fbTesting);
|
|
386
|
-
|
|
387
|
-
// await self.test('using updated mocha', async function () {
|
|
388
|
-
// let pkg = 'mocha';
|
|
389
|
-
// let latest = semver.clean(await getPkgVersion(pkg));
|
|
390
|
-
// let mine = (self.package.devDependencies[pkg] || '0.0.0').replace('^', '').replace('~', '');
|
|
391
|
-
// return isLocal(mine) || !(semver.gt(latest, mine));
|
|
392
|
-
// }, fix_mocha);
|
|
393
|
-
await self.test(`has "npm start" script`, function () {
|
|
394
|
-
return self.package.scripts.start
|
|
395
|
-
}, fix_startScript);
|
|
396
|
-
|
|
397
|
-
await self.test(`has "npm dist" script`, function () {
|
|
398
|
-
return self.package.scripts.dist
|
|
399
|
-
}, fix_distScript);
|
|
400
|
-
|
|
401
|
-
await self.test('using proper .runtimeconfig', async function () {
|
|
402
|
-
// Set pass
|
|
403
|
-
let pass = true;
|
|
404
|
-
|
|
405
|
-
// Loop through all the keys in the template
|
|
406
|
-
powertools.getKeys(runtimeconfigTemplate).forEach((key) => {
|
|
407
|
-
const userValue = _.get(self.runtimeConfigJSON, key, undefined);
|
|
408
|
-
|
|
409
|
-
// If the user value is undefined, then we need to set pass to false
|
|
410
|
-
if (typeof userValue === 'undefined') {
|
|
411
|
-
pass = false;
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Return result
|
|
416
|
-
return pass;
|
|
417
|
-
}, fix_runtimeConfig);
|
|
418
|
-
|
|
419
|
-
await self.test('using proper backend-manager-config.json', async function () {
|
|
420
|
-
// Set pass
|
|
421
|
-
let pass = true;
|
|
422
|
-
|
|
423
|
-
// Loop through all the keys in the template
|
|
424
|
-
powertools.getKeys(bemConfigTemplate).forEach((key) => {
|
|
425
|
-
const userValue = _.get(self.bemConfigJSON, key, undefined);
|
|
426
|
-
|
|
427
|
-
// If the user value is undefined, then we need to set pass to false
|
|
428
|
-
if (typeof userValue === 'undefined') {
|
|
429
|
-
pass = false;
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
// Return result
|
|
434
|
-
return pass;
|
|
435
|
-
}, fix_bemConfig);
|
|
436
|
-
|
|
437
|
-
await self.test('has correct ID in backend-manager-config.json', async function () {
|
|
438
|
-
// Check if the project name matches the projectId
|
|
439
|
-
if (self.projectName !== self.bemConfigJSON?.firebaseConfig?.projectId) {
|
|
440
|
-
console.error(chalk.red('Mismatch between project name and firebaseConfig.projectId in backend-manager-config.json'));
|
|
441
|
-
return false;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
// Return pass
|
|
445
|
-
return true;
|
|
446
|
-
}, NOFIX);
|
|
447
|
-
|
|
448
|
-
await self.test('has service-account.json', function () {
|
|
449
|
-
let exists = jetpack.exists(`${self.firebaseProjectPath}/functions/service-account.json`);
|
|
450
|
-
return !!exists;
|
|
451
|
-
}, fix_serviceAccount);
|
|
452
|
-
|
|
453
|
-
await self.test('has correct .gitignore', function () {
|
|
454
|
-
let match = self.gitignore.match(bem_giRegexOuter);
|
|
455
|
-
if (!match) {
|
|
456
|
-
return false;
|
|
457
|
-
} else {
|
|
458
|
-
let gitignore = jetpack.read(path.resolve(`${__dirname}/../../templates/gitignore.md`));
|
|
459
|
-
let file = gitignore.match(bem_giRegexOuter) ? RegExp.$1 : 'BAD1';
|
|
460
|
-
let file2 = match[0].match(bem_giRegexOuter) ? RegExp.$1 : 'BAD2';
|
|
461
|
-
return file === file2;
|
|
462
|
-
}
|
|
463
|
-
}, fix_gitignore);
|
|
464
|
-
|
|
465
|
-
// Check firebase.json fields
|
|
466
|
-
await self.test('firestore rules in JSON', () => {
|
|
467
|
-
return self.firebaseJSON?.firestore?.rules === 'firestore.rules'
|
|
468
|
-
}, fix_firestoreRules);
|
|
469
|
-
|
|
470
|
-
await self.test('firestore indexes in JSON', () => {
|
|
471
|
-
return self.firebaseJSON?.firestore?.indexes === 'firestore.indexes.json';
|
|
472
|
-
}, fix_firestoreIndexes);
|
|
473
|
-
|
|
474
|
-
await self.test('realtime rules in JSON', () => {
|
|
475
|
-
return self.firebaseJSON?.database?.rules === 'database.rules.json';
|
|
476
|
-
}, fix_realtimeRules);
|
|
477
|
-
|
|
478
|
-
await self.test('storage rules in JSON', () => {
|
|
479
|
-
return self.firebaseJSON?.storage?.rules === 'storage.rules';
|
|
480
|
-
}, fix_storageRules);
|
|
481
|
-
|
|
482
|
-
await self.test('remoteconfig template in JSON', () => {
|
|
483
|
-
if (hasContent(self.remoteconfigJSON)) {
|
|
484
|
-
return self.firebaseJSON?.remoteconfig?.template === 'remoteconfig.template.json';
|
|
485
|
-
} else {
|
|
486
|
-
return self.firebaseJSON?.remoteconfig?.template === '';
|
|
487
|
-
}
|
|
488
|
-
}, fix_remoteconfigTemplate);
|
|
489
|
-
|
|
490
|
-
await self.test('firestore indexes synced', async function () {
|
|
491
|
-
const tempPath = '_firestore.indexes.json'
|
|
492
|
-
const liveIndexes = await cmd_indexesGet(self, tempPath, false);
|
|
493
|
-
|
|
494
|
-
const localIndexes_exists = jetpack.exists(`${self.firebaseProjectPath}/firestore.indexes.json`);
|
|
495
|
-
let localIndexes
|
|
496
|
-
if (localIndexes_exists) {
|
|
497
|
-
localIndexes = require(`${self.firebaseProjectPath}/firestore.indexes.json`)
|
|
498
|
-
}
|
|
499
|
-
const equal = _.isEqual(liveIndexes, localIndexes);
|
|
500
|
-
|
|
501
|
-
if (localIndexes_exists && !equal) {
|
|
502
|
-
console.log(chalk.red(`To fix this...`));
|
|
503
|
-
console.log(chalk.red(` - ${chalk.bold('npx bm indexes:get')} to overwrite Firestore's local indexes with the live indexes`));
|
|
504
|
-
console.log(chalk.red(' OR'));
|
|
505
|
-
console.log(chalk.red(` - ${chalk.bold('firebase deploy --only firestore:indexes')} to replace the live indexes.`));
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
jetpack.remove(`${self.firebaseProjectPath}/${tempPath}`)
|
|
509
|
-
|
|
510
|
-
return !localIndexes_exists || equal
|
|
511
|
-
}, fix_indexesSync);
|
|
512
|
-
|
|
513
|
-
// await self.test('add roles/datastore.importExportAdmin', async function () {
|
|
514
|
-
// const result = await cmd_iamImportExport(self).catch(e => e);
|
|
515
|
-
// return !(result instanceof Error);
|
|
516
|
-
// }, NOFIX);
|
|
517
|
-
|
|
518
|
-
await self.test('set storage lifecycle policy', async function () {
|
|
519
|
-
const result = await cmd_setStorageLifecycle(self).catch(e => e);
|
|
520
|
-
return !(result instanceof Error);
|
|
521
|
-
}, fix_setStoragePolicy);
|
|
522
|
-
|
|
523
|
-
// Update actual files
|
|
524
|
-
await self.test('update firestore rules file', function () {
|
|
525
|
-
const exists = jetpack.exists(`${self.firebaseProjectPath}/firestore.rules`);
|
|
526
|
-
const contents = jetpack.read(`${self.firebaseProjectPath}/firestore.rules`) || '';
|
|
527
|
-
const containsCore = contents.match(bem_allRulesRegex);
|
|
528
|
-
const matchesVersion = contents.match(self.default.rulesVersionRegex);
|
|
529
|
-
|
|
530
|
-
return (!!exists && !!containsCore && !!matchesVersion);
|
|
531
|
-
}, fix_firestoreRulesFile);
|
|
532
|
-
|
|
533
|
-
await self.test('update firestore indexes file', function () {
|
|
534
|
-
const exists = jetpack.exists(`${self.firebaseProjectPath}/firestore.indexes.json`);
|
|
535
|
-
return (!!exists);
|
|
536
|
-
}, fix_firestoreIndexesFile);
|
|
537
|
-
|
|
538
|
-
await self.test('update realtime rules file', function () {
|
|
539
|
-
const exists = jetpack.exists(`${self.firebaseProjectPath}/database.rules.json`);
|
|
540
|
-
const contents = jetpack.read(`${self.firebaseProjectPath}/database.rules.json`) || '';
|
|
541
|
-
const containsCore = contents.match(bem_allRulesRegex);
|
|
542
|
-
const matchesVersion = contents.match(self.default.rulesVersionRegex);
|
|
543
|
-
|
|
544
|
-
return (!!exists && !!containsCore && !!matchesVersion);
|
|
545
|
-
}, fix_realtimeRulesFile);
|
|
546
|
-
|
|
547
|
-
await self.test('update storage rules file', function () {
|
|
548
|
-
let exists = jetpack.exists(`${self.firebaseProjectPath}/storage.rules`);
|
|
549
|
-
return (!!exists);
|
|
550
|
-
}, fix_storageRulesFile);
|
|
551
|
-
|
|
552
|
-
await self.test('update remoteconfig template file', function () {
|
|
553
|
-
let exists = jetpack.exists(`${self.firebaseProjectPath}/remoteconfig.template.json`);
|
|
554
|
-
return (!!exists);
|
|
555
|
-
}, fix_remoteconfigTemplateFile);
|
|
556
|
-
|
|
557
|
-
// Hosting
|
|
558
|
-
await self.test('hosting is set to dedicated folder in JSON', function () {
|
|
559
|
-
let hosting = _.get(self.firebaseJSON, 'hosting', {});
|
|
560
|
-
return (hosting.public && (hosting.public === 'public' || hosting.public !== '.'))
|
|
561
|
-
}, fix_firebaseHostingFolder);
|
|
562
|
-
|
|
563
|
-
// Hosting
|
|
564
|
-
// await self.test('hosting has auth page', async function () {
|
|
565
|
-
// return await fix_firebaseHostingAuth(self);
|
|
566
|
-
// }, NOFIX);
|
|
567
|
-
|
|
568
|
-
await self.test('update backend-manager-tests.js', function () {
|
|
569
|
-
jetpack.write(`${self.firebaseProjectPath}/test/backend-manager-tests.js`,
|
|
570
|
-
(jetpack.read(path.resolve(`${__dirname}/../../templates/backend-manager-tests.js`)))
|
|
571
|
-
)
|
|
572
|
-
return true;
|
|
573
|
-
}, NOFIX);
|
|
574
|
-
|
|
575
|
-
await self.test('create public .html files', function () {
|
|
576
|
-
const options = {url: self.bemConfigJSON.brand.url}
|
|
577
|
-
// index.html
|
|
578
|
-
const templateIndex = jetpack.read(path.resolve(`${__dirname}/../../templates/public/index.html`));
|
|
579
|
-
jetpack.write(`${self.firebaseProjectPath}/public/index.html`,
|
|
580
|
-
powertools.template(templateIndex, options)
|
|
581
|
-
)
|
|
582
|
-
|
|
583
|
-
// 404.html
|
|
584
|
-
const template404 = jetpack.read(path.resolve(`${__dirname}/../../templates/public/404.html`));
|
|
585
|
-
jetpack.write(`${self.firebaseProjectPath}/public/404.html`,
|
|
586
|
-
powertools.template(template404, options)
|
|
587
|
-
)
|
|
588
|
-
return true;
|
|
589
|
-
}, NOFIX);
|
|
590
|
-
|
|
591
|
-
// await self.test('add roles/datastore.importExportAdmin', function () {
|
|
592
|
-
// const result = await cmd_iamImportExport(self);
|
|
593
|
-
// console.log('---result', result);
|
|
594
|
-
// return true;
|
|
595
|
-
// }, NOFIX);
|
|
596
|
-
|
|
597
|
-
// await self.test('has mocha package.json script', function () {
|
|
598
|
-
// let script = _.get(self.package, 'scripts.test', '')
|
|
599
|
-
// return script === MOCHA_PKG_SCRIPT;
|
|
600
|
-
// }, fix_mochaScript);
|
|
601
|
-
|
|
602
|
-
// await self.test('has clean:npm package.json script', function () {
|
|
603
|
-
// let script = _.get(self.package, 'scripts.clean:npm', '')
|
|
604
|
-
// return script === NPM_CLEAN_SCRIPT;
|
|
605
|
-
// }, fix_cleanNpmScript);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (self.package.dependencies['backend-manager'].includes('file:')) {
|
|
611
|
-
console.log('\n' + chalk.yellow(chalk.bold('Warning: ') + 'You are using the local ' + chalk.bold('backend-manager')));
|
|
612
|
-
} else {
|
|
613
|
-
console.log('\n');
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const statsFetchResult = await fetch(self.bemApiURL, {
|
|
617
|
-
method: 'post',
|
|
618
|
-
timeout: 30000,
|
|
619
|
-
response: 'json',
|
|
620
|
-
body: {
|
|
621
|
-
command: 'admin:get-stats',
|
|
622
|
-
},
|
|
623
|
-
})
|
|
624
|
-
.then(json => json)
|
|
625
|
-
.catch(e => e);
|
|
626
|
-
|
|
627
|
-
if (statsFetchResult instanceof Error) {
|
|
628
|
-
if (!statsFetchResult.message.includes('network timeout')) {
|
|
629
|
-
console.log(chalk.yellow(`Ran into error while fetching stats endpoint`, statsFetchResult));
|
|
630
|
-
}
|
|
631
|
-
} else {
|
|
632
|
-
// console.log(chalk.green(`Stats fetched/created properly.`, JSON.stringify(statsFetchResult)));
|
|
633
|
-
console.log(chalk.green(`Stats fetched/created properly.`));
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
console.log(chalk.green(`Checks finished. Passed ${self.testCount}/${self.testTotal} tests.`));
|
|
637
|
-
if (self.testCount !== self.testTotal) {
|
|
638
|
-
console.log(chalk.yellow(`You should continue to run ${chalk.bold('npx bm setup')} until you pass all tests and fix all errors.`));
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Notify parent that finished with test results
|
|
642
|
-
if (process.send) {
|
|
643
|
-
process.send({
|
|
644
|
-
sender: 'electron-manager',
|
|
645
|
-
command: 'setup:complete',
|
|
646
|
-
payload: {
|
|
647
|
-
passed: self.testCount === self.testTotal,
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
return;
|
|
653
|
-
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
Main.prototype.test = async function(name, fn, fix, args) {
|
|
657
|
-
const self = this;
|
|
658
|
-
let status;
|
|
659
|
-
let passed = await fn();
|
|
660
|
-
return new Promise(async function(resolve, reject) {
|
|
661
|
-
if (passed instanceof Error) {
|
|
662
|
-
log(chalk.red(passed));
|
|
663
|
-
process.exit(0);
|
|
664
|
-
} else if (passed) {
|
|
665
|
-
status = chalk.green('passed');
|
|
666
|
-
self.testCount++;
|
|
667
|
-
self.testTotal++;
|
|
668
|
-
} else {
|
|
669
|
-
status = chalk.red('failed');
|
|
670
|
-
self.testTotal++;
|
|
671
|
-
}
|
|
672
|
-
log(chalk.bold(`[${self.testTotal}]`), `${name}:`, status);
|
|
673
|
-
if (!passed) {
|
|
674
|
-
log(chalk.yellow(`Fixing...`));
|
|
675
|
-
fix(self, args)
|
|
676
|
-
.then(function (result) {
|
|
677
|
-
log(chalk.green(`...done~!`));
|
|
678
|
-
resolve();
|
|
679
|
-
})
|
|
680
|
-
} else {
|
|
681
|
-
resolve();
|
|
682
|
-
}
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
function cleanPackageVersion(v) {
|
|
687
|
-
return v.replace('^', '').replace('~', '');
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// FIXES
|
|
691
|
-
function NOFIX() {
|
|
692
|
-
return new Promise(function(resolve, reject) {
|
|
693
|
-
log(NOFIX_TEXT);
|
|
694
|
-
reject();
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
function bemPackageVersionWarning(package, current, latest) {
|
|
699
|
-
if (semver.gt(latest, current)) {
|
|
700
|
-
log(chalk.yellow(`${package} needs to be updated in backend-manager: ${current} => ${latest}`));
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
async function fix_runtimeConfig(self) {
|
|
705
|
-
return new Promise(function(resolve, reject) {
|
|
706
|
-
// Log
|
|
707
|
-
log(NOFIX_TEXT);
|
|
708
|
-
log(chalk.red(`You need to run ${chalk.bold(`npx bm config:set`)} for each of these keys:`));
|
|
709
|
-
|
|
710
|
-
// Log what keys are missing
|
|
711
|
-
powertools.getKeys(runtimeconfigTemplate).forEach((key) => {
|
|
712
|
-
const userValue = _.get(self.runtimeConfigJSON, key, undefined);
|
|
713
|
-
|
|
714
|
-
if (typeof userValue === 'undefined') {
|
|
715
|
-
log(chalk.red.bold(`${key}`));
|
|
716
|
-
} else {
|
|
717
|
-
log(chalk.red(`${key} (${userValue})`));
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
// Reject
|
|
722
|
-
reject();
|
|
723
|
-
});
|
|
724
|
-
};
|
|
725
|
-
|
|
726
|
-
async function fix_bemConfig(self) {
|
|
727
|
-
return new Promise(function(resolve, reject) {
|
|
728
|
-
// Log
|
|
729
|
-
log(NOFIX_TEXT);
|
|
730
|
-
log(chalk.red(`You need to open backend-manager-config.json and set each of these keys:`));
|
|
731
|
-
|
|
732
|
-
// Write if it doesnt exist
|
|
733
|
-
if (!hasContent(self.bemConfigJSON)) {
|
|
734
|
-
// jetpack.write(`${self.firebaseProjectPath}/functions/backend-manager-config.json`, bemConfigTemplate)
|
|
735
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/backend-manager-config.json`, {})
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
// Log what keys are missing
|
|
739
|
-
powertools.getKeys(bemConfigTemplate).forEach((key) => {
|
|
740
|
-
const userValue = _.get(self.bemConfigJSON, key, undefined);
|
|
741
|
-
|
|
742
|
-
if (typeof userValue === 'undefined') {
|
|
743
|
-
log(chalk.red.bold(`${key}`));
|
|
744
|
-
} else {
|
|
745
|
-
log(chalk.red(`${key} (${userValue})`));
|
|
746
|
-
}
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
// Reject
|
|
750
|
-
reject();
|
|
751
|
-
});
|
|
752
|
-
};
|
|
753
|
-
|
|
754
|
-
async function fix_serviceAccount(self) {
|
|
755
|
-
return new Promise(function(resolve, reject) {
|
|
756
|
-
log(NOFIX_TEXT);
|
|
757
|
-
log(chalk.red(`Please install a service account --> ` + chalk.yellow.red(`${self.projectUrl}/settings/serviceaccounts/adminsdk`)));
|
|
758
|
-
reject();
|
|
759
|
-
});
|
|
760
|
-
};
|
|
761
|
-
|
|
762
|
-
// function fix_mochaScript(self) {
|
|
763
|
-
// return new Promise(function(resolve, reject) {
|
|
764
|
-
// _.set(self.package, 'scripts.test', MOCHA_PKG_SCRIPT);
|
|
765
|
-
// jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
766
|
-
// resolve();
|
|
767
|
-
// });
|
|
768
|
-
// }
|
|
769
|
-
|
|
770
|
-
function fix_startScript(self) {
|
|
771
|
-
return new Promise(function(resolve, reject) {
|
|
772
|
-
_.set(self.package, 'scripts.start', 'firebase serve');
|
|
773
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
774
|
-
resolve();
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
function fix_distScript(self) {
|
|
779
|
-
return new Promise(function(resolve, reject) {
|
|
780
|
-
_.set(self.package, 'scripts.dist', 'firebase deploy');
|
|
781
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
782
|
-
resolve();
|
|
783
|
-
});
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
function fix_setupScript(self) {
|
|
787
|
-
return new Promise(function(resolve, reject) {
|
|
788
|
-
_.set(self.package, 'scripts.setup', 'npx bm setup');
|
|
789
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
790
|
-
resolve();
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
function fix_nodeVersion(self) {
|
|
795
|
-
return new Promise(function(resolve, reject) {
|
|
796
|
-
if (false) {
|
|
797
|
-
_.set(self.package, 'engines.node', self.packageJSON.engines.node)
|
|
798
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
799
|
-
|
|
800
|
-
resolve();
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
throw new Error('Please manually fix your outdated Node.js version')
|
|
804
|
-
});
|
|
805
|
-
};
|
|
806
|
-
|
|
807
|
-
function fix_nvmrc(self) {
|
|
808
|
-
return new Promise(function(resolve, reject) {
|
|
809
|
-
var v = self.packageJSON.engines.node;
|
|
810
|
-
|
|
811
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/.nvmrc`, `v${v}/*`);
|
|
812
|
-
|
|
813
|
-
log(chalk.red(`Please run ${chalk.bold(`nmv use ${v}`)} to use the correct version of Node.js`));
|
|
814
|
-
|
|
815
|
-
throw '';
|
|
816
|
-
});
|
|
817
|
-
};
|
|
818
|
-
|
|
819
|
-
async function fix_isFirebase(self) {
|
|
820
|
-
log(chalk.red(`This is not a firebase project. Please use ${chalk.bold('firebase-init')} to set up.`));
|
|
821
|
-
throw '';
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
function fix_projpackage(self) {
|
|
825
|
-
return new Promise(function(resolve, reject) {
|
|
826
|
-
self.projectPackage = self.projectPackage || {};
|
|
827
|
-
self.projectPackage.name = self.projectPackage.name || self.projectName;
|
|
828
|
-
self.projectPackage.version = self.projectPackage.version || '0.0.1';
|
|
829
|
-
self.projectPackage.dependencies = self.projectPackage.dependencies || {};
|
|
830
|
-
self.projectPackage.devDependencies = self.projectPackage.devDependencies || {};
|
|
831
|
-
|
|
832
|
-
jetpack.write(`${self.firebaseProjectPath}/package.json`, JSON.stringify(self.projectPackage, null, 2) );
|
|
833
|
-
resolve();
|
|
834
|
-
});
|
|
835
|
-
};
|
|
836
|
-
|
|
837
|
-
function fix_functionspackage(self) {
|
|
838
|
-
return new Promise(function(resolve, reject) {
|
|
839
|
-
self.package.dependencies = self.package.dependencies || {};
|
|
840
|
-
self.package.devDependencies = self.package.devDependencies || {};
|
|
841
|
-
self.package.version = self.package.version || '0.0.1';
|
|
842
|
-
|
|
843
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
844
|
-
resolve();
|
|
845
|
-
});
|
|
846
|
-
};
|
|
847
|
-
|
|
848
|
-
function fix_packageversion(self) {
|
|
849
|
-
return new Promise(function(resolve, reject) {
|
|
850
|
-
self.package.version = self.projectPackage.version;
|
|
851
|
-
|
|
852
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/package.json`, JSON.stringify(self.package, null, 2) );
|
|
853
|
-
resolve();
|
|
854
|
-
});
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
async function fix_fbf(self) {
|
|
858
|
-
// console.log('----FIX FBF'); return Promise.resolve();
|
|
859
|
-
return await installPkg('firebase-functions', `@${self.packageJSON.dependencies['firebase-functions']}`)
|
|
860
|
-
};
|
|
861
|
-
async function fix_fba(self) {
|
|
862
|
-
// console.log('----FIX FBA'); return Promise.resolve();
|
|
863
|
-
return await installPkg('firebase-admin', `@${self.packageJSON.dependencies['firebase-admin']}`)
|
|
864
|
-
};
|
|
865
|
-
async function fix_bem(self) {
|
|
866
|
-
await installPkg('backend-manager');
|
|
867
|
-
|
|
868
|
-
console.log(chalk.green(`Process has exited since a new version of backend-manager was installed. Run ${chalk.bold('npx bm setup')} again.`));
|
|
869
|
-
process.exit(0);
|
|
870
|
-
|
|
871
|
-
return;
|
|
872
|
-
};
|
|
873
|
-
|
|
874
|
-
// async function fix_ujp(self) {
|
|
875
|
-
// return await installPkg('ultimate-jekyll-poster')
|
|
876
|
-
// };
|
|
877
|
-
// async function fix_fbTesting(self) {
|
|
878
|
-
// return await installPkg('@firebase/testing', '', '--save-dev')
|
|
879
|
-
// };
|
|
880
|
-
// async function fix_mocha(self) {
|
|
881
|
-
// return await installPkg('mocha', '', '--save-dev')
|
|
882
|
-
// };
|
|
883
|
-
|
|
884
|
-
function fix_gitignore(self) {
|
|
885
|
-
return new Promise(function(resolve, reject) {
|
|
886
|
-
let gi = (jetpack.read(path.resolve(`${__dirname}/../../templates/gitignore.md`)));
|
|
887
|
-
if (self.gitignore.match(bem_giRegexOuter)) {
|
|
888
|
-
self.gitignore = self.gitignore.replace(bem_giRegexOuter, gi);
|
|
889
|
-
} else {
|
|
890
|
-
self.gitignore = gi;
|
|
891
|
-
}
|
|
892
|
-
self.gitignore = self.gitignore.replace(/\n\s*\n$/mg, '\n')
|
|
893
|
-
// self.gitignore = `${self.gitignore}\n${gi}`.replace(/$\n/m,'');
|
|
894
|
-
// self.gitignore = self.gitignore.replace(/$\n/m,'');
|
|
895
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/.gitignore`, self.gitignore);
|
|
896
|
-
resolve();
|
|
897
|
-
});
|
|
898
|
-
};
|
|
899
|
-
|
|
900
|
-
function fix_firestoreRules(self) {
|
|
901
|
-
return new Promise(function(resolve, reject) {
|
|
902
|
-
_.set(self.firebaseJSON, 'firestore.rules', 'firestore.rules')
|
|
903
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
904
|
-
resolve();
|
|
905
|
-
});
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
function fix_firestoreIndexes(self) {
|
|
909
|
-
return new Promise(function(resolve, reject) {
|
|
910
|
-
_.set(self.firebaseJSON, 'firestore.indexes', 'firestore.indexes.json')
|
|
911
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
912
|
-
resolve();
|
|
913
|
-
});
|
|
914
|
-
};
|
|
915
|
-
|
|
916
|
-
function fix_realtimeRules(self) {
|
|
917
|
-
return new Promise(function(resolve, reject) {
|
|
918
|
-
_.set(self.firebaseJSON, 'database.rules', 'database.rules.json')
|
|
919
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
920
|
-
resolve();
|
|
921
|
-
});
|
|
922
|
-
};
|
|
923
|
-
|
|
924
|
-
function fix_storageRules(self) {
|
|
925
|
-
return new Promise(function(resolve, reject) {
|
|
926
|
-
_.set(self.firebaseJSON, 'storage.rules', 'storage.rules')
|
|
927
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
928
|
-
resolve();
|
|
929
|
-
});
|
|
930
|
-
};
|
|
931
|
-
|
|
932
|
-
function fix_remoteconfigTemplate(self) {
|
|
933
|
-
return new Promise(function(resolve, reject) {
|
|
934
|
-
|
|
935
|
-
_.set(self.firebaseJSON, 'remoteconfig.template', hasContent(self.remoteconfigJSON) ? 'remoteconfig.template.json' : '')
|
|
936
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
937
|
-
resolve();
|
|
938
|
-
});
|
|
939
|
-
};
|
|
940
|
-
|
|
941
|
-
function fix_indexesSync(self) {
|
|
942
|
-
return new Promise(function(resolve, reject) {
|
|
943
|
-
inquirer.prompt([
|
|
944
|
-
{
|
|
945
|
-
type: 'confirm',
|
|
946
|
-
name: 'replace',
|
|
947
|
-
message: 'Would you like to replace the local indexes?',
|
|
948
|
-
default: true,
|
|
949
|
-
}
|
|
950
|
-
])
|
|
951
|
-
.then(async (answer) => {
|
|
952
|
-
if (answer.replace) {
|
|
953
|
-
cmd_indexesGet(self, undefined, true)
|
|
954
|
-
.then(r => {
|
|
955
|
-
return resolve();
|
|
956
|
-
})
|
|
957
|
-
} else {
|
|
958
|
-
return reject();
|
|
959
|
-
}
|
|
960
|
-
})
|
|
961
|
-
});
|
|
962
|
-
};
|
|
963
|
-
|
|
964
|
-
function fix_setStoragePolicy(self) {
|
|
965
|
-
return new Promise(function(resolve, reject) {
|
|
966
|
-
// fetch(self.bemApiURL, {
|
|
967
|
-
// method: 'post',
|
|
968
|
-
// timeout: 30000,
|
|
969
|
-
// response: 'json',
|
|
970
|
-
// body: {
|
|
971
|
-
// command: 'admin:backup',
|
|
972
|
-
// },
|
|
973
|
-
// })
|
|
974
|
-
// .then(json => {
|
|
975
|
-
// console.log('Response', json);
|
|
976
|
-
// return resolve();
|
|
977
|
-
// })
|
|
978
|
-
// .catch(e => {
|
|
979
|
-
// console.error(chalk.red(`There is no automatic fix. Please run: \n${chalk.bold('firebase deploy && npx bm setup')}`));
|
|
980
|
-
// return reject();
|
|
981
|
-
// });
|
|
982
|
-
// Log
|
|
983
|
-
console.error(chalk.red(`There is no automatic fix. Please run: \n${chalk.bold('firebase deploy && npx bm setup')}`));
|
|
984
|
-
|
|
985
|
-
// Reject
|
|
986
|
-
return reject();
|
|
987
|
-
});
|
|
988
|
-
};
|
|
989
|
-
|
|
990
|
-
function fix_firestoreRulesFile(self) {
|
|
991
|
-
return new Promise(function(resolve, reject) {
|
|
992
|
-
const name = 'firestore.rules'
|
|
993
|
-
let path = `${self.firebaseProjectPath}/${name}`;
|
|
994
|
-
let exists = jetpack.exists(path);
|
|
995
|
-
let contents = jetpack.read(path) || '';
|
|
996
|
-
|
|
997
|
-
if (!exists || !contents) {
|
|
998
|
-
log(chalk.yellow(`Writing new ${name} file...`));
|
|
999
|
-
jetpack.write(path, self.default.firestoreRulesWhole)
|
|
1000
|
-
contents = jetpack.read(path) || '';
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
let hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
|
|
1004
|
-
|
|
1005
|
-
if (!hasTemplate) {
|
|
1006
|
-
log(chalk.red(`Could not find rules template. Please edit ${name} file and add`), chalk.red(`{{backend-manager}}`), chalk.red(`to it.`));
|
|
1007
|
-
return resolve()
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
let matchesVersion = contents.match(self.default.rulesVersionRegex);
|
|
1011
|
-
if (!matchesVersion) {
|
|
1012
|
-
// console.log('replace wih', self.default.firestoreRulesCore);
|
|
1013
|
-
contents = contents.replace(bem_allRulesBackupRegex, self.default.firestoreRulesCore)
|
|
1014
|
-
contents = contents.replace(bem_allRulesRegex, self.default.firestoreRulesCore)
|
|
1015
|
-
jetpack.write(path, contents)
|
|
1016
|
-
log(chalk.yellow(`Writing core rules to ${name} file...`));
|
|
1017
|
-
}
|
|
1018
|
-
resolve();
|
|
1019
|
-
});
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
|
-
function fix_realtimeRulesFile(self) {
|
|
1023
|
-
return new Promise(function(resolve, reject) {
|
|
1024
|
-
const name = 'database.rules.json'
|
|
1025
|
-
let path = `${self.firebaseProjectPath}/${name}`;
|
|
1026
|
-
let exists = jetpack.exists(path);
|
|
1027
|
-
let contents = jetpack.read(path) || '';
|
|
1028
|
-
|
|
1029
|
-
if (!exists || !contents) {
|
|
1030
|
-
log(chalk.yellow(`Writing new ${name} file...`));
|
|
1031
|
-
jetpack.write(path, self.default.databaseRulesWhole)
|
|
1032
|
-
contents = jetpack.read(path) || '';
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
let hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
|
|
1036
|
-
|
|
1037
|
-
if (!hasTemplate) {
|
|
1038
|
-
log(chalk.red(`Could not find rules template. Please edit ${name} file and add`), chalk.red(`{{backend-manager}}`), chalk.red(`to it.`));
|
|
1039
|
-
return resolve()
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
let matchesVersion = contents.match(self.default.rulesVersionRegex);
|
|
1043
|
-
if (!matchesVersion) {
|
|
1044
|
-
// console.log('replace wih', self.default.databaseRulesCore);
|
|
1045
|
-
contents = contents.replace(bem_allRulesBackupRegex, self.default.databaseRulesCore)
|
|
1046
|
-
contents = contents.replace(bem_allRulesRegex, self.default.databaseRulesCore)
|
|
1047
|
-
jetpack.write(path, contents)
|
|
1048
|
-
log(chalk.yellow(`Writing core rules to ${name} file...`));
|
|
1049
|
-
}
|
|
1050
|
-
resolve();
|
|
1051
|
-
});
|
|
1052
|
-
};
|
|
1053
|
-
|
|
1054
|
-
// function fix_realtimeRulesFile(self) {
|
|
1055
|
-
// return new Promise(function(resolve, reject) {
|
|
1056
|
-
// const name = 'database.rules.json';
|
|
1057
|
-
// let filePath = `${self.firebaseProjectPath}/${name}`;
|
|
1058
|
-
// let exists = jetpack.exists(filePath);
|
|
1059
|
-
// let contents = jetpack.read(filePath) || '';
|
|
1060
|
-
//
|
|
1061
|
-
// if (!exists) {
|
|
1062
|
-
// log(chalk.yellow(`Writing new ${name} file...`));
|
|
1063
|
-
// jetpack.write(filePath, jetpack.read(path.resolve(`${__dirname}/../../templates/${name}`)))
|
|
1064
|
-
// contents = jetpack.read(filePath) || '';
|
|
1065
|
-
// }
|
|
1066
|
-
//
|
|
1067
|
-
// resolve();
|
|
1068
|
-
// });
|
|
1069
|
-
// };
|
|
1070
|
-
|
|
1071
|
-
function fix_firestoreIndexesFile(self) {
|
|
1072
|
-
return new Promise(async function(resolve, reject) {
|
|
1073
|
-
const name = 'firestore.indexes.json';
|
|
1074
|
-
let filePath = `${self.firebaseProjectPath}/${name}`;
|
|
1075
|
-
let exists = jetpack.exists(filePath);
|
|
1076
|
-
|
|
1077
|
-
if (!exists) {
|
|
1078
|
-
log(chalk.yellow(`Writing new ${name} file...`));
|
|
1079
|
-
await cmd_indexesGet(self, name, false);
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
resolve();
|
|
1083
|
-
});
|
|
1084
|
-
};
|
|
1085
|
-
|
|
1086
|
-
function fix_storageRulesFile(self) {
|
|
1087
|
-
return new Promise(function(resolve, reject) {
|
|
1088
|
-
const name = 'storage.rules';
|
|
1089
|
-
let filePath = `${self.firebaseProjectPath}/${name}`;
|
|
1090
|
-
let exists = jetpack.exists(filePath);
|
|
1091
|
-
let contents = jetpack.read(filePath) || '';
|
|
1092
|
-
|
|
1093
|
-
if (!exists) {
|
|
1094
|
-
log(chalk.yellow(`Writing new ${name} file...`));
|
|
1095
|
-
jetpack.write(filePath, jetpack.read(path.resolve(`${__dirname}/../../templates/${name}`)))
|
|
1096
|
-
contents = jetpack.read(filePath) || '';
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
resolve();
|
|
1100
|
-
});
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
function fix_remoteconfigTemplateFile(self) {
|
|
1104
|
-
return new Promise(function(resolve, reject) {
|
|
1105
|
-
const name = 'remoteconfig.template.json'
|
|
1106
|
-
let filePath = `${self.firebaseProjectPath}/${name}`;
|
|
1107
|
-
let exists = jetpack.exists(filePath);
|
|
1108
|
-
let contents = jetpack.read(filePath) || '';
|
|
1109
|
-
|
|
1110
|
-
if (!exists) {
|
|
1111
|
-
log(chalk.yellow(`Writing new ${name} file...`));
|
|
1112
|
-
jetpack.write(filePath, jetpack.read(path.resolve(`${__dirname}/../../templates/${name}`)))
|
|
1113
|
-
contents = jetpack.read(filePath) || '';
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
resolve();
|
|
1117
|
-
});
|
|
1118
|
-
};
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
// Hosting
|
|
1122
|
-
function fix_firebaseHostingFolder(self) {
|
|
1123
|
-
return new Promise(function(resolve, reject) {
|
|
1124
|
-
_.set(self.firebaseJSON, 'hosting.public', 'public')
|
|
1125
|
-
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
1126
|
-
resolve();
|
|
1127
|
-
});
|
|
1128
|
-
};
|
|
1129
|
-
|
|
1130
|
-
function fix_firebaseHostingAuth(self) {
|
|
1131
|
-
return new Promise(async function(resolve, reject) {
|
|
1132
|
-
const url = `${self.bemConfigJSON.brand.url}/server/auth/handler`;
|
|
1133
|
-
|
|
1134
|
-
await fetch(url, {
|
|
1135
|
-
method: 'get',
|
|
1136
|
-
cacheBreaker: true,
|
|
1137
|
-
tries: 2,
|
|
1138
|
-
response: 'text',
|
|
1139
|
-
})
|
|
1140
|
-
.then(async (text) => {
|
|
1141
|
-
// Save to file
|
|
1142
|
-
jetpack.write(`${self.firebaseProjectPath}/public/auth/handler/index.html`, text);
|
|
1143
|
-
|
|
1144
|
-
resolve(true)
|
|
1145
|
-
})
|
|
1146
|
-
.catch(async (e) => {
|
|
1147
|
-
log(chalk.red(`Failed to fetch auth handler. Please ensure it is live @ ${url}.`));
|
|
1148
|
-
|
|
1149
|
-
reject(false)
|
|
1150
|
-
})
|
|
1151
|
-
});
|
|
1152
|
-
};
|
|
1153
|
-
|
|
1154
|
-
function getPkgVersion(package) {
|
|
1155
|
-
return new Promise(async function(resolve, reject) {
|
|
1156
|
-
let npm = new Npm();
|
|
1157
|
-
npm.repo(package)
|
|
1158
|
-
.package()
|
|
1159
|
-
.then(function(pkg) {
|
|
1160
|
-
resolve(pkg.version);
|
|
1161
|
-
}, function(err) {
|
|
1162
|
-
resolve('0.0.0');
|
|
1163
|
-
});
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
async function cmd_indexesGet(self, filePath, log) {
|
|
1168
|
-
return new Promise(function(resolve, reject) {
|
|
1169
|
-
const finalPath = `${self.firebaseProjectPath}/${filePath || 'firestore.indexes.json'}`;
|
|
1170
|
-
let existingIndexes;
|
|
1171
|
-
try {
|
|
1172
|
-
existingIndexes = require(`${self.firebaseProjectPath}/firestore.indexes.json`)
|
|
1173
|
-
} catch (e) {
|
|
1174
|
-
if (log !== false) {
|
|
1175
|
-
console.error('Failed to read existing local indexes', e);
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
let cmd = exec(`firebase firestore:indexes > ${finalPath}`, function (error, stdout, stderr) {
|
|
1179
|
-
if (error) {
|
|
1180
|
-
if (log !== false) {
|
|
1181
|
-
console.error(error);
|
|
1182
|
-
}
|
|
1183
|
-
reject(error);
|
|
1184
|
-
} else {
|
|
1185
|
-
const newIndexes = require(finalPath);
|
|
1186
|
-
if (log !== false) {
|
|
1187
|
-
console.log(chalk.green(`Saving indexes to: ${finalPath}`));
|
|
1188
|
-
console.log(stdout);
|
|
1189
|
-
|
|
1190
|
-
const equal = (_.isEqual(newIndexes, existingIndexes));
|
|
1191
|
-
|
|
1192
|
-
if (!equal) {
|
|
1193
|
-
console.log(chalk.red(`The live and local index files did not match and have been overwritten by the ${chalk.bold('live indexes')}`));
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
}
|
|
1197
|
-
resolve(newIndexes);
|
|
1198
|
-
}
|
|
1199
|
-
});
|
|
1200
|
-
});
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
async function execute(command, cwd) {
|
|
1204
|
-
cwd = cwd || process.cwd();
|
|
1205
|
-
return new Promise(function(resolve, reject) {
|
|
1206
|
-
exec(command, { cwd: cwd, stdio: 'inherit' })
|
|
1207
|
-
.on('error', function(err) {
|
|
1208
|
-
reject(err);
|
|
1209
|
-
})
|
|
1210
|
-
.on('close', function (one, two, three) {
|
|
1211
|
-
console.log('===', one, two, three);
|
|
1212
|
-
resolve()
|
|
1213
|
-
})
|
|
1214
|
-
// fork(command, function (error, stdout, stderr) {
|
|
1215
|
-
// if (error) {
|
|
1216
|
-
// reject(error);
|
|
1217
|
-
// } else {
|
|
1218
|
-
// resolve(stdout);
|
|
1219
|
-
// }
|
|
1220
|
-
// });
|
|
1221
|
-
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
// async function execute(command, args, cwd) {
|
|
1226
|
-
// cwd = cwd || process.cwd();
|
|
1227
|
-
// return new Promise(function(resolve, reject) {
|
|
1228
|
-
// spawn(command, args, { cwd: cwd, stdio: 'inherit' })
|
|
1229
|
-
// .on('error', function(err) {
|
|
1230
|
-
// reject(err);
|
|
1231
|
-
// })
|
|
1232
|
-
// .on('close', function (one, two, three) {
|
|
1233
|
-
// console.log('===', one, two, three);
|
|
1234
|
-
// resolve()
|
|
1235
|
-
// })
|
|
1236
|
-
// // fork(command, function (error, stdout, stderr) {
|
|
1237
|
-
// // if (error) {
|
|
1238
|
-
// // reject(error);
|
|
1239
|
-
// // } else {
|
|
1240
|
-
// // resolve(stdout);
|
|
1241
|
-
// // }
|
|
1242
|
-
// // });
|
|
1243
|
-
|
|
1244
|
-
// });
|
|
1245
|
-
// }
|
|
1246
|
-
|
|
1247
|
-
async function cmd_configGet(self, filePath) {
|
|
1248
|
-
return new Promise(function(resolve, reject) {
|
|
1249
|
-
const finalPath = `${self.firebaseProjectPath}/${filePath || 'functions/.runtimeconfig.json'}`;
|
|
1250
|
-
|
|
1251
|
-
const max = 10;
|
|
1252
|
-
let retries = 0;
|
|
1253
|
-
|
|
1254
|
-
function _attempt() {
|
|
1255
|
-
exec(`firebase functions:config:get > ${finalPath}`, function (error, stdout, stderr) {
|
|
1256
|
-
if (error) {
|
|
1257
|
-
console.error(chalk.red(`Failed to get config: ${error}`));
|
|
1258
|
-
|
|
1259
|
-
// If retries are exhausted, reject
|
|
1260
|
-
if (retries++ > max) {
|
|
1261
|
-
return reject(error);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
// Retry
|
|
1265
|
-
const delay = 2500 * retries
|
|
1266
|
-
console.error(chalk.yellow(`Retrying config:get ${retries}/${max} in ${delay}ms...`));
|
|
1267
|
-
setTimeout(_attempt, delay);
|
|
1268
|
-
} else {
|
|
1269
|
-
console.log(chalk.green(`Saving config to: ${finalPath}`));
|
|
1270
|
-
console.log(stdout);
|
|
1271
|
-
resolve(require(finalPath));
|
|
1272
|
-
}
|
|
1273
|
-
});
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
// Start the attempts
|
|
1277
|
-
_attempt();
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
async function cmd_configSet(self, newPath, newValue) {
|
|
1282
|
-
return new Promise(async function(resolve, reject) {
|
|
1283
|
-
// console.log(self.options);
|
|
1284
|
-
// console.log(self.argv);
|
|
1285
|
-
newPath = newPath || await inquirer.prompt([
|
|
1286
|
-
{
|
|
1287
|
-
type: 'input',
|
|
1288
|
-
name: 'path',
|
|
1289
|
-
default: 'service.key'
|
|
1290
|
-
}
|
|
1291
|
-
]).then(answers => answers.path);
|
|
1292
|
-
|
|
1293
|
-
let object = null;
|
|
1294
|
-
|
|
1295
|
-
try {
|
|
1296
|
-
object = JSON5.parse(newPath);
|
|
1297
|
-
} catch (e) {
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
const isObject = object && typeof object === 'object';
|
|
1301
|
-
|
|
1302
|
-
// If it's a string, ensure some things
|
|
1303
|
-
if (!isObject) {
|
|
1304
|
-
// Validate path
|
|
1305
|
-
if (!newPath.includes('.')) {
|
|
1306
|
-
console.log(chalk.red(`Path needs 2 parts (one.two): ${newPath}`));
|
|
1307
|
-
return reject();
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
// Make sure it's only letters, numbers, periods, and underscores
|
|
1311
|
-
if (newPath.match(/[^a-zA-Z0-9._]/)) {
|
|
1312
|
-
console.log(chalk.red(`Path contains invalid characters: ${newPath}`));
|
|
1313
|
-
return reject();
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
try {
|
|
1318
|
-
if (isObject) {
|
|
1319
|
-
const keyify = (obj, prefix = '') =>
|
|
1320
|
-
Object.keys(obj).reduce((res, el) => {
|
|
1321
|
-
if( Array.isArray(obj[el]) ) {
|
|
1322
|
-
return res;
|
|
1323
|
-
} else if( typeof obj[el] === 'object' && obj[el] !== null ) {
|
|
1324
|
-
return [...res, ...keyify(obj[el], prefix + el + '.')];
|
|
1325
|
-
}
|
|
1326
|
-
return [...res, prefix + el];
|
|
1327
|
-
}, []);
|
|
1328
|
-
const pathArray = keyify(object);
|
|
1329
|
-
for (var i = 0; i < pathArray.length; i++) {
|
|
1330
|
-
const pathName = pathArray[i];
|
|
1331
|
-
const pathValue = _.get(object, pathName);
|
|
1332
|
-
// console.log(chalk.blue(`Setting object: ${chalk.bold(pathName)} = ${chalk.bold(pathValue)}`));
|
|
1333
|
-
console.log(chalk.blue(`Setting object: ${chalk.bold(pathName)}`));
|
|
1334
|
-
await cmd_configSet(self, pathName, pathValue)
|
|
1335
|
-
.catch(e => {
|
|
1336
|
-
log(chalk.red(`Failed to save object path: ${e}`));
|
|
1337
|
-
})
|
|
1338
|
-
}
|
|
1339
|
-
return resolve();
|
|
1340
|
-
}
|
|
1341
|
-
} catch (e) {
|
|
1342
|
-
log(chalk.red(`Failed to save object: ${e}`));
|
|
1343
|
-
return reject(e)
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
newValue = newValue || await inquirer.prompt([
|
|
1347
|
-
{
|
|
1348
|
-
type: 'input',
|
|
1349
|
-
name: 'value',
|
|
1350
|
-
default: '123-abc'
|
|
1351
|
-
}
|
|
1352
|
-
]).then(answers => answers.value)
|
|
1353
|
-
|
|
1354
|
-
let isInvalid = false;
|
|
1355
|
-
if (newPath !== newPath.toLowerCase()) {
|
|
1356
|
-
isInvalid = true;
|
|
1357
|
-
newPath = newPath.replace(/([A-Z])/g, '_$1').trim().toLowerCase();
|
|
1358
|
-
}
|
|
1359
|
-
log(chalk.yellow(`Saving to ${chalk.bold(newPath)}...`));
|
|
1360
|
-
let cmd = exec(`firebase functions:config:set ${newPath}="${newValue}"`, function (error, stdout, stderr) {
|
|
1361
|
-
if (error) {
|
|
1362
|
-
log(chalk.red(`Failed to save ${chalk.bold(newPath)}: ${error}`));
|
|
1363
|
-
reject(error);
|
|
1364
|
-
} else {
|
|
1365
|
-
console.log(stdout);
|
|
1366
|
-
if (isInvalid) {
|
|
1367
|
-
log(chalk.red(`!!! Your path contained an invalid uppercase character`));
|
|
1368
|
-
log(chalk.red(`!!! It was set to: ${chalk.bold(newPath)}`));
|
|
1369
|
-
} else {
|
|
1370
|
-
log(chalk.green(`Successfully saved to ${chalk.bold(newPath)}`));
|
|
1371
|
-
}
|
|
1372
|
-
resolve();
|
|
1373
|
-
}
|
|
1374
|
-
});
|
|
1375
|
-
});
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
async function cmd_configUnset(self) {
|
|
1379
|
-
return new Promise(async function(resolve, reject) {
|
|
1380
|
-
// console.log(self.options);
|
|
1381
|
-
// console.log(self.argv);
|
|
1382
|
-
await inquirer
|
|
1383
|
-
.prompt([
|
|
1384
|
-
/* Pass your questions in here */
|
|
1385
|
-
{
|
|
1386
|
-
type: 'input',
|
|
1387
|
-
name: 'path',
|
|
1388
|
-
default: 'service.key'
|
|
1389
|
-
}
|
|
1390
|
-
])
|
|
1391
|
-
.then(answers => {
|
|
1392
|
-
// Use user feedback for... whatever!!
|
|
1393
|
-
// console.log('answer', answers);
|
|
1394
|
-
log(chalk.yellow(`Deleting ${chalk.bold(answers.path)}...`));
|
|
1395
|
-
let cmd = exec(`firebase functions:config:unset ${answers.path}`, function (error, stdout, stderr) {
|
|
1396
|
-
if (error) {
|
|
1397
|
-
log(chalk.red(`Failed to delete ${chalk.bold(answers.path)}: ${error}`));
|
|
1398
|
-
reject(error);
|
|
1399
|
-
} else {
|
|
1400
|
-
console.log(stdout);
|
|
1401
|
-
log(chalk.green(`Successfully deleted ${chalk.bold(answers.path)}`));
|
|
1402
|
-
resolve();
|
|
1403
|
-
}
|
|
1404
|
-
});
|
|
1405
|
-
});
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
async function cmd_iamImportExport(self) {
|
|
1410
|
-
return new Promise(function(resolve, reject) {
|
|
1411
|
-
const command = `
|
|
1412
|
-
gcloud projects add-iam-policy-binding {projectId} \
|
|
1413
|
-
--member serviceAccount:{projectId}@appspot.gserviceaccount.com \
|
|
1414
|
-
--role roles/datastore.importExportAdmin
|
|
1415
|
-
`
|
|
1416
|
-
.replace(/{projectId}/ig, self.projectName)
|
|
1417
|
-
|
|
1418
|
-
let cmd = exec(command, function (error, stdout, stderr) {
|
|
1419
|
-
if (error) {
|
|
1420
|
-
console.log(chalk.red(`Failed to run command`, error));
|
|
1421
|
-
reject(error);
|
|
1422
|
-
} else {
|
|
1423
|
-
// console.log(chalk.green(`Added permission`));
|
|
1424
|
-
resolve(stdout);
|
|
1425
|
-
}
|
|
1426
|
-
});
|
|
1427
|
-
});
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
async function cmd_setStorageLifecycle(self) {
|
|
1431
|
-
return new Promise(function(resolve, reject) {
|
|
1432
|
-
const command = `gsutil lifecycle set {config} gs://{bucket}`
|
|
1433
|
-
.replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-1-day.json`))
|
|
1434
|
-
.replace(/{bucket}/ig, `us.artifacts.${self.projectName}.appspot.com`)
|
|
1435
|
-
const command2 = `gsutil lifecycle set {config} gs://{bucket}`
|
|
1436
|
-
.replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-30-days.json`))
|
|
1437
|
-
.replace(/{bucket}/ig, `bm-backup-firestore-${self.projectName}`)
|
|
1438
|
-
|
|
1439
|
-
exec(command, function (error, stdout, stderr) {
|
|
1440
|
-
if (error) {
|
|
1441
|
-
console.log(chalk.red(`Failed to run command`, error));
|
|
1442
|
-
reject(error);
|
|
1443
|
-
} else {
|
|
1444
|
-
exec(command2, function (error, stdout, stderr) {
|
|
1445
|
-
if (error) {
|
|
1446
|
-
console.log(chalk.red(`Failed to run command`, error));
|
|
1447
|
-
reject(error);
|
|
1448
|
-
} else {
|
|
1449
|
-
// console.log(chalk.green(`Added lifecycle`));
|
|
1450
|
-
resolve(stdout);
|
|
1451
|
-
}
|
|
1452
|
-
})
|
|
1453
|
-
}
|
|
1454
|
-
});
|
|
1455
|
-
});
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
// HELPER
|
|
1459
|
-
|
|
1460
|
-
function initMocha() {
|
|
1461
|
-
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
function isLocal(name) {
|
|
1465
|
-
return name.indexOf('file:') > -1;
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
function installPkg(name, version, type) {
|
|
1469
|
-
let v;
|
|
1470
|
-
let t;
|
|
1471
|
-
if (name.indexOf('file:') > -1) {
|
|
1472
|
-
v = '';
|
|
1473
|
-
} else if (!version) {
|
|
1474
|
-
v = '@latest';
|
|
1475
|
-
} else {
|
|
1476
|
-
v = version;
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
if (!type) {
|
|
1480
|
-
t = ''
|
|
1481
|
-
} else if (type === 'dev' || type === '--save-dev') {
|
|
1482
|
-
t = ' --save-dev';
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
let latest = version ? '' : '@latest';
|
|
1486
|
-
return new Promise(function(resolve, reject) {
|
|
1487
|
-
let command = `npm i ${name}${v}${t}`;
|
|
1488
|
-
console.log('Running ', command);
|
|
1489
|
-
let cmd = exec(command, function (error, stdout, stderr) {
|
|
1490
|
-
if (error) {
|
|
1491
|
-
reject(error);
|
|
1492
|
-
} else {
|
|
1493
|
-
resolve();
|
|
1494
|
-
}
|
|
1495
|
-
});
|
|
1496
|
-
});
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
function uninstallPkg(name) {
|
|
1500
|
-
return new Promise(function(resolve, reject) {
|
|
1501
|
-
let command = `npm uninstall ${name}`;
|
|
1502
|
-
console.log('Running ', command);
|
|
1503
|
-
let cmd = exec(command, function (error, stdout, stderr) {
|
|
1504
|
-
if (error) {
|
|
1505
|
-
reject(error);
|
|
1506
|
-
} else {
|
|
1507
|
-
resolve();
|
|
1508
|
-
}
|
|
1509
|
-
});
|
|
1510
|
-
});
|
|
1511
|
-
}
|
|
1512
|
-
function loadJSON(path) {
|
|
1513
|
-
const contents = jetpack.read(path);
|
|
1514
|
-
if (!contents) {
|
|
1515
|
-
return {};
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
return JSON5.parse(contents);
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
function hasContent(object) {
|
|
1522
|
-
return Object.keys(object).length > 0;
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
function cleanOutput(data) {
|
|
1526
|
-
try {
|
|
1527
|
-
data = (data + '').replace(/\n$/, '')
|
|
1528
|
-
} catch (e) {
|
|
1529
|
-
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
// Return
|
|
1533
|
-
return data;
|
|
1534
|
-
}
|