UNPKG

6.88 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const path_1 = require("path");
4const minimatch = require("minimatch");
5class PlatformFSPlugin {
6 constructor({ platform, platforms, ignore }) {
7 this.platform = platform || "";
8 this.platforms = platforms || ["ios", "android"];
9 this.ignore = ignore || [];
10 }
11 apply(compiler) {
12 this.context = compiler.context;
13 compiler.inputFileSystem = mapFileSystem({
14 fs: compiler.inputFileSystem,
15 platform: this.platform,
16 platforms: this.platforms,
17 ignore: this.ignore,
18 context: this.context
19 });
20 }
21}
22exports.PlatformFSPlugin = PlatformFSPlugin;
23function mapFileSystem(args) {
24 let { fs, platform, platforms, ignore, context } = args;
25 ignore = args.ignore || [];
26 const minimatchFileFilters = ignore.map(pattern => {
27 const minimatchFilter = minimatch.filter(pattern);
28 return file => minimatchFilter(path_1.relative(context, file));
29 });
30 const isIgnored = file => minimatchFileFilters.some(filter => filter(file));
31 const alienPlatforms = platforms.filter(p => p !== platform);
32 const alienPlatformFilters = alienPlatforms
33 .map(platform => `.${platform}.`)
34 .map(contains => baseFileName => baseFileName.indexOf(contains) !== -1);
35 const isNotAlienPlatformFile = file => !alienPlatformFilters.some(filter => filter(path_1.basename(file)));
36 const currentPlatformExt = `.${platform}`;
37 const trimPlatformSuffix = file => {
38 const { dir, name, ext } = path_1.parse(file);
39 if (name.endsWith(currentPlatformExt)) {
40 return path_1.join(dir, name.substr(0, name.length - currentPlatformExt.length) + ext);
41 }
42 return file;
43 };
44 const isNotIgnored = file => !isIgnored(file);
45 const mappedFS = {
46 get _statStorage() { return fs._statStorage; },
47 get _readFileStorage() { return fs._readFileStorage; },
48 get _readdirStorage() { return fs._readdirStorage; }
49 };
50 ["readFile", "provide", "stat", "readJson", "readlink"].forEach(mapPath);
51 ["readdir"].forEach(filterResultingFiles);
52 function platformSpecificFile(file) {
53 const { dir, name, ext } = path_1.parse(file);
54 const platformFilePath = path_1.join(dir, `${name}.${platform}${ext}`);
55 return platformFilePath;
56 }
57 function listWithPlatformSpecificFiles(files) {
58 const mappedFiles = [];
59 files.forEach(file => {
60 mappedFiles.push(file);
61 mappedFiles.push(platformSpecificFile(file));
62 });
63 return mappedFiles;
64 }
65 /**
66 * Maps and filters the input files.
67 * Expects array with absolute paths.
68 * Returns array with absolute paths.
69 */
70 function filterIgnoredFilesAlienFilesAndMap(files) {
71 const mappedFiles = files
72 .filter(isNotIgnored)
73 .filter(isNotAlienPlatformFile)
74 .map(trimPlatformSuffix);
75 const uniqueMappedFiles = Array.from(new Set(mappedFiles));
76 return uniqueMappedFiles;
77 }
78 const platformSuffix = "." + platform + ".";
79 mappedFS.watch = function (files, dirs, missing, startTime, watchOptions, callback) {
80 const mappedFiles = listWithPlatformSpecificFiles(files);
81 const callbackCalled = function (err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps) {
82 const mappedFilesModified = filterIgnoredFilesAlienFilesAndMap(filesModified);
83 const mappedTimestamps = new Map();
84 for (const file in fileTimestamps) {
85 const timestamp = fileTimestamps[file];
86 mappedTimestamps.set(file, timestamp);
87 const platformSuffixIndex = file.lastIndexOf(platformSuffix);
88 if (platformSuffixIndex != -1) {
89 const mappedFile = file.substr(0, platformSuffixIndex) + file.substr(platformSuffixIndex + platformSuffix.length - 1);
90 if (!(mappedFile in fileTimestamps)) {
91 mappedTimestamps.set(mappedFile, timestamp);
92 }
93 }
94 }
95 callback.call(this, err, mappedFilesModified, contextModified, missingModified, mappedTimestamps, contextTimestamps);
96 };
97 fs.watch(mappedFiles, dirs, missing, startTime, watchOptions, callbackCalled);
98 };
99 /**
100 * For FS functions that get as first argument a file path,
101 * this will map it to a platform specific file if such file exists or fallback to the default.
102 * Also the last argument must be a function that handles results such as (err, files[]),
103 * it will invoke err for files that are ignored.
104 */
105 function mapPath(fName) {
106 const base = fs[fName];
107 mappedFS[fName] = function () {
108 const args = arguments;
109 const originalFilePath = args[0];
110 const callback = args[args.length - 1];
111 if (isIgnored(originalFilePath)) {
112 callback(new Error("File " + originalFilePath + " is ignored!"));
113 return;
114 }
115 const platformFilePath = platformSpecificFile(originalFilePath);
116 fs.stat(platformFilePath, (err, stat) => {
117 if (!err && stat && stat.isFile()) {
118 args[0] = platformFilePath;
119 }
120 base.apply(fs, args);
121 });
122 };
123 }
124 /**
125 * For FS functions that get as a last argument a function,
126 * that handles results such as (err, files[]),
127 * will filter and map the returned files[].
128 */
129 function filterResultingFiles(name) {
130 const base = fs[name];
131 mappedFS[name] = function () {
132 const dir = arguments[0];
133 const callback = arguments[arguments.length - 1];
134 if (isIgnored(dir)) {
135 // Return empty file list for filtered directories.
136 callback(null, []);
137 return;
138 }
139 arguments[arguments.length - 1] = function (err, files) {
140 if (err) {
141 callback(err);
142 }
143 else {
144 // Create absolute paths for "ignored" testing, map platforms, and return back the base name.
145 const absoluteFilePaths = files.map(file => path_1.join(dir, file));
146 const resultAbsolute = filterIgnoredFilesAlienFilesAndMap(absoluteFilePaths);
147 const resultFileNames = resultAbsolute.map(f => path_1.basename(f));
148 callback(null, resultFileNames);
149 }
150 };
151 base.apply(fs, arguments);
152 };
153 }
154 return mappedFS;
155}
156exports.mapFileSystem = mapFileSystem;
157//# sourceMappingURL=PlatformFSPlugin.js.map
\No newline at end of file