2022-06-23 00:09:43 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
|
|
import { join } from 'path';
|
2022-07-14 02:03:37 +00:00
|
|
|
import { execSync } from 'child_process';
|
|
|
|
import { gt as greaterVersionThan } from 'semver';
|
2022-06-23 00:09:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { MONOREPO_ROOT, excludedPackages } from './const';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get filepath for a given package name.
|
|
|
|
*
|
|
|
|
* @param {string} name package name.
|
|
|
|
* @return {string} Absolute path for the package.
|
|
|
|
*/
|
|
|
|
export const getFilepathFromPackageName = ( name: string ): string =>
|
|
|
|
join( MONOREPO_ROOT, 'packages/js', name.replace( '@woocommerce', '' ) );
|
|
|
|
|
|
|
|
/**
|
2022-07-14 02:03:37 +00:00
|
|
|
* Get a package's package.json file in JSON format.
|
2022-06-23 00:09:43 +00:00
|
|
|
*
|
|
|
|
* @param {string} name package name.
|
2022-07-14 02:03:37 +00:00
|
|
|
* @return {Object|false} JSON object or false if it fails.
|
2022-06-23 00:09:43 +00:00
|
|
|
*/
|
2022-07-14 02:03:37 +00:00
|
|
|
export const getPackageJson = ( name: string ) => {
|
2022-06-23 00:09:43 +00:00
|
|
|
const filepath = getFilepathFromPackageName( name );
|
|
|
|
const packageJsonFilepath = `${ filepath }/package.json`;
|
|
|
|
const packageJsonExists = existsSync( packageJsonFilepath );
|
|
|
|
if ( ! packageJsonExists ) {
|
|
|
|
return false;
|
|
|
|
}
|
2022-07-14 02:03:37 +00:00
|
|
|
|
|
|
|
return JSON.parse( readFileSync( packageJsonFilepath, 'utf8' ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if package is valid and can be deployed to NPM.
|
|
|
|
*
|
|
|
|
* @param {string} name package name.
|
|
|
|
* @return {boolean} true if the package is private.
|
|
|
|
*/
|
|
|
|
export const isValidPackage = ( name: string ): boolean => {
|
|
|
|
const packageJson = getPackageJson( name );
|
|
|
|
|
|
|
|
if ( ! packageJson ) {
|
|
|
|
return false;
|
|
|
|
}
|
2022-06-23 00:09:43 +00:00
|
|
|
|
|
|
|
if ( name !== packageJson.name ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isPrivatePackage = !! packageJson.private;
|
|
|
|
|
|
|
|
if ( isPrivatePackage ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate package name.
|
|
|
|
*
|
|
|
|
* @param {string} name package name.
|
|
|
|
* @param {Function} error Error logging function.
|
|
|
|
*/
|
|
|
|
export const validatePackageName = (
|
|
|
|
name: string,
|
|
|
|
error: ( s: string ) => void
|
|
|
|
) => {
|
|
|
|
const filepath = getFilepathFromPackageName( name );
|
|
|
|
|
|
|
|
try {
|
|
|
|
const exists = existsSync( filepath );
|
|
|
|
if ( ! exists ) {
|
|
|
|
throw new Error();
|
|
|
|
}
|
|
|
|
} catch ( e ) {
|
|
|
|
error( `${ name } does not exist as a package.` );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all releaseable package names.
|
|
|
|
*
|
|
|
|
* @return {Array<string>} Package names.
|
|
|
|
*/
|
|
|
|
export const getAllPackges = (): Array< string > => {
|
|
|
|
const jsPackageFolders = readdirSync(
|
|
|
|
join( MONOREPO_ROOT, 'packages/js' ),
|
|
|
|
{
|
|
|
|
encoding: 'utf-8',
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
return jsPackageFolders
|
|
|
|
.map( ( folder ) => '@woocommerce/' + folder )
|
|
|
|
.filter( ( name ) => {
|
|
|
|
if ( excludedPackages.includes( name ) ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return isValidPackage( name );
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate a package.
|
|
|
|
*
|
|
|
|
* @param {string} name package name.
|
|
|
|
* @param {Function} error Error logging function.
|
|
|
|
*/
|
|
|
|
export const validatePackage = (
|
|
|
|
name: string,
|
|
|
|
error: ( s: string ) => void
|
|
|
|
) => {
|
|
|
|
validatePackageName( name, error );
|
|
|
|
|
|
|
|
if ( ! isValidPackage( name ) ) {
|
|
|
|
error(
|
|
|
|
`${ name } is not a valid package. It may be private or incorrectly configured.`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
2022-07-14 02:03:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if an update is valid by comparing version numbers.
|
|
|
|
*
|
2023-06-29 01:28:19 +00:00
|
|
|
* @param {string} name package name.
|
|
|
|
* @param {boolean} initialRelease if package has not been released yet.
|
2022-07-14 02:03:37 +00:00
|
|
|
* @return {boolean} If an update is valid.
|
|
|
|
*/
|
2023-06-29 01:28:19 +00:00
|
|
|
export const isValidUpdate = (
|
|
|
|
name: string,
|
|
|
|
initialRelease: boolean
|
|
|
|
): boolean => {
|
2022-07-14 02:03:37 +00:00
|
|
|
const packageJson = getPackageJson( name );
|
|
|
|
|
|
|
|
if ( ! packageJson ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nextVersion = packageJson.version;
|
|
|
|
|
|
|
|
if ( ! nextVersion ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-06-29 01:28:19 +00:00
|
|
|
if ( initialRelease ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-22 00:08:11 +00:00
|
|
|
const npmVersion = execSync( `pnpm view ${ name } version`, {
|
2022-07-14 02:03:37 +00:00
|
|
|
encoding: 'utf-8',
|
|
|
|
} );
|
|
|
|
|
|
|
|
return greaterVersionThan( nextVersion.trim(), npmVersion.trim() );
|
|
|
|
};
|