/
prepareFunctionsUpload.js
111 lines (97 loc) · 3.62 KB
/
prepareFunctionsUpload.js
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
'use strict';
var _ = require('lodash');
var archiver = require('archiver');
var chalk = require('chalk');
var filesize = require('filesize');
var fs = require('fs-extra');
var fstreamIgnore = require('fstream-ignore');
var path = require('path');
var RSVP = require('rsvp');
var tmp = require('tmp');
var FirebaseError = require('./error');
var functionsConfig = require('./functionsConfig');
var getProjectId = require('./getProjectId');
var utils = require('./utils');
var parseTriggers = require('./parseTriggers');
var CONFIG_DEST_FILE = '.runtimeconfig.json';
var _prepareSource = function(context, options) {
var tmpdir = tmp.dirSync({prefix: 'fbfn_'});
var configDest = path.join(tmpdir.name, CONFIG_DEST_FILE);
try {
fs.copySync(options.config.path(options.config.get('functions.source')), tmpdir.name);
} catch (err) {
throw new FirebaseError('Problem preparing functions directory for upload.', {exit: 1});
}
return functionsConfig.materializeAll(getProjectId(options)).then(function(output) {
var firebaseConfig = _.get(context, 'firebaseConfig');
_.set(output, 'firebase', firebaseConfig);
fs.ensureFileSync(configDest);
fs.writeFileSync(configDest, JSON.stringify(output, null, 2));
return tmpdir;
});
};
var _packageSource = function(options, tmpdir) {
var sourceDir = tmpdir.name;
return new RSVP.Promise(function(resolve, reject) {
var tmpFile = tmp.fileSync({prefix: 'firebase-functions-', postfix: '.zip'});
var fileStream = fs.createWriteStream(tmpFile.name, {
flags: 'w',
defaultEncoding: 'binary'
});
var archive = archiver('zip');
fileStream.on('finish', function() {
utils.logBullet(chalk.cyan.bold('functions:') + ' packaged ' + chalk.bold(options.config.get('functions.source')) + ' (' + filesize(archive.pointer()) + ') for uploading');
resolve({
file: tmpFile.name,
stream: fs.createReadStream(tmpFile.name),
size: archive.pointer()
});
});
archive.on('error', function(err) {
reject(new FirebaseError('Could not read source directory. Remove links and shortcuts and try again.', {
original: err,
exit: 1
}));
});
archive.pipe(fileStream);
var reader = fstreamIgnore({
path: sourceDir,
type: 'Directory',
follow: true
});
// we must ignore this or weird things happen if
// you're in the public dir when you deploy
reader.addIgnoreRules(['firebase-debug.log']);
reader.addIgnoreRules(options.config.get(['functions', '.ignore'], ['**/.*', '**/node_modules/**']));
// We want to always upload the env file regardless of ignore rules
reader.addIgnoreRules(['!' + CONFIG_DEST_FILE]);
reader.on('child', function(file) {
if (file.type !== 'Directory') {
archive.append(file, { name: path.relative(sourceDir, file.path), mode: file.props.mode });
}
});
reader.on('error', function(err) {
reject(new FirebaseError('Could not read source directory. Remove links and shortcuts and try again.', {
original: err,
exit: 1
}));
});
reader.on('end', function() {
archive.finalize();
fs.removeSync(tmpdir.name);
});
});
};
module.exports = function(context, options) {
var tmpdir;
return _prepareSource(context, options).then(function(result) {
tmpdir = result;
return parseTriggers(getProjectId(options), tmpdir.name);
}).then(function(triggers) {
options.config.set('functions.triggers', triggers);
if (options.config.get('functions.triggers').length === 0) {
return RSVP.resolve(null);
}
return _packageSource(options, tmpdir);
});
};