167 lines
4.1 KiB
TypeScript
167 lines
4.1 KiB
TypeScript
import * as plugins from './mod.plugins.js';
|
|
|
|
export type TAccessLevel = 'public' | 'private';
|
|
|
|
export interface IReleaseConfig {
|
|
registries: string[];
|
|
accessLevel: TAccessLevel;
|
|
}
|
|
|
|
/**
|
|
* Manages release configuration stored in npmextra.json
|
|
* under @git.zone/cli.release namespace
|
|
*/
|
|
export class ReleaseConfig {
|
|
private cwd: string;
|
|
private config: IReleaseConfig;
|
|
|
|
constructor(cwd: string = process.cwd()) {
|
|
this.cwd = cwd;
|
|
this.config = { registries: [], accessLevel: 'public' };
|
|
}
|
|
|
|
/**
|
|
* Create a ReleaseConfig instance from current working directory
|
|
*/
|
|
public static async fromCwd(cwd: string = process.cwd()): Promise<ReleaseConfig> {
|
|
const instance = new ReleaseConfig(cwd);
|
|
await instance.load();
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Load configuration from npmextra.json
|
|
*/
|
|
public async load(): Promise<void> {
|
|
const npmextraInstance = new plugins.npmextra.Npmextra(this.cwd);
|
|
const gitzoneConfig = npmextraInstance.dataFor<any>('@git.zone/cli', {});
|
|
|
|
// Also check szci for backward compatibility
|
|
const szciConfig = npmextraInstance.dataFor<any>('@ship.zone/szci', {});
|
|
|
|
this.config = {
|
|
registries: gitzoneConfig?.release?.registries || [],
|
|
accessLevel: gitzoneConfig?.release?.accessLevel || szciConfig?.npmAccessLevel || 'public',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Save configuration to npmextra.json
|
|
*/
|
|
public async save(): Promise<void> {
|
|
const npmextraPath = plugins.path.join(this.cwd, 'npmextra.json');
|
|
let npmextraData: any = {};
|
|
|
|
// Read existing npmextra.json
|
|
if (await plugins.smartfs.file(npmextraPath).exists()) {
|
|
const content = await plugins.smartfs.file(npmextraPath).encoding('utf8').read();
|
|
npmextraData = JSON.parse(content as string);
|
|
}
|
|
|
|
// Ensure @git.zone/cli namespace exists
|
|
if (!npmextraData['@git.zone/cli']) {
|
|
npmextraData['@git.zone/cli'] = {};
|
|
}
|
|
|
|
// Ensure release object exists
|
|
if (!npmextraData['@git.zone/cli'].release) {
|
|
npmextraData['@git.zone/cli'].release = {};
|
|
}
|
|
|
|
// Update registries and accessLevel
|
|
npmextraData['@git.zone/cli'].release.registries = this.config.registries;
|
|
npmextraData['@git.zone/cli'].release.accessLevel = this.config.accessLevel;
|
|
|
|
// Write back to file
|
|
await plugins.smartfs
|
|
.file(npmextraPath)
|
|
.encoding('utf8')
|
|
.write(JSON.stringify(npmextraData, null, 2));
|
|
}
|
|
|
|
/**
|
|
* Get all configured registries
|
|
*/
|
|
public getRegistries(): string[] {
|
|
return [...this.config.registries];
|
|
}
|
|
|
|
/**
|
|
* Check if any registries are configured
|
|
*/
|
|
public hasRegistries(): boolean {
|
|
return this.config.registries.length > 0;
|
|
}
|
|
|
|
/**
|
|
* Add a registry URL
|
|
* @returns true if added, false if already exists
|
|
*/
|
|
public addRegistry(url: string): boolean {
|
|
const normalizedUrl = this.normalizeUrl(url);
|
|
|
|
if (this.config.registries.includes(normalizedUrl)) {
|
|
return false;
|
|
}
|
|
|
|
this.config.registries.push(normalizedUrl);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Remove a registry URL
|
|
* @returns true if removed, false if not found
|
|
*/
|
|
public removeRegistry(url: string): boolean {
|
|
const normalizedUrl = this.normalizeUrl(url);
|
|
const index = this.config.registries.indexOf(normalizedUrl);
|
|
|
|
if (index === -1) {
|
|
return false;
|
|
}
|
|
|
|
this.config.registries.splice(index, 1);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Clear all registries
|
|
*/
|
|
public clearRegistries(): void {
|
|
this.config.registries = [];
|
|
}
|
|
|
|
/**
|
|
* Get the npm access level
|
|
*/
|
|
public getAccessLevel(): TAccessLevel {
|
|
return this.config.accessLevel;
|
|
}
|
|
|
|
/**
|
|
* Set the npm access level
|
|
*/
|
|
public setAccessLevel(level: TAccessLevel): void {
|
|
this.config.accessLevel = level;
|
|
}
|
|
|
|
/**
|
|
* Normalize a registry URL (ensure it has https:// prefix)
|
|
*/
|
|
private normalizeUrl(url: string): string {
|
|
let normalized = url.trim();
|
|
|
|
// Add https:// if no protocol specified
|
|
if (!normalized.startsWith('http://') && !normalized.startsWith('https://')) {
|
|
normalized = `https://${normalized}`;
|
|
}
|
|
|
|
// Remove trailing slash
|
|
if (normalized.endsWith('/')) {
|
|
normalized = normalized.slice(0, -1);
|
|
}
|
|
|
|
return normalized;
|
|
}
|
|
}
|