-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgobble-unpackage.js
130 lines (95 loc) · 4.21 KB
/
gobble-unpackage.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 🦃namespace unpackage
// Filters files from NPM/SPM/CommonJS modules so only the needed ones (e.g. 'main' in package.json) are used
var sander = require('sander');
var path = require('path');
var _ = require('underscore');
var SourceNode = require( 'source-map' ).SourceNode;
getSourceNode = require( './get-source-node' );
var sourceMapRegExp = new RegExp(/(?:\/\/#|\/\/@|\/\*#)\s*sourceMappingURL=(.*?)\s*(?:\*\/\s*)?$/);
function unpackage ( inputdir, outputdir, options/*, callback */) {
function linkFile(filename) {
// console.log(filename);
if (filename === undefined) { return true; }
if (filename instanceof Array) {
// console.log('Linking fileS:', filename);
return sander.Promise.all(filename.map(linkFile));
}
return sander.stat(inputdir, filename).then(function(stats) {
// If there is a reference to that directory, link the whole thing.
if (stats.isDirectory()) {
return sander.symlink(inputdir, filename).to(outputdir, filename);
}
// If the library *file* refers to a sourcemap, excise it (sourcemaps are
// not tracked files). If not, it's enough to link it.
return sander.readFile(inputdir, filename).then(function(contents){;
contents = contents.toString();
var match = contents.match(sourceMapRegExp);
if (match) {
// 🦃option stripSourcemaps: Boolean = false; Whether to strip any existing sourcemaps. Also strips the sourcemaps reference and creates inline sourcemaps pointing to the original location of the files.
return getSourceNode(inputdir, filename, options.stripSourcemaps).then(function (node) {
var generated = node.toStringWithSourceMap();
var sourcemap = JSON.parse(generated.map.toString());
// console.log(sourcemap);
// console.log(sourcemap.sources);
// Replace paths to make them relative to the CWD
// console.log(inputdir, outputdir, filename);
var srcDir = path.dirname(filename);
var cwd = process.cwd();
sourcemap.sources.forEach(function(sourcepath, i){
var newSourcepath = path.resolve(path.join(inputdir, srcDir), sourcepath);
sourcemap.sources[i] = path.relative(cwd, newSourcepath);
});
// console.log(sourcemap.sources);
var encodedMap = 'data:application/json;charset=utf-8;base64,' + new Buffer(JSON.stringify(sourcemap)).toString('base64');
var sourceMapLocation;
if (filename.match(/\.css$/)) {
sourceMapLocation = '\n\n/*# sourceMappingURL=' + encodedMap + ' */\n';
} else {
sourceMapLocation = '\n\n//# sourceMappingURL=' + encodedMap + '\n'
}
sander.writeFile( outputdir, filename, generated.code + sourceMapLocation );
});
} else {
// console.log('No sourcemap at ', filename);
// console.log('Linking file: ', inputdir, filename, outputdir);
return sander.symlink(inputdir, filename).to(outputdir, filename);
}
});
});
}
var packageJsonFilename = path.join(inputdir, '/package.json');
var pending = [];
if (sander.existsSync(packageJsonFilename) || options) {
if (!options) { options = {}; }
var packageJson = JSON.parse(sander.readFileSync(packageJsonFilename));
options = _.extend(packageJson, options);
// console.log(options);
}
if (options) {
if ('style' in options) {
// Any npm-css compliant package will have this.
pending.push(linkFile(options.style));
} else if ('less' in options) {
// Some stuff (e.g. bootstrap) use this
pending.push(linkFile(options.less));
}
if ('main' in options) {
// This is the most common way of defining stuff
pending.push(linkFile(options.main));
} else if ('spm' in options && 'main' in options.spm) {
// See spmjs.io. Some stuff (e.g. jQuery, es6-promise) uses this.
pending.push(linkFile(options.spm.main));
}
if ('browser' in options && (typeof options.browser === 'string')) {
// Becoming more popular as bower dies out, see
// https://github.com/defunctzombie/package-browser-field-spec
pending.push(linkFile(options.browser));
}
} else {
// If no package.json file is present, just passthru all the files
pending.push(sander.readdir(inputdir).then(linkFile));
}
// console.log('Pending ops:', pending);
return sander.Promise.all(pending);
}
module.exports = unpackage;