mirror of
https://github.com/zhigang1992/firebase-tools.git
synced 2026-05-25 10:22:40 +08:00
107 lines
2.9 KiB
JavaScript
107 lines
2.9 KiB
JavaScript
'use strict';
|
|
|
|
var cjson = require('cjson');
|
|
var FirebaseError = require('./error');
|
|
var _ = require('lodash');
|
|
var resolveProjectPath = require('./resolveProjectPath');
|
|
var path = require('path');
|
|
var fs = require('fs');
|
|
var loadCJSON = require('./loadCJSON');
|
|
var parseBoltRules = require('./parseBoltRules');
|
|
var detectProjectRoot = require('./detectProjectRoot');
|
|
|
|
var Config = function(src, options) {
|
|
this.options = options || {};
|
|
|
|
this._src = src;
|
|
this.data = {};
|
|
this.defaults = {};
|
|
|
|
if (this._src.firebase) {
|
|
this.defaults.project = this._src.firebase;
|
|
}
|
|
|
|
Config.TARGETS.forEach(function(target) {
|
|
if (this._src[target]) {
|
|
this.data[target] = this._materialize(target);
|
|
}
|
|
}, this);
|
|
|
|
// use 'public' as signal for legacy hosting since it's a required key
|
|
if (!this.data.hosting && this._src.public) {
|
|
this.data.hosting = {};
|
|
Config.LEGACY_HOSTING_KEYS.forEach(function(key) {
|
|
if (this._src[key]) {
|
|
this.data.hosting[key] = this._src[key];
|
|
}
|
|
}, this);
|
|
}
|
|
};
|
|
|
|
Config.FILENAME = 'firebase.json';
|
|
Config.TARGETS = ['hosting', 'rules'];
|
|
Config.LEGACY_HOSTING_KEYS = ['public', 'rewrites', 'redirects', 'headers', 'ignore'];
|
|
|
|
Config.prototype._materialize = function(target) {
|
|
if (_.isString(this._src[target])) {
|
|
return this._parseFile(target, this._src[target]);
|
|
} else if (_.isObject(this._src[target])) {
|
|
return this._src[target];
|
|
}
|
|
|
|
throw new FirebaseError('Parse Error: "' + target + '" must be object or import path', {exit: 1});
|
|
};
|
|
|
|
Config.prototype._parseFile = function(target, filePath) {
|
|
var fullPath = resolveProjectPath(this.options.cwd, filePath);
|
|
var ext = path.extname(filePath);
|
|
if (!fs.existsSync(fullPath)) {
|
|
throw new FirebaseError('Parse Error: Imported file ' + filePath + ' does not exist', {exit: 1});
|
|
}
|
|
|
|
switch (ext) {
|
|
case '.json':
|
|
var data = loadCJSON(fullPath);
|
|
// if e.g. rules.json has {"rules": {}} use that
|
|
if (_.size(data) === 1 && data[target]) {
|
|
data = data[target];
|
|
}
|
|
return data;
|
|
/* istanbul ignore-next */
|
|
case '.bolt':
|
|
return parseBoltRules(fullPath);
|
|
default:
|
|
throw new FirebaseError('Parse Error: ' + filePath + ' is not of a supported config file type', {exit: 1});
|
|
}
|
|
};
|
|
|
|
Config.prototype.get = function(key, fallback) {
|
|
return _.get(this.data, key, fallback);
|
|
};
|
|
|
|
Config.prototype.has = function(key) {
|
|
return _.has(this.data, key);
|
|
};
|
|
|
|
Config.load = function(options, allowMissing) {
|
|
var pd = detectProjectRoot(options.cwd);
|
|
if (pd) {
|
|
try {
|
|
var data = cjson.load(path.join(pd, Config.FILENAME));
|
|
return new Config(data, options);
|
|
} catch (e) {
|
|
throw new FirebaseError('There was an error loading firebase.json:\n\n' + e.message, {
|
|
exit: 1
|
|
});
|
|
}
|
|
}
|
|
|
|
if (allowMissing) {
|
|
return null;
|
|
}
|
|
|
|
throw new FirebaseError('Not in a Firebase app directory (could not locate firebase.json)', {exit: 1});
|
|
};
|
|
|
|
module.exports = Config;
|