-
Notifications
You must be signed in to change notification settings - Fork 61
/
validate-included-files.ts
92 lines (88 loc) · 3.46 KB
/
validate-included-files.ts
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
import path from "path";
import chalk from "chalk";
import * as fs from "fs-extra";
import packlist from "npm-packlist";
import { Package } from "./package";
import { FatalError } from "./errors";
export async function validateIncludedFiles(pkg: Package) {
try {
const rootDistDirectoryTestFilepath = path.join(
pkg.directory,
"dist",
"preconstruct-test-file"
);
const hasNoEntrypointAtRootOfPackage = pkg.entrypoints.every(
(entrypoint) => entrypoint.directory !== pkg.directory
);
await Promise.all(
pkg.entrypoints
.map(async (entrypoint) => {
let filename = path.join(
entrypoint.directory,
"dist",
"preconstruct-test-file"
);
return fs.outputFile(filename, "test content");
})
.concat(
hasNoEntrypointAtRootOfPackage
? fs.outputFile(rootDistDirectoryTestFilepath, "test content")
: []
)
);
let packedFilesArr = await packlist({ path: pkg.directory });
// Ensure consistent path separators. Without this, there's a mismatch between this result and the path it
// checks on Windows. This value will have a forward slash (dist/preconstruct-test-file), whereas the value
// of distFilePath below will have a backslash (dist\preconstruct-test-file). Obviously these two won't match,
// so the distfile check will fail.
let result = new Set(packedFilesArr.map((p) => path.normalize(p)));
// check that we're including the package.json and main file
// TODO: add Flow and TS check and if they're ignored, don't write them
let messages: string[] = [];
pkg.entrypoints.forEach((entrypoint) => {
let pkgJsonPath = path.relative(
pkg.directory,
path.resolve(entrypoint.directory, "package.json")
);
let distFilePath = path.relative(
pkg.directory,
path.resolve(entrypoint.directory, "dist", "preconstruct-test-file")
);
let entrypointName = path.relative(pkg.directory, entrypoint.directory);
if (!result.has(pkgJsonPath)) {
messages.push(
`the entrypoint ${chalk.cyan(
entrypointName
)} isn't included in the published files for this package, please add it to the files field in the package's package.json`
);
} else if (!result.has(distFilePath)) {
messages.push(
`the dist directory ${
entrypointName === ""
? ""
: `for entrypoint ${chalk.cyan(entrypointName)} `
}isn't included in the published files for this package, please add it to the files field in the package's package.json`
);
}
});
if (
hasNoEntrypointAtRootOfPackage &&
!result.has(path.relative(pkg.directory, rootDistDirectoryTestFilepath))
) {
messages.push(
"the dist directory in the root of the package isn't included in the published files for this package, please add it to the files field in the package's package.json.\nthough this package does not have an entrypoint at the root of the package, preconstruct will write common chunks to the root dist directory so it must be included."
);
}
if (messages.length) {
throw new FatalError(messages.join("\n"), pkg.name);
}
} finally {
await Promise.all(
pkg.entrypoints.map((entrypoint) =>
fs.remove(
path.join(entrypoint.directory, "dist", "preconstruct-test-file")
)
)
);
}
}