|
|
@@ -4,35 +4,64 @@ const util = require('util');
|
|
|
const readFile = util.promisify(fs.readFile);
|
|
|
const writeFile = util.promisify(fs.writeFile);
|
|
|
|
|
|
-// sed -i '' 's|https://registry.npm.taobao.org|https://registry.yarnpkg.com|g' yarn.lock
|
|
|
-
|
|
|
+const base = {
|
|
|
+ parse(url) {
|
|
|
+ const parts = url.slice(this.prefix.length).split('/');
|
|
|
+ let scope;
|
|
|
+ if (parts[0].startsWith('@')) scope = parts.shift();
|
|
|
+ const name = parts.shift();
|
|
|
+ const suffix = parts.pop();
|
|
|
+ return { scope, name, suffix };
|
|
|
+ },
|
|
|
+ build({ scope, name, suffix }) {
|
|
|
+ return this.prefix + [scope, name, '-', suffix].filter(Boolean).join('/');
|
|
|
+ },
|
|
|
+};
|
|
|
const targets = {
|
|
|
- taobao: 'http://registry.npm.taobao.org/',
|
|
|
- yarn: 'https://registry.yarnpkg.com/',
|
|
|
- npm: 'http://registry.npmjs.org/',
|
|
|
+ taobao: Object.assign({}, base, {
|
|
|
+ prefix: 'http://registry.npm.taobao.org/',
|
|
|
+ build({ scope, name, suffix }) {
|
|
|
+ return this.prefix + [scope, name, 'download', scope, suffix].filter(Boolean).join('/');
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ yarn: Object.assign({}, base, {
|
|
|
+ prefix: 'https://registry.yarnpkg.com/',
|
|
|
+ }),
|
|
|
+ npm: Object.assign({}, base, {
|
|
|
+ prefix: 'http://registry.npmjs.org/',
|
|
|
+ }),
|
|
|
};
|
|
|
|
|
|
-function string2re(str, flag) {
|
|
|
- return new RegExp(str.replace(/([./])/g, '\\$1'), flag);
|
|
|
+function parseResolved(resolved) {
|
|
|
+ let result;
|
|
|
+ Object.entries(targets)
|
|
|
+ .some(([key, value]) => {
|
|
|
+ if (resolved.startsWith(value.prefix)) {
|
|
|
+ result = value.parse(resolved);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!result) throw new Error(`Unknown resolved value: ${resolved}`);
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+function getProcessor(targetName) {
|
|
|
+ const target = targets[targetName];
|
|
|
+ return line => {
|
|
|
+ const matches = line.match(/(\s+resolved\s+)"(.*)"/);
|
|
|
+ if (!matches) return line;
|
|
|
+ const parsed = parseResolved(matches[2]);
|
|
|
+ return `${matches[1]}"${target.build(parsed)}"`;
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
async function transformLock(name) {
|
|
|
const disallowChange = name.startsWith('=');
|
|
|
const targetName = disallowChange ? name.slice(1) : name;
|
|
|
- const prefix = targets[targetName];
|
|
|
- if (!prefix) {
|
|
|
- console.error('Unknown target:', targetName);
|
|
|
- process.exit(1);
|
|
|
- return;
|
|
|
- }
|
|
|
- const transformers = Object.entries(targets)
|
|
|
- .filter(([key]) => key !== targetName)
|
|
|
- .map(([_, value]) => string2re(value, 'g'));
|
|
|
const originalContent = await readFile('yarn.lock', 'utf8');
|
|
|
- let content = originalContent;
|
|
|
- transformers.forEach(transformer => {
|
|
|
- content = content.replace(transformer, prefix);
|
|
|
- });
|
|
|
+ const content = originalContent.split('\n')
|
|
|
+ .map(getProcessor(targetName))
|
|
|
+ .join('\n');
|
|
|
if (originalContent !== content) {
|
|
|
await writeFile('yarn.lock', content, 'utf8');
|
|
|
console.error('yarn.lock is updated.');
|