UNPKG

11.4 kBSource Map (JSON)View Raw
1{"version":3,"file":"StringChecks.js","sourceRoot":"","sources":["../../src/parser/StringChecks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Helpers for validating various text string formats.\r\n */\r\nexport class StringChecks {\r\n private static readonly _tsdocTagNameRegExp: RegExp = /^@[a-z][a-z0-9]*$/i;\r\n\r\n private static readonly _urlSchemeRegExp: RegExp = /^[a-z][a-z0-9]*\\:\\/\\//i;\r\n private static readonly _urlSchemeAfterRegExp: RegExp = /^[a-z][a-z0-9]*\\:\\/\\/./i;\r\n\r\n // HTML element definitions:\r\n // https://spec.commonmark.org/0.29/#tag-name\r\n // https://www.w3.org/TR/html5/syntax.html#tag-name\r\n // https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name\r\n //\r\n // We use the CommonMark spec:\r\n // \"A tag name consists of an ASCII letter followed by zero or more ASCII letters, digits, or hyphens (-).\"\r\n private static readonly _htmlNameRegExp: RegExp = /^[a-z]+[a-z0-9\\-]*$/i;\r\n\r\n // Note: In addition to letters, numbers, underscores, and dollar signs, modern ECMAScript\r\n // also allows Unicode categories such as letters, combining marks, digits, and connector punctuation.\r\n // These are mostly supported in all environments except IE11, so if someone wants it, we would accept\r\n // a PR to allow them (although the test surface might be somewhat large).\r\n private static readonly _identifierBadCharRegExp: RegExp = /[^a-z0-9_$]/i;\r\n\r\n // Identifiers most not start with a number.\r\n private static readonly _identifierNumberStartRegExp: RegExp = /^[0-9]/;\r\n\r\n // For detailed notes about NPM package name syntax, see:\r\n // tslint:disable-next-line:max-line-length\r\n // https://github.com/Microsoft/web-build-tools/blob/a417ca25c63aca31dba43a34d39cc9cd529b9c78/libraries/node-core-library/src/PackageName.ts\r\n private static readonly _validPackageNameRegExp: RegExp = /^(?:@[a-z0-9\\-_\\.]+\\/)?[a-z0-9\\-_\\.]+$/i;\r\n\r\n private static readonly _systemSelectors: Set<string> = new Set<string>([\r\n // For classes:\r\n 'instance',\r\n 'static',\r\n 'constructor',\r\n\r\n // For merged declarations:\r\n 'class',\r\n 'enum',\r\n 'function',\r\n 'interface',\r\n 'namespace',\r\n 'type',\r\n 'variable'\r\n ]);\r\n\r\n /**\r\n * Tests whether the input string is a valid TSDoc tag name; if not, returns an error message.\r\n * TSDoc tag names start with an at-sign (\"@\") followed by ASCII letters using\r\n * \"camelCase\" capitalization.\r\n */\r\n public static explainIfInvalidTSDocTagName(tagName: string): string | undefined {\r\n if (tagName[0] !== '@') {\r\n return 'A TSDoc tag name must start with an \"@\" symbol';\r\n }\r\n\r\n if (!StringChecks._tsdocTagNameRegExp.test(tagName)) {\r\n return 'A TSDoc tag name must start with a letter and contain only letters and numbers';\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Throws an exception if the input string is not a valid TSDoc tag name.\r\n * TSDoc tag names start with an at-sign (\"@\") followed by ASCII letters using\r\n * \"camelCase\" capitalization.\r\n */\r\n public static validateTSDocTagName(tagName: string): void {\r\n const explanation: string | undefined = StringChecks.explainIfInvalidTSDocTagName(tagName);\r\n if (explanation) {\r\n throw new Error(explanation);\r\n }\r\n }\r\n\r\n /**\r\n * Tests whether the input string is a URL form supported inside an \"@link\" tag; if not,\r\n * returns an error message.\r\n */\r\n public static explainIfInvalidLinkUrl(url: string): string | undefined {\r\n if (url.length === 0) {\r\n return 'The URL cannot be empty';\r\n }\r\n if (!StringChecks._urlSchemeRegExp.test(url)) {\r\n return (\r\n 'An @link URL must begin with a scheme comprised only of letters and numbers followed by \"://\".' +\r\n ' (For general URLs, use an HTML \"<a>\" tag instead.)'\r\n );\r\n }\r\n if (!StringChecks._urlSchemeAfterRegExp.test(url)) {\r\n return 'An @link URL must have at least one character after \"://\"';\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Tests whether the input string is a valid HTML element or attribute name.\r\n */\r\n public static explainIfInvalidHtmlName(htmlName: string): string | undefined {\r\n if (!StringChecks._htmlNameRegExp.test(htmlName)) {\r\n return 'An HTML name must be an ASCII letter followed by zero or more letters, digits, or hyphens';\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Throws an exception if the input string is a not valid HTML element or attribute name.\r\n */\r\n public static validateHtmlName(htmlName: string): void {\r\n const explanation: string | undefined = StringChecks.explainIfInvalidHtmlName(htmlName);\r\n if (explanation) {\r\n throw new Error(explanation);\r\n }\r\n }\r\n\r\n /**\r\n * Tests whether the input string is a valid NPM package name.\r\n */\r\n public static explainIfInvalidPackageName(packageName: string): string | undefined {\r\n if (packageName.length === 0) {\r\n return 'The package name cannot be an empty string';\r\n }\r\n\r\n if (!StringChecks._validPackageNameRegExp.test(packageName)) {\r\n return `The package name ${JSON.stringify(packageName)} is not a valid package name`;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Tests whether the input string is a valid declaration reference import path.\r\n */\r\n public static explainIfInvalidImportPath(\r\n importPath: string,\r\n prefixedByPackageName: boolean\r\n ): string | undefined {\r\n if (importPath.length > 0) {\r\n if (importPath.indexOf('//') >= 0) {\r\n return 'An import path must not contain \"//\"';\r\n }\r\n if (importPath[importPath.length - 1] === '/') {\r\n return 'An import path must not end with \"/\"';\r\n }\r\n\r\n if (!prefixedByPackageName) {\r\n if (importPath[0] === '/') {\r\n return 'An import path must not start with \"/\" unless prefixed by a package name';\r\n }\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Returns true if the input string is a TSDoc system selector.\r\n */\r\n public static isSystemSelector(selector: string): boolean {\r\n return StringChecks._systemSelectors.has(selector);\r\n }\r\n\r\n /**\r\n * Tests whether the input string is a valid ECMAScript identifier.\r\n * A precise check is extremely complicated and highly dependent on the standard version\r\n * and how faithfully the interpreter implements it, so here we use a conservative heuristic.\r\n */\r\n public static explainIfInvalidUnquotedIdentifier(identifier: string): string | undefined {\r\n if (identifier.length === 0) {\r\n return 'The identifier cannot be an empty string';\r\n }\r\n\r\n if (StringChecks._identifierBadCharRegExp.test(identifier)) {\r\n return 'The identifier cannot non-word characters';\r\n }\r\n\r\n if (StringChecks._identifierNumberStartRegExp.test(identifier)) {\r\n return 'The identifier must not start with a number';\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Tests whether the input string can be used without quotes as a member identifier in a declaration reference.\r\n * If not, it should be enclosed in quotes.\r\n */\r\n public static explainIfInvalidUnquotedMemberIdentifier(identifier: string): string | undefined {\r\n const explanation: string | undefined = StringChecks.explainIfInvalidUnquotedIdentifier(identifier);\r\n if (explanation !== undefined) {\r\n return explanation;\r\n }\r\n\r\n if (StringChecks.isSystemSelector(identifier)) {\r\n // We do this to avoid confusion about the declaration reference syntax rules.\r\n // For example if someone were to see \"MyClass.(static:instance)\" it would be unclear which\r\n // side the colon is the selector.\r\n return `The identifier \"${identifier}\" must be quoted because it is a TSDoc system selector name`;\r\n }\r\n\r\n return undefined;\r\n }\r\n}\r\n"]}
\No newline at end of file