@pnp/cli-microsoft365
Version:
Manage Microsoft 365 and SharePoint Framework projects on any platform
366 lines • 12.8 kB
JavaScript
import { formatting } from "./formatting.js";
export const validation = {
isValidGuidArray(guidsString) {
const guids = guidsString.split(',').map(guid => guid.trim());
const invalidGuids = guids.filter(guid => !this.isValidGuid(guid));
return invalidGuids.length > 0 ? invalidGuids.join(', ') : true;
},
isValidGuid(guid) {
if (!guid) {
return false;
}
const guidRegEx = new RegExp(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
// verify if the guid is a valid guid. @meid will be replaced in a later
// stage with the actual user id of the logged in user
// we also need to make it toString in case the args is resolved as number
// or boolean
return guidRegEx.test(guid) || guid.toString().toLowerCase().trim() === '@meid';
},
isValidTeamsChannelId(guid) {
const guidRegEx = new RegExp(/^19:[0-9a-zA-Z-_]+@thread\.(skype|tacv2)$/i);
return guidRegEx.test(guid);
},
isValidTeamsChatId(guid) {
const guidRegEx = new RegExp(/^19:[0-9a-zA-Z-_]+(@thread\.v2|@unq\.gbl\.spaces)$/i);
return guidRegEx.test(guid);
},
isValidUserPrincipalNameArray(upnsString) {
const upns = upnsString.split(',').map(upn => upn.trim());
const invalidUPNs = upns.filter(upn => !this.isValidUserPrincipalName(upn));
return invalidUPNs.length > 0 ? invalidUPNs.join(', ') : true;
},
isValidUserPrincipalName(upn) {
const upnRegEx = new RegExp(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/i);
// verify if the upn is a valid upn. @meusername will be replaced in a later stage with the actual username of the logged in user
return upnRegEx.test(upn) || upn.toLowerCase().trim() === '@meusername';
},
/**
* Validates if the provided number is a valid positive integer (1 or higher).
* @param integer Integer value.
* @returns True if integer, false otherwise.
*/
isValidPositiveInteger(integer) {
return !isNaN(Number(integer)) && Number.isInteger(+integer) && +integer > 0;
},
/**
* Validates an array of integers. The integers must be positive (1 or higher).
* @param integerString Comma-separated string of integers.
* @returns True if the integers are valid, an error message with the invalid integers otherwise.
*/
isValidPositiveIntegerArray(integerString) {
const integers = formatting.splitAndTrim(integerString);
const invalidIntegers = integers.filter(integer => !this.isValidPositiveInteger(integer));
return invalidIntegers.length > 0 ? invalidIntegers.join(', ') : true;
},
isDateInRange(date, monthOffset) {
const d = new Date(date);
const cutoffDate = new Date();
cutoffDate.setMonth(cutoffDate.getMonth() - monthOffset);
return d > cutoffDate;
},
isValidISODate(date) {
const dateRegEx = new RegExp(/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/i);
return dateRegEx.test(date);
},
isValidISODateDashOnly(date) {
const dateTimeRegEx = new RegExp(/^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))$/i);
const dateOnlyRegEx = new RegExp(/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/i);
return dateTimeRegEx.test(date) ? true : dateOnlyRegEx.test(date);
},
isValidISODateTime(dateTime) {
// Format: 2000-01-01T00:00:00.0000000Z
const withMilliSecsLongPattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])\.[0-9]{7}Z$/);
if (withMilliSecsLongPattern.test(dateTime)) {
return true;
}
// Format: 2000-01-01T00:00:00.000Z
const withMilliSecsShortPattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])\.[0-9]{3}Z$/);
if (withMilliSecsShortPattern.test(dateTime)) {
return true;
}
// Format: 2000-01-01T00:00:00Z
const withSecsPattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])Z$/);
if (withSecsPattern.test(dateTime)) {
return true;
}
// Format: 2000-01-01T00:00Z
const withMinutesPattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])Z$/);
if (withMinutesPattern.test(dateTime)) {
return true;
}
// Format: 2000-01-01T00Z
const withHoursPattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3])Z$/);
if (withHoursPattern.test(dateTime)) {
return true;
}
// Format: 2000-01-01
const withoutTimePattern = new RegExp(/^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))$/);
if (withoutTimePattern.test(dateTime)) {
return true;
}
return false;
},
isValidBoolean(value) {
return value.toLowerCase() === 'true' || value.toLowerCase() === 'false';
},
isJavaScriptReservedWord(input) {
const javascriptReservedWords = [
"arguments",
"await",
"break",
"case",
"catch",
"class",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"else",
"enum",
"eval",
"export",
"extends",
"false",
"finally",
"for",
"function",
"if",
"implements",
"import",
"in",
"instanceof",
"interface",
"let",
"new",
"null",
"package",
"private",
"protected",
"public",
"return",
"static",
"super",
"switch",
"this",
"throw",
"true",
"try",
"typeof",
"var",
"void",
"while",
"with",
"yield",
"Array",
"Date",
"eval",
"function",
"hasOwnProperty",
"Infinity",
"isFinite",
"isNaN",
"isPrototypeOf",
"length",
"Math",
"NaN",
"name",
"Number",
"Object",
"prototype",
"String",
"toString",
"undefined",
"valueOf",
"alert",
"all",
"anchor",
"anchors",
"area",
"assign",
"blur",
"button",
"checkbox",
"clearInterval",
"clearTimeout",
"clientInformation",
"close",
"closed",
"confirm",
"constructor",
"crypto",
"decodeURI",
"decodeURIComponent",
"defaultStatus",
"document",
"element",
"elements",
"embed",
"embeds",
"encodeURI",
"encodeURIComponent",
"escape",
"event",
"fileUpload",
"focus",
"form",
"forms",
"frame",
"innerHeight",
"innerWidth",
"layer",
"layers",
"link",
"location",
"mimeTypes",
"navigate",
"navigator",
"frames",
"frameRate",
"hidden",
"history",
"image",
"images",
"offscreenBuffering",
"open",
"opener",
"option",
"outerHeight",
"outerWidth",
"packages",
"pageXOffset",
"pageYOffset",
"parent",
"parseFloat",
"parseInt",
"password",
"pkcs11",
"plugin",
"prompt",
"propertyIsEnum",
"radio",
"reset",
"screenX",
"screenY",
"scroll",
"secure",
"select",
"self",
"setInterval",
"setTimeout",
"status",
"submit",
"taint",
"text",
"textarea",
"top",
"unescape",
"untaint",
"window",
"onblur",
"onclick",
"onerror",
"onfocus",
"onkeydown",
"onkeypress",
"onkeyup",
"onmouseover",
"onload",
"onmouseup",
"onmousedown",
"onsubmit"
];
return !!input && !input.split('.').every(value => !~javascriptReservedWords.indexOf(value));
},
isValidTheme(input) {
const validThemeProperties = [
"themePrimary",
"themeLighterAlt",
"themeLighter",
"themeLight",
"themeTertiary",
"themeSecondary",
"themeDarkAlt",
"themeDark",
"themeDarker",
"neutralLighterAlt",
"neutralLighter",
"neutralLight",
"neutralQuaternaryAlt",
"neutralQuaternary",
"neutralTertiaryAlt",
"neutralTertiary",
"neutralSecondary",
"neutralPrimaryAlt",
"neutralPrimary",
"neutralDark",
"black",
"white"
];
let theme;
try {
theme = JSON.parse(input);
}
catch {
return false;
}
if (Array.isArray(theme)) {
return false;
}
const hasInvalidProperties = validThemeProperties.map((property) => {
return theme.hasOwnProperty(property);
}).includes(false);
if (hasInvalidProperties) {
return false;
}
const regex = new RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
const hasInvalidValues = validThemeProperties.map((property) => {
return regex.test(theme[property]);
}).includes(false);
if (hasInvalidValues) {
return false;
}
return true;
},
isValidSharePointUrl(url) {
if (typeof url !== 'string') {
return 'SharePoint Online site URL must be a string.';
}
if (url.indexOf('https://') !== 0) {
return `'${url}' is not a valid SharePoint Online site URL.`;
}
else {
return true;
}
},
isValidFormDigest(contextInfo) {
if (!contextInfo) {
return false;
}
const now = new Date();
if (contextInfo.FormDigestValue && now < contextInfo.FormDigestExpiresAt) {
return true;
}
return false;
},
isValidMailNickname(mailNickname) {
const mailNicknameRegEx = new RegExp(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*$/i);
return mailNicknameRegEx.test(mailNickname);
},
isValidISODuration(duration) {
const durationRegEx = new RegExp(/^P(?!$)((\d+Y)|(\d+\.\d+Y$))?((\d+M)|(\d+\.\d+M$))?((\d+W)|(\d+\.\d+W$))?((\d+D)|(\d+\.\d+D$))?(T(?=\d)((\d+H)|(\d+\.\d+H$))?((\d+M)|(\d+\.\d+M$))?(\d+(\.\d+)?S)?)??$/);
return durationRegEx.test(duration);
},
isValidPermission(permissions) {
const invalidPermissions = permissions
.split(' ')
.filter(permission => permission.indexOf('/') < 0);
return invalidPermissions.length > 0 ? invalidPermissions : true;
},
isValidPowerPagesUrl(url) {
const powerPagesUrlPattern = /^https:\/\/[a-zA-Z0-9-]+\.powerappsportals\.com$/;
return powerPagesUrlPattern.test(url);
}
};
//# sourceMappingURL=validation.js.map