Skip to content

Commit b6714d3

Browse files
author
Daniel Del Core
committed
refactors the experimental module-loader
1 parent d3efd00 commit b6714d3

File tree

7 files changed

+134
-97
lines changed

7 files changed

+134
-97
lines changed

.changeset/wise-turtles-rescue.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@hypermod/fetcher': minor
3+
'@hypermod/cli': minor
4+
---
5+
6+
Refactors the module loader in order to support custom npm registries + auth keys.

packages/cli/src/list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { fetchPackages } from './utils/fetch-package';
55
import { getHypermodPackageName } from './utils/package-names';
66

77
export default async function list(packages: string[]) {
8-
const packageManager = new PluginManager();
8+
const packageManager = new PluginManager() as any;
99
const configs = [];
1010

1111
for (const packageName of packages) {

packages/cli/src/main.ts

Lines changed: 11 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,21 @@ import semver from 'semver';
33
import chalk from 'chalk';
44
import findUp from 'find-up';
55
import inquirer from 'inquirer';
6-
import fs from 'fs-extra';
76
import { PluginManager, PluginManagerOptions } from 'live-plugin-manager';
8-
import { installPackage } from '@antfu/install-pkg';
97

108
import * as core from '@hypermod/core';
11-
import { fetchConfigAtPath } from '@hypermod/fetcher';
9+
import {
10+
type ModuleLoader as MdlLoader,
11+
fetchConfigAtPath,
12+
} from '@hypermod/fetcher';
1213

1314
import { InvalidUserInputError } from './errors';
1415
import { fetchPackages } from './utils/fetch-package';
1516
import { mergeConfigs } from './utils/merge-configs';
1617
import { fetchConfigsForWorkspaces, getPackageJson } from './utils/file-system';
18+
import ModuleLoader from './utils/module-loader';
1719
import { getConfigPrompt, getMultiConfigPrompt } from './prompt';
1820

19-
const ExperimentalModuleLoader = () => {
20-
const getInfo = (packageName: string) => {
21-
const entryPath = require.resolve(packageName);
22-
const location = entryPath.split(packageName)[0] + packageName;
23-
const pkgJsonRaw = fs.readFileSync(
24-
path.join(location, 'package.json'),
25-
'utf8',
26-
);
27-
const pkgJson = JSON.parse(pkgJsonRaw);
28-
29-
return {
30-
location,
31-
entryPath,
32-
pkgJson,
33-
};
34-
};
35-
36-
const install = async (packageName: string) => {
37-
await installPackage(packageName, {
38-
cwd: __dirname,
39-
packageManager: 'npm',
40-
additionalArgs: ['--force'],
41-
});
42-
43-
const { pkgJson } = getInfo(packageName);
44-
45-
// Install whitelisted devDependencies
46-
if (pkgJson?.hypermod?.dependencies) {
47-
await Promise.all(
48-
pkgJson.hypermod.dependencies.map((dep: string) => {
49-
const version = pkgJson.devDependencies[dep];
50-
if (!version) return;
51-
return installPackage(`${dep}@${version}`, {
52-
cwd: __dirname,
53-
packageManager: 'npm',
54-
additionalArgs: ['--force'],
55-
});
56-
}),
57-
);
58-
}
59-
};
60-
61-
return {
62-
install,
63-
getInfo,
64-
require: (packageName: string) => require(packageName),
65-
};
66-
};
67-
6821
export default async function main(
6922
paths: string[],
7023
flags: Partial<core.Flags>,
@@ -91,9 +44,12 @@ export default async function main(
9144
};
9245
}
9346

94-
const packageManager = flags.experimentalLoader
95-
? ExperimentalModuleLoader()
96-
: new PluginManager(pluginManagerConfig);
47+
const packageManager: MdlLoader = flags.experimentalLoader
48+
? ModuleLoader({
49+
authToken: flags.registryToken,
50+
npmRegistryUrl: flags.registry,
51+
})
52+
: (new PluginManager(pluginManagerConfig) as unknown as MdlLoader);
9753

9854
let transforms: string[] = [];
9955

@@ -235,7 +191,6 @@ export default async function main(
235191

236192
const { community, remote } = await fetchPackages(
237193
pkgName,
238-
// @ts-expect-error Experimental loader
239194
packageManager,
240195
);
241196

packages/cli/src/utils/fetch-package.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import ora from 'ora';
22
import chalk from 'chalk';
3-
import { PluginManager } from 'live-plugin-manager';
43

54
import {
65
fetchPackage,
76
fetchRemotePackage,
87
ConfigMeta,
8+
type ModuleLoader,
99
} from '@hypermod/fetcher';
1010
import { isValidConfig } from '@hypermod/validator';
1111

1212
import { getHypermodPackageName } from './package-names';
1313

1414
export async function fetchPackages(
1515
packageName: string,
16-
packageManager: PluginManager,
16+
packageManager: ModuleLoader,
1717
) {
1818
const hypermodPackageName = getHypermodPackageName(packageName);
1919
let hypermodPackage: ConfigMeta | undefined;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import path from 'path';
2+
import fs from 'fs-extra';
3+
import { installPackage } from '@antfu/install-pkg';
4+
5+
import { ModuleLoader } from '@hypermod/fetcher';
6+
7+
const ModuleLoader = (config: {
8+
npmRegistryUrl?: string;
9+
authToken?: string;
10+
}): ModuleLoader => {
11+
const getInfo = (packageName: string) => {
12+
const entryPath = require.resolve(packageName);
13+
const location = entryPath.split(packageName)[0] + packageName;
14+
const pkgJsonRaw = fs.readFileSync(
15+
path.join(location, 'package.json'),
16+
'utf8',
17+
);
18+
const pkgJson = JSON.parse(pkgJsonRaw);
19+
20+
return {
21+
location,
22+
entryPath,
23+
pkgJson,
24+
};
25+
};
26+
27+
const install = async (packageName: string) => {
28+
await installPackage(packageName, {
29+
cwd: __dirname,
30+
packageManager: 'npm',
31+
additionalArgs: [
32+
'--force',
33+
// --registry=https://your-custom-registry-url/ --//your-custom-registry-url/:_authToken=YOUR_AUTH_TOKEN
34+
config.npmRegistryUrl ? `--registry=${config.npmRegistryUrl}` : '',
35+
config.authToken
36+
? `--${config.npmRegistryUrl}/:_authToken=${config.authToken}`
37+
: '',
38+
],
39+
});
40+
41+
const { pkgJson } = getInfo(packageName);
42+
43+
// Install whitelisted devDependencies
44+
if (pkgJson?.hypermod?.dependencies) {
45+
await Promise.all(
46+
pkgJson.hypermod.dependencies.map((dep: string) => {
47+
const version = pkgJson.devDependencies[dep];
48+
if (!version) return;
49+
return installPackage(`${dep}@${version}`, {
50+
cwd: __dirname,
51+
packageManager: 'npm',
52+
additionalArgs: ['--force'],
53+
});
54+
}),
55+
);
56+
}
57+
};
58+
59+
return {
60+
install,
61+
getInfo,
62+
require: (packageName: string) => require(packageName),
63+
};
64+
};
65+
66+
export default ModuleLoader;

packages/fetcher/src/index.spec.ts

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ jest.mock('globby');
33
import fs from 'fs';
44
import path from 'path';
55
import globby from 'globby';
6-
import { PluginManager } from 'live-plugin-manager';
76

8-
import { fetchConfig, fetchPackage, fetchRemotePackage } from '.';
7+
import {
8+
fetchConfig,
9+
fetchPackage,
10+
fetchRemotePackage,
11+
type ModuleLoader,
12+
} from '.';
913

1014
const mockBasePath = path.join(__dirname, 'path', 'to');
1115

@@ -109,28 +113,23 @@ describe('fetcher', () => {
109113
require: jest.fn().mockReturnValue(mockConfig),
110114
};
111115

112-
const configMeta = await fetchPackage(
113-
'fake-package',
114-
mockPackageManager as unknown as PluginManager,
115-
);
116+
const configMeta = await fetchPackage('fake-package', mockPackageManager);
116117

117118
expect(configMeta!.config).toEqual(mockConfig);
118119
expect(configMeta!.filePath).toEqual(mockFilePath);
119120
});
120121

121122
it('should throw if fetching fails', async () => {
122-
const mockPackageManager = {
123+
const mockPackageManager: ModuleLoader = {
123124
install: jest.fn().mockRejectedValue('Import error'),
124125
require: jest.fn().mockReturnValue(mockConfig),
126+
getInfo: jest.fn(),
125127
};
126128

127129
expect.assertions(1);
128130

129131
await expect(
130-
fetchPackage(
131-
'fake-package',
132-
mockPackageManager as unknown as PluginManager,
133-
),
132+
fetchPackage('fake-package', mockPackageManager),
134133
).rejects.toEqual('Import error');
135134
});
136135
});
@@ -150,7 +149,7 @@ describe('fetcher', () => {
150149

151150
const configMeta = await fetchRemotePackage(
152151
'fake-package',
153-
mockPackageManager as unknown as PluginManager,
152+
mockPackageManager,
154153
);
155154

156155
expect(configMeta!.config).toEqual(mockConfig);
@@ -160,17 +159,16 @@ describe('fetcher', () => {
160159
});
161160

162161
it('should throw if fetching fails', async () => {
163-
const mockPackageManager = {
162+
const mockPackageManager: ModuleLoader = {
164163
install: jest.fn().mockRejectedValue('Import error'),
164+
getInfo: jest.fn(),
165+
require: jest.fn(),
165166
};
166167

167168
expect.assertions(1);
168169

169170
await expect(
170-
fetchRemotePackage(
171-
'fake-package',
172-
mockPackageManager as unknown as PluginManager,
173-
),
171+
fetchRemotePackage('fake-package', mockPackageManager),
174172
).rejects.toEqual('Import error');
175173
});
176174

@@ -185,7 +183,7 @@ describe('fetcher', () => {
185183

186184
const configMeta = await fetchRemotePackage(
187185
'fake-package',
188-
mockPackageManager as unknown as PluginManager,
186+
mockPackageManager,
189187
);
190188

191189
expect(configMeta!.config).toEqual(mockConfig);
@@ -205,42 +203,38 @@ describe('fetcher', () => {
205203
Promise.resolve([]),
206204
);
207205

208-
const res = await fetchRemotePackage(
209-
'fake-package',
210-
mockPackageManager as unknown as PluginManager,
211-
);
206+
const res = await fetchRemotePackage('fake-package', mockPackageManager);
212207

213208
expect(res).toBeUndefined();
214209
});
215210

216211
it('should throw if fetching fails', async () => {
217-
const mockPackageManager = {
212+
const mockPackageManager: ModuleLoader = {
218213
install: jest.fn().mockRejectedValue('Import error'),
214+
getInfo: jest.fn(),
215+
require: jest.fn(),
219216
};
220217

221218
expect.assertions(1);
222219

223220
await expect(
224-
fetchRemotePackage(
225-
'fake-package',
226-
mockPackageManager as unknown as PluginManager,
227-
),
221+
fetchRemotePackage('fake-package', mockPackageManager),
228222
).rejects.toEqual('Import error');
229223
});
230224

231225
it('should throw if package source cannot be retrieved', async () => {
232-
const mockPackageManager = {
226+
const mockPackageManager: ModuleLoader = {
233227
install: jest.fn(),
234-
getInfo: () => undefined,
228+
getInfo: () => {
229+
throw new Error('Package not found');
230+
},
231+
require: jest.fn(),
235232
};
236233

237234
expect.assertions(1);
238235

239236
await expect(
240-
fetchRemotePackage(
241-
'fake-package',
242-
mockPackageManager as unknown as PluginManager,
243-
),
237+
fetchRemotePackage('fake-package', mockPackageManager),
244238
).rejects.toEqual(
245239
new Error(`Unable to locate package files for package: 'fake-package'`),
246240
);

0 commit comments

Comments
 (0)