UNPKG

2.61 kBJavaScriptView Raw
1// @flow
2import type {FileSystem} from '@parcel/fs';
3import type {FilePath, File} from '@parcel/types';
4import type {Entry, ParcelOptions} from './types';
5import path from 'path';
6import {isGlob, glob} from '@parcel/utils';
7
8export type EntryResult = {|
9 entries: Array<Entry>,
10 files: Array<File>,
11|};
12
13export class EntryResolver {
14 fs: FileSystem;
15
16 constructor(options: ParcelOptions) {
17 this.fs = options.inputFS;
18 }
19
20 async resolveEntry(entry: FilePath): Promise<EntryResult> {
21 if (isGlob(entry)) {
22 let files = await glob(entry, this.fs, {
23 absolute: true,
24 onlyFiles: false,
25 });
26 let results = await Promise.all(files.map(f => this.resolveEntry(f)));
27 return results.reduce(
28 (p, res) => ({
29 entries: p.entries.concat(res.entries),
30 files: p.files.concat(res.files),
31 }),
32 {entries: [], files: []},
33 );
34 }
35
36 let stat;
37 try {
38 stat = await this.fs.stat(entry);
39 } catch (err) {
40 throw new Error(`Entry ${entry} does not exist`);
41 }
42
43 if (stat.isDirectory()) {
44 let pkg = await this.readPackage(entry);
45 if (pkg && typeof pkg.source === 'string') {
46 let source = path.join(path.dirname(pkg.filePath), pkg.source);
47 try {
48 stat = await this.fs.stat(source);
49 } catch (err) {
50 throw new Error(
51 `${pkg.source} in ${path.relative(
52 this.fs.cwd(),
53 pkg.filePath,
54 )}#source does not exist`,
55 );
56 }
57
58 if (!stat.isFile()) {
59 throw new Error(
60 `${pkg.source} in ${path.relative(
61 this.fs.cwd(),
62 pkg.filePath,
63 )}#source is not a file`,
64 );
65 }
66
67 return {
68 entries: [{filePath: source, packagePath: entry}],
69 files: [{filePath: pkg.filePath}],
70 };
71 }
72
73 throw new Error(`Could not find entry: ${entry}`);
74 } else if (stat.isFile()) {
75 return {
76 entries: [{filePath: entry}],
77 files: [],
78 };
79 }
80
81 throw new Error(`Unknown entry ${entry}`);
82 }
83
84 async readPackage(entry: FilePath) {
85 let content, pkg;
86 let pkgFile = path.join(entry, 'package.json');
87 try {
88 content = await this.fs.readFile(pkgFile, 'utf8');
89 } catch (err) {
90 return null;
91 }
92
93 try {
94 pkg = JSON.parse(content);
95 } catch (err) {
96 throw new Error(
97 `Error parsing ${path.relative(this.fs.cwd(), pkgFile)}: ${
98 err.message
99 }`,
100 );
101 }
102
103 pkg.filePath = pkgFile;
104 return pkg;
105 }
106}