305 lines
9.0 KiB
TypeScript
305 lines
9.0 KiB
TypeScript
// gitzone config - manage release registry configuration
|
|
|
|
import * as plugins from './mod.plugins.js';
|
|
import { ReleaseConfig } from './classes.releaseconfig.js';
|
|
import { runFormatter, type ICheckResult } from '../mod_format/index.js';
|
|
|
|
export { ReleaseConfig };
|
|
|
|
/**
|
|
* Format npmextra.json with diff preview
|
|
* Shows diff first, asks for confirmation, then applies
|
|
*/
|
|
async function formatNpmextraWithDiff(): Promise<void> {
|
|
// Check for diffs first
|
|
const checkResult = await runFormatter('npmextra', {
|
|
checkOnly: true,
|
|
showDiff: true,
|
|
}) as ICheckResult | void;
|
|
|
|
if (checkResult && checkResult.hasDiff) {
|
|
const shouldApply = await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
'Apply formatting changes to npmextra.json?',
|
|
true
|
|
);
|
|
if (shouldApply) {
|
|
await runFormatter('npmextra', { silent: true });
|
|
}
|
|
}
|
|
}
|
|
|
|
export const run = async (argvArg: any) => {
|
|
const command = argvArg._?.[1];
|
|
const value = argvArg._?.[2];
|
|
|
|
// If no command provided, show interactive menu
|
|
if (!command) {
|
|
await handleInteractiveMenu();
|
|
return;
|
|
}
|
|
|
|
switch (command) {
|
|
case 'show':
|
|
await handleShow();
|
|
break;
|
|
case 'add':
|
|
await handleAdd(value);
|
|
break;
|
|
case 'remove':
|
|
await handleRemove(value);
|
|
break;
|
|
case 'clear':
|
|
await handleClear();
|
|
break;
|
|
case 'access':
|
|
case 'accessLevel':
|
|
await handleAccessLevel(value);
|
|
break;
|
|
case 'help':
|
|
showHelp();
|
|
break;
|
|
default:
|
|
plugins.logger.log('error', `Unknown command: ${command}`);
|
|
showHelp();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Interactive menu for config command
|
|
*/
|
|
async function handleInteractiveMenu(): Promise<void> {
|
|
console.log('');
|
|
console.log('╭─────────────────────────────────────────────────────────────╮');
|
|
console.log('│ gitzone config - Release Configuration │');
|
|
console.log('╰─────────────────────────────────────────────────────────────╯');
|
|
console.log('');
|
|
|
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
const response = await interactInstance.askQuestion({
|
|
type: 'list',
|
|
name: 'action',
|
|
message: 'What would you like to do?',
|
|
default: 'show',
|
|
choices: [
|
|
{ name: 'Show current configuration', value: 'show' },
|
|
{ name: 'Add a registry', value: 'add' },
|
|
{ name: 'Remove a registry', value: 'remove' },
|
|
{ name: 'Clear all registries', value: 'clear' },
|
|
{ name: 'Set access level (public/private)', value: 'access' },
|
|
{ name: 'Show help', value: 'help' },
|
|
],
|
|
});
|
|
|
|
const action = (response as any).value;
|
|
|
|
switch (action) {
|
|
case 'show':
|
|
await handleShow();
|
|
break;
|
|
case 'add':
|
|
await handleAdd();
|
|
break;
|
|
case 'remove':
|
|
await handleRemove();
|
|
break;
|
|
case 'clear':
|
|
await handleClear();
|
|
break;
|
|
case 'access':
|
|
await handleAccessLevel();
|
|
break;
|
|
case 'help':
|
|
showHelp();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show current registry configuration
|
|
*/
|
|
async function handleShow(): Promise<void> {
|
|
const config = await ReleaseConfig.fromCwd();
|
|
const registries = config.getRegistries();
|
|
const accessLevel = config.getAccessLevel();
|
|
|
|
console.log('');
|
|
console.log('╭─────────────────────────────────────────────────────────────╮');
|
|
console.log('│ Release Configuration │');
|
|
console.log('╰─────────────────────────────────────────────────────────────╯');
|
|
console.log('');
|
|
|
|
// Show access level
|
|
plugins.logger.log('info', `Access Level: ${accessLevel}`);
|
|
console.log('');
|
|
|
|
if (registries.length === 0) {
|
|
plugins.logger.log('info', 'No release registries configured.');
|
|
console.log('');
|
|
console.log(' Run `gitzone config add <registry-url>` to add one.');
|
|
console.log('');
|
|
} else {
|
|
plugins.logger.log('info', `Configured registries (${registries.length}):`);
|
|
console.log('');
|
|
registries.forEach((url, index) => {
|
|
console.log(` ${index + 1}. ${url}`);
|
|
});
|
|
console.log('');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a registry URL
|
|
*/
|
|
async function handleAdd(url?: string): Promise<void> {
|
|
if (!url) {
|
|
// Interactive mode
|
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
const response = await interactInstance.askQuestion({
|
|
type: 'input',
|
|
name: 'registryUrl',
|
|
message: 'Enter registry URL:',
|
|
default: 'https://registry.npmjs.org',
|
|
validate: (input: string) => {
|
|
return !!(input && input.trim() !== '');
|
|
},
|
|
});
|
|
url = (response as any).value;
|
|
}
|
|
|
|
const config = await ReleaseConfig.fromCwd();
|
|
const added = config.addRegistry(url!);
|
|
|
|
if (added) {
|
|
await config.save();
|
|
plugins.logger.log('success', `Added registry: ${url}`);
|
|
await formatNpmextraWithDiff();
|
|
} else {
|
|
plugins.logger.log('warn', `Registry already exists: ${url}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a registry URL
|
|
*/
|
|
async function handleRemove(url?: string): Promise<void> {
|
|
const config = await ReleaseConfig.fromCwd();
|
|
const registries = config.getRegistries();
|
|
|
|
if (registries.length === 0) {
|
|
plugins.logger.log('warn', 'No registries configured to remove.');
|
|
return;
|
|
}
|
|
|
|
if (!url) {
|
|
// Interactive mode - show list to select from
|
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
const response = await interactInstance.askQuestion({
|
|
type: 'list',
|
|
name: 'registryUrl',
|
|
message: 'Select registry to remove:',
|
|
choices: registries,
|
|
default: registries[0],
|
|
});
|
|
url = (response as any).value;
|
|
}
|
|
|
|
const removed = config.removeRegistry(url!);
|
|
|
|
if (removed) {
|
|
await config.save();
|
|
plugins.logger.log('success', `Removed registry: ${url}`);
|
|
await formatNpmextraWithDiff();
|
|
} else {
|
|
plugins.logger.log('warn', `Registry not found: ${url}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear all registries
|
|
*/
|
|
async function handleClear(): Promise<void> {
|
|
const config = await ReleaseConfig.fromCwd();
|
|
|
|
if (!config.hasRegistries()) {
|
|
plugins.logger.log('info', 'No registries to clear.');
|
|
return;
|
|
}
|
|
|
|
// Confirm before clearing
|
|
const confirmed = await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
'Clear all configured registries?',
|
|
false
|
|
);
|
|
|
|
if (confirmed) {
|
|
config.clearRegistries();
|
|
await config.save();
|
|
plugins.logger.log('success', 'All registries cleared.');
|
|
await formatNpmextraWithDiff();
|
|
} else {
|
|
plugins.logger.log('info', 'Operation cancelled.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set or toggle access level
|
|
*/
|
|
async function handleAccessLevel(level?: string): Promise<void> {
|
|
const config = await ReleaseConfig.fromCwd();
|
|
const currentLevel = config.getAccessLevel();
|
|
|
|
if (!level) {
|
|
// Interactive mode - toggle or ask
|
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
const response = await interactInstance.askQuestion({
|
|
type: 'list',
|
|
name: 'accessLevel',
|
|
message: 'Select npm access level for publishing:',
|
|
choices: ['public', 'private'],
|
|
default: currentLevel,
|
|
});
|
|
level = (response as any).value;
|
|
}
|
|
|
|
// Validate the level
|
|
if (level !== 'public' && level !== 'private') {
|
|
plugins.logger.log('error', `Invalid access level: ${level}. Must be 'public' or 'private'.`);
|
|
return;
|
|
}
|
|
|
|
if (level === currentLevel) {
|
|
plugins.logger.log('info', `Access level is already set to: ${level}`);
|
|
return;
|
|
}
|
|
|
|
config.setAccessLevel(level as 'public' | 'private');
|
|
await config.save();
|
|
plugins.logger.log('success', `Access level set to: ${level}`);
|
|
await formatNpmextraWithDiff();
|
|
}
|
|
|
|
/**
|
|
* Show help for config command
|
|
*/
|
|
function showHelp(): void {
|
|
console.log('');
|
|
console.log('Usage: gitzone config <command> [options]');
|
|
console.log('');
|
|
console.log('Commands:');
|
|
console.log(' show Display current release configuration');
|
|
console.log(' add [url] Add a registry URL');
|
|
console.log(' remove [url] Remove a registry URL');
|
|
console.log(' clear Clear all registries');
|
|
console.log(' access [public|private] Set npm access level for publishing');
|
|
console.log('');
|
|
console.log('Examples:');
|
|
console.log(' gitzone config show');
|
|
console.log(' gitzone config add https://registry.npmjs.org');
|
|
console.log(' gitzone config add https://verdaccio.example.com');
|
|
console.log(' gitzone config remove https://registry.npmjs.org');
|
|
console.log(' gitzone config clear');
|
|
console.log(' gitzone config access public');
|
|
console.log(' gitzone config access private');
|
|
console.log('');
|
|
}
|