Skip to content

Commit b449962

Browse files
authored
Merge pull request #219 from chouchouji/feat-delete-multiple-registry
feat: support deleting multiple custom registries
2 parents e1774b8 + b224d76 commit b449962

File tree

8 files changed

+187
-26
lines changed

8 files changed

+187
-26
lines changed

.changeset/grumpy-bags-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nrm": patch
3+
---
4+
5+
Added delete multiple registry. Thanks @chouchouji

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Usage: nrm [options] [command]
7171
set <registryName> Set custom registry attribute
7272
-a --attr <attr> Set custom registry attribute
7373
-v --value <value> Set custom registry value
74-
del <registry> Delete one custom registry
74+
del [registry] Delete one custom registry
7575
rename <registryName> <newName> Set custom registry name
7676
home <registry> [browser] Open the homepage of registry with optional browser
7777
publish [<tarball>|<folder>] Publish package to current registry if current registry is a custom registry. The field 'repository' of current custom registry is required running this command. If you're not using custom registry, this command will run npm publish directly

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
},
3535
"homepage": "https://github.com/Pana/nrm",
3636
"dependencies": {
37+
"@inquirer/checkbox": "^4.0.3",
3738
"@inquirer/select": "^4.0.2",
3839
"chalk": "4.1.2",
3940
"commander": "^8.3.0",

pnpm-lock.yaml

+36
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions.ts

+49-18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import checkbox from '@inquirer/checkbox';
12
import select from '@inquirer/select';
23
import chalk from 'chalk';
34
import open from 'open';
@@ -56,14 +57,18 @@ export async function onCurrent({ showUrl }: { showUrl: boolean }) {
5657
if (!matchedRegistry) {
5758
printMessages([
5859
`Your current registry(${currentRegistry}) is not included in the nrm registries.`,
59-
`Use the ${chalk.green('nrm add <registry> <url> [home]')} command to add your registry.`,
60+
`Use the ${chalk.green(
61+
'nrm add <registry> <url> [home]',
62+
)} command to add your registry.`,
6063
]);
6164
return;
6265
}
6366

6467
const [name, registry] = matchedRegistry;
6568
printMessages([
66-
`You are using ${chalk.green(showUrl ? registry[REGISTRY] : name)} registry.`,
69+
`You are using ${chalk.green(
70+
showUrl ? registry[REGISTRY] : name,
71+
)} registry.`,
6772
]);
6873
}
6974

@@ -73,7 +78,7 @@ export async function onUse(name: string) {
7378

7479
// if alias is undefined, select the registry alias from list
7580
if (alias === undefined) {
76-
alias = await select({
81+
alias = await select<string>({
7782
message: 'Please select the registry you want to use',
7883
choices: Object.keys(registries),
7984
pageSize: 10,
@@ -91,23 +96,45 @@ export async function onUse(name: string) {
9196
printSuccess(`The registry has been changed to '${alias}'.`);
9297
}
9398

94-
export async function onDelete(name: string) {
95-
if (
96-
(await isRegistryNotFound(name)) ||
97-
(await isInternalRegistry(name, 'delete'))
98-
) {
99+
export async function onDelete(name: string | undefined) {
100+
const customRegistries = await readFile(NRMRC);
101+
102+
const deleteKeys: string[] = [];
103+
if (name) {
104+
deleteKeys.push(name);
105+
}
106+
107+
const choices = Object.keys(customRegistries);
108+
if (name === undefined && !choices.length) {
109+
printMessages(['No any custom registries can be deleted.']);
99110
return;
100111
}
101112

102-
const customRegistries = await readFile(NRMRC);
103-
const registry = customRegistries[name];
104-
delete customRegistries[name];
105-
await writeFile(NRMRC, customRegistries);
106-
printSuccess(`The registry '${name}' has been deleted successfully.`);
113+
if (name === undefined) {
114+
const selectedKeys = await checkbox<string>({
115+
message: 'Please select the registries you want to delete',
116+
choices,
117+
});
118+
deleteKeys.push(...selectedKeys);
119+
}
107120

108-
const currentRegistry = await getCurrentRegistry();
109-
if (currentRegistry === registry[REGISTRY]) {
110-
await onUse('npm');
121+
for (const key of deleteKeys) {
122+
if (
123+
(await isRegistryNotFound(key)) ||
124+
(await isInternalRegistry(key, 'delete'))
125+
) {
126+
continue;
127+
}
128+
129+
const registry = customRegistries[key];
130+
delete customRegistries[key];
131+
await writeFile(NRMRC, customRegistries);
132+
printSuccess(`The registry '${key}' has been deleted successfully.`);
133+
134+
const currentRegistry = await getCurrentRegistry();
135+
if (currentRegistry === registry[REGISTRY]) {
136+
await onUse('npm');
137+
}
111138
}
112139
}
113140

@@ -135,7 +162,9 @@ export async function onAdd(name: string, url: string, home?: string) {
135162
});
136163
await writeFile(NRMRC, newCustomRegistries);
137164
printSuccess(
138-
`Add registry ${name} success, run ${chalk.green(`nrm use ${name}`)} command to use ${name} registry.`,
165+
`Add registry ${name} success, run ${chalk.green(
166+
`nrm use ${name}`,
167+
)} command to use ${name} registry.`,
139168
);
140169
}
141170

@@ -250,7 +279,9 @@ export async function onSetAttribute(
250279

251280
if (REPOSITORY === attr) {
252281
return exit(
253-
`Use the ${chalk.green('nrm set-hosted-repo <name> <repo>')} command to set repository.`,
282+
`Use the ${chalk.green(
283+
'nrm set-hosted-repo <name> <repo>',
284+
)} command to set repository.`,
254285
);
255286
}
256287
const customRegistries = await readFile(NRMRC);

src/helpers.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ export function printError(error: string) {
5353
}
5454

5555
export function printMessages(messages: string[]) {
56-
for (const message of messages) {
57-
console.log(message);
58-
}
56+
console.log(messages.join('\n'));
5957
}
6058

6159
export function geneDashLine(message: string, length: number) {
@@ -105,3 +103,20 @@ export function exit(error?: string) {
105103
error && printError(error);
106104
process.exit(1);
107105
}
106+
107+
export function isUnicodeSupported() {
108+
if (process.platform !== 'win32') {
109+
return process.env.TERM !== 'linux';
110+
}
111+
112+
return (
113+
Boolean(process.env.WT_SESSION) ||
114+
Boolean(process.env.TERMINUS_SUBLIME) ||
115+
process.env.ConEmuTask === '{cmd::Cmder}' ||
116+
process.env.TERM_PROGRAM === 'Terminus-Sublime' ||
117+
process.env.TERM_PROGRAM === 'vscode' ||
118+
process.env.TERM === 'xterm-256color' ||
119+
process.env.TERM === 'alacritty' ||
120+
process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm'
121+
);
122+
}

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ program
8282
.action(onRename);
8383

8484
program
85-
.command('del <name>')
85+
.command('del [name]')
8686
.description('Delete custom registry')
8787
.action(onDelete);
8888

tests/cli.test.ts

+76-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@ import {
1414
vi,
1515
} from 'vitest';
1616

17+
import { unlink } from 'node:fs/promises';
1718
import { onHome, onTest } from '../src/actions';
18-
import { NPMRC, REGISTRIES } from '../src/constants';
19-
import { readFile, writeFile } from '../src/helpers';
19+
import { NPMRC, NRMRC, REGISTRIES } from '../src/constants';
20+
import { isUnicodeSupported, readFile, writeFile } from '../src/helpers';
21+
2022

2123
const isWin = process.platform === 'win32';
2224

25+
const shouldUseMain = isUnicodeSupported();
26+
27+
const pointer = shouldUseMain ? '❯' : '>';
28+
const radioOff = shouldUseMain ? '◯' : '( )';
29+
const radioOn = shouldUseMain ? '◉' : '(*)';
30+
2331
vi.setConfig({
2432
testTimeout: 20000,
2533
});
@@ -138,7 +146,7 @@ it('nrm use without argument', async () => {
138146
expect(
139147
message,
140148
).toBe(`? Please select the registry you want to use (Use arrow keys)
141-
${isWin ? '>' : '❯'} npm
149+
${pointer} npm
142150
yarn
143151
tencent
144152
cnpm
@@ -281,3 +289,68 @@ it('nrm home <registry> [browser]', async () => {
281289
await onHome('cnpm');
282290
expect(open).toHaveBeenCalled();
283291
});
292+
293+
describe('nrm delete without argument (use keyword to select delete)', () => {
294+
const registries = [
295+
{ name: 'test', url: 'http://localhost:3000' },
296+
{ name: 'test1', url: 'http://localhost:3001' },
297+
{ name: 'test2', url: 'http://localhost:3002' },
298+
];
299+
beforeEach(async () => {
300+
for (const registry of registries) {
301+
await coffee
302+
.spawn('nrm', ['add', `${registry.name}`, `${registry.url}`], {
303+
shell: isWin,
304+
})
305+
.expect('stdout', /success/g)
306+
.expect('code', 0)
307+
.end();
308+
}
309+
});
310+
311+
afterEach(async () => {
312+
await unlink(NRMRC);
313+
});
314+
315+
it('nrm delete', async () => {
316+
const { stdout } = spawn('nrm', ['del'], { shell: isWin });
317+
318+
const message = await new Promise((resolve) => {
319+
stdout.on('data', (data) => {
320+
resolve(stripAnsi(data.toString()).trim());
321+
});
322+
});
323+
324+
expect(message).toMatchInlineSnapshot(`
325+
"? Please select the registries you want to delete (Press <space> to select, <a>
326+
to toggle all, <i> to invert selection, and <enter> to proceed)
327+
${pointer}${radioOff} test
328+
${radioOff} test1
329+
${radioOff} test2"
330+
`);
331+
});
332+
333+
it('nrm delete (with keyword input)', async () => {
334+
const { stdout, stdin } = spawn('nrm', ['del'], { shell: isWin });
335+
stdin.write('\u001b[B');
336+
337+
const message = await new Promise((resolve) => {
338+
const m: string[] = [];
339+
stdout.on('data', (data) => {
340+
m.push(stripAnsi(data.toString()).trim());
341+
// get the last output
342+
if (m.length === 2) {
343+
resolve(m[m.length - 1]);
344+
}
345+
});
346+
});
347+
348+
expect(message).toMatchInlineSnapshot(`
349+
"? Please select the registries you want to delete (Press <space> to select, <a>
350+
to toggle all, <i> to invert selection, and <enter> to proceed)
351+
${radioOff} test
352+
${pointer}${radioOff} test1
353+
${radioOff} test2"
354+
`);
355+
});
356+
});

0 commit comments

Comments
 (0)