-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.npm-postprepare.cjs
147 lines (134 loc) · 3.4 KB
/
.npm-postprepare.cjs
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
'use strict';
const fsPromises = require('node:fs/promises');
const path = require('node:path');
const PACKAGE_PATH = path.resolve('./package.json');
const README_PATH = path.resolve('./README.md');
const KEYS_ORDER = [
'name',
'version',
'description',
'keywords',
'license',
'author',
'repository',
'bugs',
'homepage',
'engines',
'browserslist',
'scripts',
'main',
'files',
'exports',
// ...any unspecified keys will be added here
'dependencies',
'devDependencies',
'peerDependencies',
];
/**
* Sort an object by key
* Keys that are not specified in `order` will be placed at the end of the object
* If no `order` given the order will default to alphabetical sorting
* @param {object} object - the object to be sorted
* @param {array} [order] - an array of keys
* @returns {{}}
*/
function sortObjectByKey(object, order) {
return Object.keys(object)
.sort(
order
? (accumulator, key) => {
if (!order.includes(accumulator)) {
return 1;
}
if (!order.includes(key)) {
return -1;
}
return order.indexOf(accumulator) - order.indexOf(key);
}
: undefined,
)
.reduce((accumulator, key) => {
return { ...accumulator, [key]: object[key] };
}, {});
}
/**
* Update the pkg field values
* @param {object} pkg
* @returns {{}}
*/
function updatePkg(pkg) {
// Format shorthand urls
if (pkg.repository && pkg.repository.url) {
pkg.repository = new URL(pkg.repository.url).pathname
.replace('/', 'github:')
.replace('.git', '');
}
if (pkg.bugs && pkg.bugs.url) {
pkg.bugs = pkg.bugs.url;
}
// Sort sub-keys alphabetically
Object.keys(pkg).forEach((key) => {
// Sort only objects, not arrays
if (pkg[key].constructor === Object) {
pkg[key] = sortObjectByKey(pkg[key]);
}
});
// Sort pkg keys
const { dependencies, devDependencies, peerDependencies, ...sortedPkg } =
sortObjectByKey(pkg, KEYS_ORDER);
return {
...sortedPkg,
dependencies,
devDependencies,
peerDependencies,
};
}
/**
* Update the README.md contents
* @param {string} description
* @param {string} name
* @param {string} readme
* @returns {string}
*/
function updateReadme(description, name, readme) {
const [, ...remainingSections] = readme.split(/(\n^#)/m);
return [
// Main title
`# ${name}`,
'',
// First paragraph
description,
remainingSections.join(''),
].join('\n');
}
/**
* Log file changes
* @param {string} filename
*/
function logFileUpdate(filename) {
// eslint-disable-next-line no-console
return console.log(`.npm-postprepare.cjs - ${filename} updated`);
}
(async function () {
try {
const pkg = await fsPromises.readFile(PACKAGE_PATH, 'utf8');
const pkgUpdated = updatePkg(JSON.parse(pkg));
const pkgUpdatedString = `${JSON.stringify(pkgUpdated, null, 2)}\n`;
if (pkgUpdatedString !== pkg) {
await fsPromises.writeFile(PACKAGE_PATH, pkgUpdatedString);
logFileUpdate('package.json');
}
const readme = await fsPromises.readFile(README_PATH, 'utf8');
const readmeUpdated = updateReadme(
pkgUpdated.description,
pkgUpdated.name,
readme,
);
if (readmeUpdated !== readme) {
await fsPromises.writeFile(README_PATH, readmeUpdated);
logFileUpdate('readme.md');
}
} catch (error) {
console.error(error);
}
})();