UNPKG

3.3 kBPlain TextView Raw
1import { readdirSync, readFileSync } from 'fs';
2import { join, resolve, extname, basename } from 'path';
3import { satisfies } from 'semver';
4
5// eslint-disable-next-line
6const verbose = (...args: any[]) => process.env.VERBOSE ? console.log(...args) : undefined;
7
8type UnPromisify<T> = T extends Promise<infer U> ? U : T;
9type Patch = UnPromisify<ReturnType<typeof getAvailablePatches>>['availablePatches'][0];
10
11const { applyPatch } = require('patch-package/dist/applyPatches');
12
13export function applyPatchFile(baseDir: string, patch: Patch, reverse = false) {
14 return applyPatch({
15 patchFilePath: resolve(baseDir, patch.fileName),
16 patchDir: baseDir,
17 packageDetails: patch.details,
18 reverse,
19 });
20}
21
22export async function applyPatches(rootDirectory: string, reverse = false): Promise<void> {
23 const { availablePatches, baseDir } = await getAvailablePatches();
24
25 for (const patch of availablePatches) {
26 if (patch.details) {
27 const packageResolution = resolvePackage(rootDirectory, patch);
28
29 if (packageResolution) {
30 const isValidVersion = satisfies(packageResolution, patch.details.version);
31
32 if (isValidVersion) {
33 const result = applyPatchFile(baseDir, patch, reverse);
34
35 if (result) {
36 // eslint-disable-next-line
37 console.info(`[TypedDocumentNode] Patch for ${patch.details.name}@${packageResolution} has been ${reverse ? 'reversed' : 'applied'}!`);
38 } else {
39 // eslint-disable-next-line
40 console.warn(`[TypedDocumentNode] Something went wrong, unable to patch ${patch.details.name} (Patch: ${patch.details.version}, Installed: ${packageResolution})`);
41 }
42 } else {
43 // eslint-disable-next-line
44 verbose(`[TypedDocumentNode] Patch for ${patch.details.name} exists, but you have a version mismatch! (Supported: ${patch.details.version}, you have: ${packageResolution})`);
45 }
46 } else {
47 verbose(`[TypedDocumentNode] Skipping ${patch.fileName} patch, didn't find any package resolution!`)
48 }
49 } else {
50 verbose(`[TypedDocumentNode] Unable to extract package details for patch file ${patch.fileName}!`)
51 }
52 }
53}
54
55function resolvePackage(rootDirectory: string, patch: Patch): string | null {
56 try {
57 const packagePath = require.resolve(`${patch.details.name}/package.json`, { paths: [rootDirectory] });
58 const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
59
60 return packageJson.version || null;
61 } catch (e) {
62 return null;
63 }
64}
65
66export async function getAvailablePatches() {
67 const baseDir = join(__dirname, './patches/');
68 const files = readdirSync(baseDir).filter(d => extname(d) === '.patch');
69
70 return {
71 baseDir,
72 availablePatches: files.map(fileName => {
73 const cleanName = basename(fileName, extname(fileName));
74 const parts = cleanName.split('+');
75 const versionRange = parts.pop();
76 const name = parts.join('/');
77
78 return {
79 fileName,
80 details: {
81 // This structure and fields are required internally in `patch-package` code.
82 version: versionRange,
83 name,
84 pathSpecifier: name,
85 humanReadablePathSpecifier: name,
86 packageNames: [name],
87 },
88 };
89 })
90 };
91}
\No newline at end of file