import * as plugins from './plugins.js'; import * as paths from './paths.js'; import { logger } from './logging.js'; export interface IPublishModuleOptions { monoRepoDir: string; packageSubFolder: string; packageSubFolderFullPath?: string; publishModDirFullPath?: string; name?: string; version?: string; dependencies?: { [key: string]: string }; } export class PublishModule { public options: IPublishModuleOptions; constructor(options: IPublishModuleOptions) { this.options = options; } public async init() { this.options.packageSubFolderFullPath = plugins.path.join( this.options.monoRepoDir, this.options.packageSubFolder ); // check requirements if (!this.options.packageSubFolder.startsWith('ts')) { throw new Error('subFolder must start with "ts"'); } const jsonData = plugins.smartfile.fs.toObjectSync( plugins.path.join(this.options.packageSubFolderFullPath, 'tspublish.json') ); const monoRepoPackageJson = JSON.parse( plugins.smartfile.fs.toStringSync(plugins.path.join(this.options.monoRepoDir, 'package.json')) ) this.options.dependencies = { ...this.options.dependencies, ...(() => { const resultDependencies = {}; for (const dependency of jsonData.dependencies) { resultDependencies[dependency] = monoRepoPackageJson.dependencies[dependency]; } return resultDependencies; })() }; this.options.name = this.options.name || jsonData.name; this.options.version = monoRepoPackageJson.version; // now that we have a name and version, lets check if there is already a package under the same name and version. const smartnpmInstance = new plugins.smartnpm.NpmRegistry({}); // TODO: pass in options const packageInfo = await smartnpmInstance.getPackageInfo(this.options.name); if (packageInfo) { const availableVersions = packageInfo.allVersions.map((versionArg) => versionArg.version); logger.log('info', `available versions are: ${availableVersions.toString()}`); if (availableVersions.includes(this.options.version)) { throw new Error( `package ${this.options.name} already exists with version ${this.options.version}` ); } } } public async getLatestVersionOfPackage(name: string) { const smartnpmInstance = new plugins.smartnpm.NpmRegistry({}); // TODO: pass in options const packageInfo = await smartnpmInstance.getPackageInfo(name); if (!packageInfo) { throw new Error(`package ${name} not found`); } return packageInfo.allVersions[0].version; } public async createPackageJson() { const packageJson = { name: this.options.name, version: this.options.version, description: '', exports: { '.': { import: './dist_${this.options.packageSubFolder}/index.js', }, }, scripts: { build: 'tsbuild tsfolders --allowimplicitany', }, dependencies: this.options.dependencies, devDependencies: { '@git.zone/tsbuild': await this.getLatestVersionOfPackage('@git.zone/tsbuild'), }, }; return JSON.stringify(packageJson, null, 2); } public async createPublishModuleDir() { this.options.publishModDirFullPath = plugins.path.join( this.options.monoRepoDir, `dist_publish_${this.options.packageSubFolder}` ); // package.json await plugins.smartfile.fs.ensureEmptyDir(this.options.publishModDirFullPath); const packageJson = await plugins.smartfile.SmartFile.fromString( plugins.path.join(this.options.publishModDirFullPath, 'package.json'), await this.createPackageJson(), 'utf8' ); // ts folder await plugins.smartfile.fs.copy(this.options.packageSubFolderFullPath, plugins.path.join(this.options.publishModDirFullPath, this.options.packageSubFolder)) } public async build() { const smartshellInstance = new plugins.smartshell.Smartshell({ executor: 'bash', }) await smartshellInstance.exec(`cd ${this.options.publishModDirFullPath} && pnpm run build`); } public async publish() { const smartshellInstance = new plugins.smartshell.Smartshell({ executor: 'bash', }) await smartshellInstance.exec(`cd ${this.options.publishModDirFullPath} && pnpm publish`); } }