backend-manager 3.2.131 → 3.2.133
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
|
@@ -49,8 +49,8 @@ let bem_allRulesBackupRegex = /({{\s*?backend-manager\s*?}})/sgm;
|
|
|
49
49
|
let MOCHA_PKG_SCRIPT = 'mocha ../test/ --recursive --timeout=10000';
|
|
50
50
|
let NPM_CLEAN_SCRIPT = 'rm -fr node_modules && rm -fr package-lock.json && npm cache clean --force && npm install && npm rb';
|
|
51
51
|
let NOFIX_TEXT = chalk.red(`There is no automatic fix for this check.`);
|
|
52
|
-
let runtimeconfigTemplate =
|
|
53
|
-
let bemConfigTemplate =
|
|
52
|
+
let runtimeconfigTemplate = loadJSON(`${__dirname}/../../templates/runtimeconfig.json`);
|
|
53
|
+
let bemConfigTemplate = loadJSON(`${__dirname}/../../templates/backend-manager-config.json`);
|
|
54
54
|
|
|
55
55
|
function Main() {
|
|
56
56
|
}
|
|
@@ -236,35 +236,32 @@ Main.prototype.getRulesFile = function () {
|
|
|
236
236
|
Main.prototype.setup = async function () {
|
|
237
237
|
const self = this;
|
|
238
238
|
let cwd = jetpack.cwd();
|
|
239
|
+
|
|
239
240
|
log(chalk.green(`\n---- RUNNING SETUP v${self.default.version} ----`));
|
|
240
|
-
self.package = jetpack.read(`${self.firebaseProjectPath}/functions/package.json`) || '{}';
|
|
241
|
-
self.firebaseJSON = jetpack.read(`${self.firebaseProjectPath}/firebase.json`) || '{}';
|
|
242
|
-
self.firebaseRC = jetpack.read(`${self.firebaseProjectPath}/.firebaserc`) || '{}';
|
|
243
|
-
self.runtimeConfigJSON = jetpack.read(`${self.firebaseProjectPath}/functions/.runtimeconfig.json`) || '{}';
|
|
244
|
-
self.remoteconfigJSON = jetpack.read(`${self.firebaseProjectPath}/remoteconfig.template.json`) || '{}';
|
|
245
|
-
self.projectPackage = jetpack.read(`${self.firebaseProjectPath}/package.json`) || '{}';
|
|
246
|
-
self.bemConfigJSON = jetpack.read(`${self.firebaseProjectPath}/functions/backend-manager-config.json`) || '{}';
|
|
247
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`);
|
|
248
250
|
self.gitignore = jetpack.read(`${self.firebaseProjectPath}/functions/.gitignore`) || '';
|
|
249
|
-
|
|
251
|
+
|
|
252
|
+
// Check if package exists
|
|
253
|
+
if (!hasContent(self.package)) {
|
|
250
254
|
log(chalk.red(`Missing functions/package.json :(`));
|
|
251
255
|
return;
|
|
252
256
|
}
|
|
253
|
-
|
|
257
|
+
|
|
258
|
+
// Check if we're running from the functions folder
|
|
254
259
|
if (!cwd.endsWith('functions') && !cwd.endsWith('functions/')) {
|
|
255
260
|
log(chalk.red(`Please run ${chalk.bold('npx bm setup')} from the ${chalk.bold('functions')} folder. Run ${chalk.bold('cd functions')}.`));
|
|
256
261
|
return;
|
|
257
262
|
}
|
|
258
263
|
|
|
259
|
-
|
|
260
|
-
self.firebaseJSON = JSON.parse(self.firebaseJSON);
|
|
261
|
-
self.firebaseRC = JSON.parse(self.firebaseRC);
|
|
262
|
-
self.runtimeConfigJSON = JSON.parse(self.runtimeConfigJSON);
|
|
263
|
-
self.remoteconfigJSON = JSON.parse(self.remoteconfigJSON);
|
|
264
|
-
self.projectPackage = JSON.parse(self.projectPackage);
|
|
265
|
-
|
|
266
|
-
self.remoteconfigJSONExists = Object.keys(self.remoteconfigJSON).length > 0;
|
|
267
|
-
|
|
264
|
+
// Load the rules files
|
|
268
265
|
self.getRulesFile();
|
|
269
266
|
|
|
270
267
|
self.default.rulesVersionRegex = new RegExp(`///---version=${self.default.version}---///`)
|
|
@@ -275,8 +272,7 @@ Main.prototype.setup = async function () {
|
|
|
275
272
|
self.projectName = self.firebaseRC.projects.default;
|
|
276
273
|
self.projectUrl = `https://console.firebase.google.com/project/${self.projectName}`;
|
|
277
274
|
|
|
278
|
-
self.bemApiURL = `https://us-central1-${
|
|
279
|
-
// const prepareStatsURL = `https://us-central1-${_.get(self.firebaseRC, 'projects.default')}.cloudfunctions.net/bm_api?authenticationToken=undefined`;
|
|
275
|
+
self.bemApiURL = `https://us-central1-${self?.firebaseRC?.projects?.default}.cloudfunctions.net/bm_api?authenticationToken=${self?.runtimeConfigJSON?.backend_manager?.key}`;
|
|
280
276
|
|
|
281
277
|
// Log
|
|
282
278
|
log(`ID: `, chalk.bold(`${self.projectName}`));
|
|
@@ -403,63 +399,51 @@ Main.prototype.setup = async function () {
|
|
|
403
399
|
}, fix_distScript);
|
|
404
400
|
|
|
405
401
|
await self.test('using proper .runtimeconfig', async function () {
|
|
406
|
-
|
|
407
|
-
let ogPaths = getObjectPaths(runtimeconfigTemplate).split('\n');
|
|
402
|
+
// Set pass
|
|
408
403
|
let pass = true;
|
|
409
404
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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;
|
|
416
412
|
}
|
|
417
|
-
}
|
|
413
|
+
});
|
|
418
414
|
|
|
419
|
-
|
|
415
|
+
// Return result
|
|
416
|
+
return pass;
|
|
420
417
|
}, fix_runtimeConfig);
|
|
421
418
|
|
|
422
|
-
// await self.test('using proper env', async function () {
|
|
423
|
-
// let runtimeconfig = JSON.parse(jetpack.read(`${self.firebaseProjectPath}/functions/.runtimeconfig.json`) || '{}');
|
|
424
|
-
// let ogPaths = getObjectPaths(runtimeconfigTemplate).split('\n');
|
|
425
|
-
// let pass = true;
|
|
426
|
-
|
|
427
|
-
// for (var i = 0, l = ogPaths.length; i < l; i++) {
|
|
428
|
-
// let item = ogPaths[i];
|
|
429
|
-
// if (!item) {continue}
|
|
430
|
-
// pass = _.get(runtimeconfig, item, undefined);
|
|
431
|
-
// if (typeof pass === 'undefined') {
|
|
432
|
-
// break;
|
|
433
|
-
// }
|
|
434
|
-
// }
|
|
435
|
-
|
|
436
|
-
// return !!pass;
|
|
437
|
-
// }, fix_runtimeConfig);
|
|
438
|
-
|
|
439
419
|
await self.test('using proper backend-manager-config.json', async function () {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
let ogPaths = getObjectPaths(bemConfigTemplate).split('\n');
|
|
420
|
+
// Set pass
|
|
443
421
|
let pass = true;
|
|
444
422
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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;
|
|
451
430
|
}
|
|
452
|
-
}
|
|
431
|
+
});
|
|
453
432
|
|
|
454
|
-
|
|
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) {
|
|
455
440
|
console.error(chalk.red('Mismatch between project name and firebaseConfig.projectId in backend-manager-config.json'));
|
|
456
441
|
return false;
|
|
457
442
|
}
|
|
458
443
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}, fix_bemConfig);
|
|
444
|
+
// Return pass
|
|
445
|
+
return true;
|
|
446
|
+
}, NOFIX);
|
|
463
447
|
|
|
464
448
|
await self.test('has service-account.json', function () {
|
|
465
449
|
let exists = jetpack.exists(`${self.firebaseProjectPath}/functions/service-account.json`);
|
|
@@ -478,35 +462,28 @@ Main.prototype.setup = async function () {
|
|
|
478
462
|
}
|
|
479
463
|
}, fix_gitignore);
|
|
480
464
|
|
|
481
|
-
|
|
482
465
|
// Check firebase.json fields
|
|
483
|
-
await self.test('firestore rules in JSON',
|
|
484
|
-
|
|
485
|
-
return (firestore.rules === 'firestore.rules')
|
|
466
|
+
await self.test('firestore rules in JSON', () => {
|
|
467
|
+
return self.firebaseJSON?.firestore?.rules === 'firestore.rules'
|
|
486
468
|
}, fix_firestoreRules);
|
|
487
469
|
|
|
488
|
-
await self.test('firestore indexes in JSON',
|
|
489
|
-
|
|
490
|
-
return (firestore.indexes === 'firestore.indexes.json')
|
|
470
|
+
await self.test('firestore indexes in JSON', () => {
|
|
471
|
+
return self.firebaseJSON?.firestore?.indexes === 'firestore.indexes.json';
|
|
491
472
|
}, fix_firestoreIndexes);
|
|
492
473
|
|
|
493
|
-
await self.test('realtime rules in JSON',
|
|
494
|
-
|
|
495
|
-
return (database.rules === 'database.rules.json')
|
|
474
|
+
await self.test('realtime rules in JSON', () => {
|
|
475
|
+
return self.firebaseJSON?.database?.rules === 'database.rules.json';
|
|
496
476
|
}, fix_realtimeRules);
|
|
497
477
|
|
|
498
|
-
await self.test('storage rules in JSON',
|
|
499
|
-
|
|
500
|
-
return (storage.rules === 'storage.rules')
|
|
478
|
+
await self.test('storage rules in JSON', () => {
|
|
479
|
+
return self.firebaseJSON?.storage?.rules === 'storage.rules';
|
|
501
480
|
}, fix_storageRules);
|
|
502
481
|
|
|
503
|
-
await self.test('remoteconfig template in JSON',
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (self.remoteconfigJSONExists) {
|
|
507
|
-
return (remoteconfig.template === 'remoteconfig.template.json')
|
|
482
|
+
await self.test('remoteconfig template in JSON', () => {
|
|
483
|
+
if (hasContent(self.remoteconfigJSON)) {
|
|
484
|
+
return self.firebaseJSON?.remoteconfig?.template === 'remoteconfig.template.json';
|
|
508
485
|
} else {
|
|
509
|
-
return
|
|
486
|
+
return self.firebaseJSON?.remoteconfig?.template === '';
|
|
510
487
|
}
|
|
511
488
|
}, fix_remoteconfigTemplate);
|
|
512
489
|
|
|
@@ -676,29 +653,6 @@ Main.prototype.setup = async function () {
|
|
|
676
653
|
|
|
677
654
|
};
|
|
678
655
|
|
|
679
|
-
// https://stackoverflow.com/questions/41802259/javascript-deep-check-objects-have-same-keys
|
|
680
|
-
// function objectsHaveSameKeys(...objects) {
|
|
681
|
-
// let objectPaths = getObjectPaths()
|
|
682
|
-
// // const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
|
|
683
|
-
// // const union = new Set(allKeys);
|
|
684
|
-
// // return objects.every(object => union.size === Object.keys(object).length);
|
|
685
|
-
//
|
|
686
|
-
// // const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
|
|
687
|
-
// console.log('allKeys', allKeys);
|
|
688
|
-
// return false
|
|
689
|
-
// }
|
|
690
|
-
|
|
691
|
-
function getObjectPaths(object, parent) {
|
|
692
|
-
let keys = Object.keys(object);
|
|
693
|
-
let composite = '';
|
|
694
|
-
parent = parent || '';
|
|
695
|
-
for (var i = 0, l = keys.length; i < l; i++) {
|
|
696
|
-
let item = object[keys[i]];
|
|
697
|
-
composite += typeof item === 'object' ? getObjectPaths(item, keys[i]) : `${parent}.${keys[i]}\n`;
|
|
698
|
-
}
|
|
699
|
-
return composite;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
656
|
Main.prototype.test = async function(name, fn, fix, args) {
|
|
703
657
|
const self = this;
|
|
704
658
|
let status;
|
|
@@ -749,47 +703,50 @@ function bemPackageVersionWarning(package, current, latest) {
|
|
|
749
703
|
|
|
750
704
|
async function fix_runtimeConfig(self) {
|
|
751
705
|
return new Promise(function(resolve, reject) {
|
|
706
|
+
// Log
|
|
752
707
|
log(NOFIX_TEXT);
|
|
753
708
|
log(chalk.red(`You need to run ${chalk.bold(`npx bm config:set`)} for each of these keys:`));
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
log(chalk.red(`${item} (${has})`));
|
|
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}`));
|
|
762
716
|
} else {
|
|
763
|
-
log(chalk.red
|
|
717
|
+
log(chalk.red(`${key} (${userValue})`));
|
|
764
718
|
}
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
//
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
// Reject
|
|
768
722
|
reject();
|
|
769
723
|
});
|
|
770
724
|
};
|
|
771
725
|
|
|
772
726
|
async function fix_bemConfig(self) {
|
|
773
727
|
return new Promise(function(resolve, reject) {
|
|
728
|
+
// Log
|
|
774
729
|
log(NOFIX_TEXT);
|
|
775
730
|
log(chalk.red(`You need to open backend-manager-config.json and set each of these keys:`));
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
if (
|
|
779
|
-
jetpack.write(`${self.firebaseProjectPath}/functions/backend-manager-config.json`, bemConfigTemplate)
|
|
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`, {})
|
|
780
736
|
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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}`));
|
|
787
744
|
} else {
|
|
788
|
-
log(chalk.red
|
|
745
|
+
log(chalk.red(`${key} (${userValue})`));
|
|
789
746
|
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
//
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
// Reject
|
|
793
750
|
reject();
|
|
794
751
|
});
|
|
795
752
|
};
|
|
@@ -974,7 +931,8 @@ function fix_storageRules(self) {
|
|
|
974
931
|
|
|
975
932
|
function fix_remoteconfigTemplate(self) {
|
|
976
933
|
return new Promise(function(resolve, reject) {
|
|
977
|
-
|
|
934
|
+
|
|
935
|
+
_.set(self.firebaseJSON, 'remoteconfig.template', hasContent(self.remoteconfigJSON) ? 'remoteconfig.template.json' : '')
|
|
978
936
|
jetpack.write(`${self.firebaseProjectPath}/firebase.json`, JSON.stringify(self.firebaseJSON, null, 2));
|
|
979
937
|
resolve();
|
|
980
938
|
});
|
|
@@ -1538,26 +1496,26 @@ function uninstallPkg(name) {
|
|
|
1538
1496
|
});
|
|
1539
1497
|
});
|
|
1540
1498
|
}
|
|
1499
|
+
function loadJSON(path) {
|
|
1500
|
+
const contents = jetpack.read(path);
|
|
1501
|
+
if (!contents) {
|
|
1502
|
+
return {};
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
return JSON5.parse(contents);
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
function hasContent(object) {
|
|
1509
|
+
return Object.keys(object).length > 0;
|
|
1510
|
+
}
|
|
1541
1511
|
|
|
1542
1512
|
function cleanOutput(data) {
|
|
1543
1513
|
try {
|
|
1544
|
-
// data = (data + '').replace('\n', '')
|
|
1545
1514
|
data = (data + '').replace(/\n$/, '')
|
|
1546
1515
|
} catch (e) {
|
|
1547
1516
|
|
|
1548
1517
|
}
|
|
1518
|
+
|
|
1519
|
+
// Return
|
|
1549
1520
|
return data;
|
|
1550
|
-
// try {
|
|
1551
|
-
// data = data.replace(/\n/, '');
|
|
1552
|
-
// } catch (e) {
|
|
1553
|
-
//
|
|
1554
|
-
// } finally {
|
|
1555
|
-
//
|
|
1556
|
-
// }
|
|
1557
|
-
// return data;
|
|
1558
|
-
// // if (typeof data !== 'string') {
|
|
1559
|
-
// // return data;
|
|
1560
|
-
// // } else {
|
|
1561
|
-
// // return data.replace(/\n/, '');
|
|
1562
|
-
// // }
|
|
1563
1521
|
}
|
|
@@ -299,8 +299,11 @@ Module.prototype.uploadPost = function (content) {
|
|
|
299
299
|
// Log
|
|
300
300
|
assistant.log(`uploadPost(): Existing`, existing);
|
|
301
301
|
|
|
302
|
-
//
|
|
303
|
-
if (
|
|
302
|
+
// Quit if error and it's not a 404
|
|
303
|
+
if (
|
|
304
|
+
existing instanceof Error
|
|
305
|
+
&& existing?.status !== 404
|
|
306
|
+
) {
|
|
304
307
|
return reject(existing);
|
|
305
308
|
}
|
|
306
309
|
|
|
@@ -309,7 +312,7 @@ Module.prototype.uploadPost = function (content) {
|
|
|
309
312
|
owner: owner,
|
|
310
313
|
repo: repo,
|
|
311
314
|
path: filename,
|
|
312
|
-
sha: existing?.data?.sha,
|
|
315
|
+
sha: existing?.data?.sha || undefined,
|
|
313
316
|
message: `📦 admin:create-post:upload-post ${filename}`,
|
|
314
317
|
content: Buffer.from(content).toString('base64'),
|
|
315
318
|
})
|
|
@@ -429,6 +429,9 @@ BackendAssistant.prototype.errorify = function (e, options) {
|
|
|
429
429
|
sendable = `${sendable} (${newError.tag})`;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
// Clear log prefix before sending
|
|
433
|
+
self.clearLogPrefix();
|
|
434
|
+
|
|
432
435
|
// Log
|
|
433
436
|
if (options.log) {
|
|
434
437
|
self.log(`Sending response (${options.code}):`, JSON.stringify(sendable));
|
|
@@ -492,12 +495,16 @@ BackendAssistant.prototype.respond = function(response, options) {
|
|
|
492
495
|
// Send response
|
|
493
496
|
res.status(options.code);
|
|
494
497
|
|
|
498
|
+
// Log function
|
|
495
499
|
function _log(text) {
|
|
496
500
|
if (options.log) {
|
|
497
501
|
self.log(`${text} (${options.code}):`, JSON.stringify(response));
|
|
498
502
|
}
|
|
499
503
|
}
|
|
500
504
|
|
|
505
|
+
// Clear log prefix before sending
|
|
506
|
+
self.clearLogPrefix();
|
|
507
|
+
|
|
501
508
|
// Redirect
|
|
502
509
|
const isRedirect = isBetween(options.code, 300, 399);
|
|
503
510
|
if (isRedirect) {
|
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
},
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
2
|
+
app: {
|
|
3
|
+
id: 'my-app',
|
|
4
|
+
},
|
|
5
|
+
brand: {
|
|
6
|
+
name: 'My Brand',
|
|
7
|
+
url: 'https://example.com',
|
|
8
|
+
email: 'support@example.com',
|
|
9
|
+
wordmark: 'https://example.com/wordmark.png',
|
|
10
|
+
brandmark: 'https://example.com/wordmark.png',
|
|
11
|
+
combomark: 'https://example.com/combomark.png',
|
|
12
|
+
},
|
|
13
|
+
mailchimp: {
|
|
14
|
+
list_id: '36774bf825',
|
|
15
|
+
},
|
|
16
|
+
github: {
|
|
17
|
+
user: 'username',
|
|
18
|
+
repo_website: 'https://github.com/username/backend-manager',
|
|
19
|
+
},
|
|
20
|
+
sentry: {
|
|
21
|
+
dsn: 'https://d965557418748jd749d837asf00552f@o777489.ingest.sentry.io/8789941',
|
|
22
|
+
},
|
|
23
|
+
google_analytics: {
|
|
24
|
+
id: 'UA-123456789-1',
|
|
25
|
+
secret: 'ABCx1234567890ABCDEFGH',
|
|
26
|
+
},
|
|
27
|
+
firebaseConfig: {
|
|
28
|
+
apiKey: '123-456',
|
|
29
|
+
authDomain: 'PROJECT-ID.firebaseapp.com',
|
|
30
|
+
projectId: 'PROJECT-ID',
|
|
31
|
+
storageBucket: 'PROJECT-ID.appspot.com',
|
|
32
|
+
messagingSenderId: '123',
|
|
33
|
+
appId: '1:123:web:456',
|
|
34
|
+
measurementId: 'G-0123456789',
|
|
35
|
+
},
|
|
36
|
+
ghostii: {
|
|
37
|
+
articles: 1,
|
|
38
|
+
sources: [
|
|
39
|
+
'$app',
|
|
40
|
+
]
|
|
41
|
+
},
|
|
36
42
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
mailchimp: {
|
|
3
|
+
key: 'da69e4758adb4839201bcda8565782d4-us16',
|
|
4
4
|
},
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
backend_manager: {
|
|
6
|
+
key: 'api_254448f1-4738-8884-88f7-8884jdd9cc96',
|
|
7
|
+
namespace: 'e69776e2-9d14-4486-88d0-aa84426d0882',
|
|
8
|
+
},
|
|
9
|
+
github: {
|
|
10
|
+
key: '7f7f80bafc6689895jf86937fg444f6fd5',
|
|
8
11
|
},
|
|
9
|
-
"github": {
|
|
10
|
-
"key": "7f7f80bafc6689895jf86937fg444f6fd5"
|
|
11
|
-
}
|
|
12
12
|
}
|