When you run create-nx-workspace --preset you can now pass in an npm package name. This package will contain a generator named preset which is run after the workspace has been generated.
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
const scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$');
|
|
const denyList = ['node_modules', 'favicon.ico'];
|
|
|
|
export interface ValidateNpmResult {
|
|
validForNewPackages: boolean;
|
|
validForOldPackages: boolean;
|
|
errors?: string[];
|
|
warnings?: string[];
|
|
}
|
|
|
|
export function validateNpmPackage(name: string) {
|
|
let warnings = [];
|
|
let errors = [];
|
|
|
|
if (name === null) {
|
|
errors.push('name cannot be null');
|
|
return formatResult(warnings, errors);
|
|
}
|
|
|
|
if (name === undefined) {
|
|
errors.push('name cannot be undefined');
|
|
return formatResult(warnings, errors);
|
|
}
|
|
|
|
if (typeof name !== 'string') {
|
|
errors.push('name must be a string');
|
|
return formatResult(warnings, errors);
|
|
}
|
|
|
|
if (!name.length) {
|
|
errors.push('name length must be greater than zero');
|
|
}
|
|
|
|
if (name.match(/^\./)) {
|
|
errors.push('name cannot start with a period');
|
|
}
|
|
|
|
if (name.match(/^_/)) {
|
|
errors.push('name cannot start with an underscore');
|
|
}
|
|
|
|
if (name.trim() !== name) {
|
|
errors.push('name cannot contain leading or trailing spaces');
|
|
}
|
|
|
|
// No funny business
|
|
denyList.forEach(function (denyListedName) {
|
|
if (name.toLowerCase() === denyListedName) {
|
|
errors.push(denyListedName + ' is a deny listed name');
|
|
}
|
|
});
|
|
|
|
// really-long-package-names-------------------------------such--length-----many---wow
|
|
// the thisisareallyreallylongpackagenameitshouldpublishdowenowhavealimittothelengthofpackagenames-poch.
|
|
if (name.length > 214) {
|
|
warnings.push('name can no longer contain more than 214 characters');
|
|
}
|
|
|
|
// mIxeD CaSe nAMEs
|
|
if (name.toLowerCase() !== name) {
|
|
warnings.push('name can no longer contain capital letters');
|
|
}
|
|
|
|
if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) {
|
|
warnings.push('name can no longer contain special characters ("~\'!()*")');
|
|
}
|
|
|
|
if (encodeURIComponent(name) !== name) {
|
|
// Maybe it's a scoped package name, like @user/package
|
|
const nameMatch = name.match(scopedPackagePattern);
|
|
if (nameMatch) {
|
|
const user = nameMatch[1];
|
|
const pkg = nameMatch[2];
|
|
if (
|
|
encodeURIComponent(user) === user &&
|
|
encodeURIComponent(pkg) === pkg
|
|
) {
|
|
return formatResult(warnings, errors);
|
|
}
|
|
}
|
|
|
|
errors.push('name can only contain URL-friendly characters');
|
|
}
|
|
|
|
return formatResult(warnings, errors);
|
|
}
|
|
|
|
function formatResult(warnings: string[], errors: string[]): ValidateNpmResult {
|
|
return {
|
|
validForNewPackages: errors.length === 0 && warnings.length === 0,
|
|
validForOldPackages: errors.length === 0,
|
|
...(warnings.length && { warnings }),
|
|
...(errors.length && { errors }),
|
|
};
|
|
}
|