Add existing to tracked

This commit is contained in:
Jay
2026-08-11 09:53:42 -04:00
parent afe07f3055
commit ffd6e3d73c
8531 changed files with 4396230 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
import { isAlphaNumericOrMarkChar } from '../char-utils';
/**
* A regular expression to match a 'mailto:' prefix on an email address.
*/
export declare const mailtoSchemePrefixRe: RegExp;
/**
* Determines if the given character may start the "local part" of an email
* address. The local part is the part to the left of the '@' sign.
*
* Technically according to the email spec, any of the characters in the
* {@link emailLocalPartCharRegex} can start an email address (including any of
* the special characters), but this is so rare in the wild and the
* implementation is much simpler by only starting an email address with a word
* character. This is especially important when matching the '{' character which
* generally starts a brace that isn't part of the email address.
*/
export declare const isEmailLocalPartStartChar: typeof isAlphaNumericOrMarkChar;
/**
* Determines if the given character can be part of the "local part" of an email
* address. The local part is the part to the left of the '@' sign.
*
* Checking for an email address's start char is handled with {@link #isEmailLocalPartStartChar}
*/
export declare function isEmailLocalPartChar(charCode: number): boolean;
/**
* Determines if the given email address is valid. We consider it valid if it
* has a valid TLD in its host.
*
* @param emailAddress email address
* @return true is email have valid TLD, false otherwise
*/
export declare function isValidEmail(emailAddress: string): boolean;
+39
View File
@@ -0,0 +1,39 @@
import { isAlphaNumericOrMarkChar, isValidEmailLocalPartSpecialChar } from '../char-utils';
import { isKnownTld } from './uri-utils';
/**
* A regular expression to match a 'mailto:' prefix on an email address.
*/
export var mailtoSchemePrefixRe = /^mailto:/i;
/**
* Determines if the given character may start the "local part" of an email
* address. The local part is the part to the left of the '@' sign.
*
* Technically according to the email spec, any of the characters in the
* {@link emailLocalPartCharRegex} can start an email address (including any of
* the special characters), but this is so rare in the wild and the
* implementation is much simpler by only starting an email address with a word
* character. This is especially important when matching the '{' character which
* generally starts a brace that isn't part of the email address.
*/
export var isEmailLocalPartStartChar = isAlphaNumericOrMarkChar; // alias for clarity
/**
* Determines if the given character can be part of the "local part" of an email
* address. The local part is the part to the left of the '@' sign.
*
* Checking for an email address's start char is handled with {@link #isEmailLocalPartStartChar}
*/
export function isEmailLocalPartChar(charCode) {
return isEmailLocalPartStartChar(charCode) || isValidEmailLocalPartSpecialChar(charCode);
}
/**
* Determines if the given email address is valid. We consider it valid if it
* has a valid TLD in its host.
*
* @param emailAddress email address
* @return true is email have valid TLD, false otherwise
*/
export function isValidEmail(emailAddress) {
var emailAddressTld = emailAddress.split('.').pop(); // as long as we have a valid string (as opposed to null or undefined), we will always get at least one element in the .split('.') array
return isKnownTld(emailAddressTld);
}
//# sourceMappingURL=email-utils.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"email-utils.js","sourceRoot":"","sources":["../../../src/parser/email-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,IAAM,oBAAoB,GAAG,WAAW,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,IAAM,yBAAyB,GAAG,wBAAwB,CAAC,CAAC,oBAAoB;AAEvF;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACjD,OAAO,yBAAyB,CAAC,QAAQ,CAAC,IAAI,gCAAgC,CAAC,QAAQ,CAAC,CAAC;AAC7F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB;IAC7C,IAAM,eAAe,GAAW,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,CAAC,wIAAwI;IAExM,OAAO,UAAU,CAAC,eAAe,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { isAlphaNumericOrMarkChar, isValidEmailLocalPartSpecialChar } from '../char-utils';\nimport { isKnownTld } from './uri-utils';\n\n/**\n * A regular expression to match a 'mailto:' prefix on an email address.\n */\nexport const mailtoSchemePrefixRe = /^mailto:/i;\n\n/**\n * Determines if the given character may start the \"local part\" of an email\n * address. The local part is the part to the left of the '@' sign.\n *\n * Technically according to the email spec, any of the characters in the\n * {@link emailLocalPartCharRegex} can start an email address (including any of\n * the special characters), but this is so rare in the wild and the\n * implementation is much simpler by only starting an email address with a word\n * character. This is especially important when matching the '{' character which\n * generally starts a brace that isn't part of the email address.\n */\nexport const isEmailLocalPartStartChar = isAlphaNumericOrMarkChar; // alias for clarity\n\n/**\n * Determines if the given character can be part of the \"local part\" of an email\n * address. The local part is the part to the left of the '@' sign.\n *\n * Checking for an email address's start char is handled with {@link #isEmailLocalPartStartChar}\n */\nexport function isEmailLocalPartChar(charCode: number): boolean {\n return isEmailLocalPartStartChar(charCode) || isValidEmailLocalPartSpecialChar(charCode);\n}\n\n/**\n * Determines if the given email address is valid. We consider it valid if it\n * has a valid TLD in its host.\n *\n * @param emailAddress email address\n * @return true is email have valid TLD, false otherwise\n */\nexport function isValidEmail(emailAddress: string): boolean {\n const emailAddressTld: string = emailAddress.split('.').pop()!; // as long as we have a valid string (as opposed to null or undefined), we will always get at least one element in the .split('.') array\n\n return isKnownTld(emailAddressTld);\n}\n"]}
+11
View File
@@ -0,0 +1,11 @@
/**
* Determines if the given `char` is a an allowed character in a hashtag. These
* are underscores or any alphanumeric char.
*/
export declare function isHashtagTextChar(charCode: number): boolean;
/**
* Determines if a hashtag match is valid.
*/
export declare function isValidHashtag(hashtag: string): boolean;
export type HashtagService = 'twitter' | 'facebook' | 'instagram' | 'tiktok' | 'youtube';
export declare const hashtagServices: HashtagService[];
+23
View File
@@ -0,0 +1,23 @@
import { isAlphaNumericOrMarkChar } from '../char-utils';
/**
* Determines if the given `char` is a an allowed character in a hashtag. These
* are underscores or any alphanumeric char.
*/
export function isHashtagTextChar(charCode) {
return charCode === 95 /* Char.Underscore */ || isAlphaNumericOrMarkChar(charCode);
}
/**
* Determines if a hashtag match is valid.
*/
export function isValidHashtag(hashtag) {
// Max length of 140 for a hashtag ('#' char + 139 word chars)
return hashtag.length <= 140;
}
export var hashtagServices = [
'twitter',
'facebook',
'instagram',
'tiktok',
'youtube',
];
//# sourceMappingURL=hashtag-utils.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"hashtag-utils.js","sourceRoot":"","sources":["../../../src/parser/hashtag-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAC9C,OAAO,QAAQ,6BAAoB,IAAI,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC1C,8DAA8D;IAC9D,OAAO,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;AACjC,CAAC;AAGD,MAAM,CAAC,IAAM,eAAe,GAAqB;IAC7C,SAAS;IACT,UAAU;IACV,WAAW;IACX,QAAQ;IACR,SAAS;CACZ,CAAC","sourcesContent":["import { Char } from '../char';\nimport { isAlphaNumericOrMarkChar } from '../char-utils';\n\n/**\n * Determines if the given `char` is a an allowed character in a hashtag. These\n * are underscores or any alphanumeric char.\n */\nexport function isHashtagTextChar(charCode: number): boolean {\n return charCode === Char.Underscore || isAlphaNumericOrMarkChar(charCode);\n}\n\n/**\n * Determines if a hashtag match is valid.\n */\nexport function isValidHashtag(hashtag: string): boolean {\n // Max length of 140 for a hashtag ('#' char + 139 word chars)\n return hashtag.length <= 140;\n}\n\nexport type HashtagService = 'twitter' | 'facebook' | 'instagram' | 'tiktok' | 'youtube';\nexport const hashtagServices: HashtagService[] = [\n 'twitter',\n 'facebook',\n 'instagram',\n 'tiktok',\n 'youtube',\n];\n"]}
+1
View File
@@ -0,0 +1 @@
export * from './parse-matches';
+2
View File
@@ -0,0 +1,2 @@
export * from './parse-matches';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/parser/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './parse-matches';\n"]}
+1
View File
@@ -0,0 +1 @@
export declare const tldRegex: RegExp;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+16
View File
@@ -0,0 +1,16 @@
/**
* Determines if the given character can be part of a mention's text characters.
*
* Accepts characters that match the RegExp `/[-\w.]/`, which are the possible
* mention characters for any service.
*
* We'll confirm the match based on the user-configured service name after the
* match is found.
*/
export declare function isMentionTextChar(charCode: number): boolean;
/**
* Determines if the given `mention` text is valid.
*/
export declare function isValidMention(mention: string, serviceName: MentionService): boolean;
export type MentionService = 'twitter' | 'instagram' | 'soundcloud' | 'tiktok' | 'youtube';
export declare const mentionServices: MentionService[];
+44
View File
@@ -0,0 +1,44 @@
import { isDigitChar, isAsciiLetterChar } from '../char-utils';
var mentionRegexes = {
twitter: /^@\w{1,15}$/,
instagram: /^@[_\w]{1,30}$/,
soundcloud: /^@[-a-z0-9_]{3,25}$/,
// TikTok usernames are 1-24 characters containing letters, numbers, underscores
// and periods, but cannot end in a period: https://support.tiktok.com/en/getting-started/setting-up-your-profile/changing-your-username
tiktok: /^@[.\w]{1,23}[\w]$/,
// Youtube usernames are 3-30 characters containing letters, numbers, underscores,
// dashes, or latin middle dots ('·').
// https://support.google.com/youtube/answer/11585688?hl=en&co=GENIE.Platform%3DAndroid#tns
youtube: /^@[-.·\w]{3,30}$/,
};
/**
* Determines if the given character can be part of a mention's text characters.
*
* Accepts characters that match the RegExp `/[-\w.]/`, which are the possible
* mention characters for any service.
*
* We'll confirm the match based on the user-configured service name after the
* match is found.
*/
export function isMentionTextChar(charCode) {
return (charCode === 45 /* Char.Dash */ || // '-'
charCode === 46 /* Char.Dot */ || // '.'
charCode === 95 /* Char.Underscore */ || // '_'
isAsciiLetterChar(charCode) ||
isDigitChar(charCode));
}
/**
* Determines if the given `mention` text is valid.
*/
export function isValidMention(mention, serviceName) {
var re = mentionRegexes[serviceName];
return re.test(mention);
}
export var mentionServices = [
'twitter',
'instagram',
'soundcloud',
'tiktok',
'youtube',
];
//# sourceMappingURL=mention-utils.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"mention-utils.js","sourceRoot":"","sources":["../../../src/parser/mention-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE/D,IAAM,cAAc,GAAgD;IAChE,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,gBAAgB;IAC3B,UAAU,EAAE,qBAAqB;IAEjC,gFAAgF;IAChF,wIAAwI;IACxI,MAAM,EAAE,oBAAoB;IAE5B,kFAAkF;IAClF,sCAAsC;IACtC,2FAA2F;IAC3F,OAAO,EAAE,kBAAkB;CAC9B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAC9C,OAAO,CACH,QAAQ,uBAAc,IAAI,MAAM;QAChC,QAAQ,sBAAa,IAAI,MAAM;QAC/B,QAAQ,6BAAoB,IAAI,MAAM;QACtC,iBAAiB,CAAC,QAAQ,CAAC;QAC3B,WAAW,CAAC,QAAQ,CAAC,CACxB,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,WAA2B;IACvE,IAAM,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAEvC,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAGD,MAAM,CAAC,IAAM,eAAe,GAAqB;IAC7C,SAAS;IACT,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,SAAS;CACZ,CAAC","sourcesContent":["import { Char } from '../char';\nimport { isDigitChar, isAsciiLetterChar } from '../char-utils';\n\nconst mentionRegexes: { [serviceName in MentionService]: RegExp } = {\n twitter: /^@\\w{1,15}$/,\n instagram: /^@[_\\w]{1,30}$/,\n soundcloud: /^@[-a-z0-9_]{3,25}$/,\n\n // TikTok usernames are 1-24 characters containing letters, numbers, underscores\n // and periods, but cannot end in a period: https://support.tiktok.com/en/getting-started/setting-up-your-profile/changing-your-username\n tiktok: /^@[.\\w]{1,23}[\\w]$/,\n\n // Youtube usernames are 3-30 characters containing letters, numbers, underscores,\n // dashes, or latin middle dots ('·').\n // https://support.google.com/youtube/answer/11585688?hl=en&co=GENIE.Platform%3DAndroid#tns\n youtube: /^@[-.·\\w]{3,30}$/,\n};\n\n/**\n * Determines if the given character can be part of a mention's text characters.\n *\n * Accepts characters that match the RegExp `/[-\\w.]/`, which are the possible\n * mention characters for any service.\n *\n * We'll confirm the match based on the user-configured service name after the\n * match is found.\n */\nexport function isMentionTextChar(charCode: number): boolean {\n return (\n charCode === Char.Dash || // '-'\n charCode === Char.Dot || // '.'\n charCode === Char.Underscore || // '_'\n isAsciiLetterChar(charCode) ||\n isDigitChar(charCode)\n );\n}\n\n/**\n * Determines if the given `mention` text is valid.\n */\nexport function isValidMention(mention: string, serviceName: MentionService): boolean {\n const re = mentionRegexes[serviceName];\n\n return re.test(mention);\n}\n\nexport type MentionService = 'twitter' | 'instagram' | 'soundcloud' | 'tiktok' | 'youtube';\nexport const mentionServices: MentionService[] = [\n 'twitter',\n 'instagram',\n 'soundcloud',\n 'tiktok',\n 'youtube',\n];\n"]}
+48
View File
@@ -0,0 +1,48 @@
import { Match } from '../match/match';
import { HashtagService } from './hashtag-utils';
import { MentionService } from './mention-utils';
import { AnchorTagBuilder } from '../anchor-tag-builder';
import type { StripPrefixConfigObj } from '../autolinker';
/**
* Parses URL, email, twitter, mention, and hashtag matches from the given
* `text`.
*/
export declare function parseMatches(text: string, args: ParseMatchesArgs): Match[];
export interface ParseMatchesArgs {
tagBuilder: AnchorTagBuilder;
stripPrefix: Required<StripPrefixConfigObj>;
stripTrailingSlash: boolean;
decodePercentEncoding: boolean;
hashtagServiceName: HashtagService;
mentionServiceName: MentionService;
}
/**
* Determines if a match found has unmatched closing parenthesis,
* square brackets or curly brackets. If so, these unbalanced symbol(s) will be
* removed from the URL match itself.
*
* A match may have an extra closing parenthesis/square brackets/curly brackets
* at the end of the match because these are valid URL path characters. For
* example, "wikipedia.com/something_(disambiguation)" should be auto-linked.
*
* However, an extra parenthesis *will* be included when the URL itself is
* wrapped in parenthesis, such as in the case of:
*
* "(wikipedia.com/something_(disambiguation))"
*
* In this case, the last closing parenthesis should *not* be part of the
* URL itself, and this method will exclude it from the returned URL.
*
* For square brackets in URLs such as in PHP arrays, the same behavior as
* parenthesis discussed above should happen:
*
* "[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]"
*
* The very last closing square bracket should not be part of the URL itself,
* and therefore this method will remove it.
*
* @param matchedText The full matched URL/email/hashtag/etc. from the state
* machine parser.
* @return The updated matched text with extraneous suffix characters removed.
*/
export declare function excludeUnbalancedTrailingBracesAndPunctuation(matchedText: string): string;
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
/**
* Determines if the character is a phone number separator character (i.e.
* '-', '.', or ' ' (space))
*/
export declare function isPhoneNumberSeparatorChar(charCode: number): boolean;
/**
* Determines if the character is a control character in a phone number. Control
* characters are as follows:
*
* - ',': A 1 second pause. Useful for dialing extensions once the main phone number has been reached
* - ';': A "wait" that waits for the user to take action (tap something, for instance on a smart phone)
*/
export declare function isPhoneNumberControlChar(charCode: number): boolean;
/**
* Determines if the given phone number text found in a string is a valid phone
* number.
*
* Our state machine parser is simplified to grab anything that looks like a
* phone number, and this function confirms the match.
*/
export declare function isValidPhoneNumber(phoneNumberText: string): boolean;
+52
View File
@@ -0,0 +1,52 @@
// Regex that specifies any delimiter char that allows us to treat the number as
// a phone number rather than just any other number that could appear in text.
var hasDelimCharsRe = /[-. ()]/;
// Over the years, many people have added to this regex, but it should have been
// split up by country. Maybe one day we can break this down.
var mostPhoneNumbers = /(?:(?:(?:(\+)?\d{1,3}[-. ]?)?\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-. ]?(?:\d[-. ]?){6,12}\d+))([,;]+[0-9]+#?)*/;
// Regex for Japanese phone numbers
var japanesePhoneRe = /(0([1-9]-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/;
// Combined regex
var validPhoneNumberRe = new RegExp("^".concat(mostPhoneNumbers.source, "|").concat(japanesePhoneRe.source, "$"));
/**
* Determines if the character is a phone number separator character (i.e.
* '-', '.', or ' ' (space))
*/
export function isPhoneNumberSeparatorChar(charCode) {
return (charCode === 45 /* Char.Dash */ || // '-'
charCode === 46 /* Char.Dot */ || // '.'
charCode === 32 /* Char.Space */ // ' '
);
}
/**
* Determines if the character is a control character in a phone number. Control
* characters are as follows:
*
* - ',': A 1 second pause. Useful for dialing extensions once the main phone number has been reached
* - ';': A "wait" that waits for the user to take action (tap something, for instance on a smart phone)
*/
export function isPhoneNumberControlChar(charCode) {
return (charCode === 44 /* Char.Comma */ || // ','
charCode === 59 /* Char.SemiColon */ // ';'
);
}
/**
* Determines if the given phone number text found in a string is a valid phone
* number.
*
* Our state machine parser is simplified to grab anything that looks like a
* phone number, and this function confirms the match.
*/
export function isValidPhoneNumber(phoneNumberText) {
// We'll only consider the match as a phone number if there is some kind of
// delimiter character (a prefixed '+' sign, or separator chars).
//
// Accepts:
// (123) 456-7890
// +38755233976
// Does not accept:
// 1234567890 (no delimiter chars - may just be a random number that's not a phone number)
var hasDelimiters = phoneNumberText.charAt(0) === '+' || hasDelimCharsRe.test(phoneNumberText);
return hasDelimiters && validPhoneNumberRe.test(phoneNumberText);
}
//# sourceMappingURL=phone-number-utils.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"phone-number-utils.js","sourceRoot":"","sources":["../../../src/parser/phone-number-utils.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAIhF,8EAA8E;AAC9E,IAAM,eAAe,GAAG,SAAS,CAAC;AAElC,gFAAgF;AAChF,6DAA6D;AAC7D,IAAM,gBAAgB,GAClB,uQAAuQ,CAAC;AAE5Q,mCAAmC;AACnC,IAAM,eAAe,GACjB,iIAAiI,CAAC;AAEtI,iBAAiB;AACjB,IAAM,kBAAkB,GAAG,IAAI,MAAM,CAAC,WAAI,gBAAgB,CAAC,MAAM,cAAI,eAAe,CAAC,MAAM,MAAG,CAAC,CAAC;AAEhG;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACvD,OAAO,CACH,QAAQ,uBAAc,IAAI,MAAM;QAChC,QAAQ,sBAAa,IAAI,MAAM;QAC/B,QAAQ,wBAAe,CAAC,MAAM;KACjC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACrD,OAAO,CACH,QAAQ,wBAAe,IAAI,MAAM;QACjC,QAAQ,4BAAmB,CAAC,MAAM;KACrC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,eAAuB;IACtD,2EAA2E;IAC3E,iEAAiE;IACjE,EAAE;IACF,WAAW;IACX,qBAAqB;IACrB,mBAAmB;IACnB,mBAAmB;IACnB,+FAA+F;IAC/F,IAAM,aAAa,GACf,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE/E,OAAO,aAAa,IAAI,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AACrE,CAAC","sourcesContent":["// Regex that specifies any delimiter char that allows us to treat the number as\n\nimport { Char } from '../char';\n\n// a phone number rather than just any other number that could appear in text.\nconst hasDelimCharsRe = /[-. ()]/;\n\n// Over the years, many people have added to this regex, but it should have been\n// split up by country. Maybe one day we can break this down.\nconst mostPhoneNumbers =\n /(?:(?:(?:(\\+)?\\d{1,3}[-. ]?)?\\(?\\d{3}\\)?[-. ]?\\d{3}[-. ]?\\d{4})|(?:(\\+)(?:9[976]\\d|8[987530]\\d|6[987]\\d|5[90]\\d|42\\d|3[875]\\d|2[98654321]\\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-. ]?(?:\\d[-. ]?){6,12}\\d+))([,;]+[0-9]+#?)*/;\n\n// Regex for Japanese phone numbers\nconst japanesePhoneRe =\n /(0([1-9]-?[1-9]\\d{3}|[1-9]{2}-?\\d{3}|[1-9]{2}\\d{1}-?\\d{2}|[1-9]{2}\\d{2}-?\\d{1})-?\\d{4}|0[789]0-?\\d{4}-?\\d{4}|050-?\\d{4}-?\\d{4})/;\n\n// Combined regex\nconst validPhoneNumberRe = new RegExp(`^${mostPhoneNumbers.source}|${japanesePhoneRe.source}$`);\n\n/**\n * Determines if the character is a phone number separator character (i.e.\n * '-', '.', or ' ' (space))\n */\nexport function isPhoneNumberSeparatorChar(charCode: number): boolean {\n return (\n charCode === Char.Dash || // '-'\n charCode === Char.Dot || // '.'\n charCode === Char.Space // ' '\n );\n}\n\n/**\n * Determines if the character is a control character in a phone number. Control\n * characters are as follows:\n *\n * - ',': A 1 second pause. Useful for dialing extensions once the main phone number has been reached\n * - ';': A \"wait\" that waits for the user to take action (tap something, for instance on a smart phone)\n */\nexport function isPhoneNumberControlChar(charCode: number): boolean {\n return (\n charCode === Char.Comma || // ','\n charCode === Char.SemiColon // ';'\n );\n}\n\n/**\n * Determines if the given phone number text found in a string is a valid phone\n * number.\n *\n * Our state machine parser is simplified to grab anything that looks like a\n * phone number, and this function confirms the match.\n */\nexport function isValidPhoneNumber(phoneNumberText: string): boolean {\n // We'll only consider the match as a phone number if there is some kind of\n // delimiter character (a prefixed '+' sign, or separator chars).\n //\n // Accepts:\n // (123) 456-7890\n // +38755233976\n // Does not accept:\n // 1234567890 (no delimiter chars - may just be a random number that's not a phone number)\n const hasDelimiters =\n phoneNumberText.charAt(0) === '+' || hasDelimCharsRe.test(phoneNumberText);\n\n return hasDelimiters && validPhoneNumberRe.test(phoneNumberText);\n}\n"]}
+82
View File
@@ -0,0 +1,82 @@
/**
* Regular expression to match an http:// or https:// scheme.
*/
export declare const httpSchemeRe: RegExp;
/**
* Regular expression to match an http:// or https:// scheme as the prefix of
* a string.
*/
export declare const httpSchemePrefixRe: RegExp;
/**
* A regular expression used to determine the schemes we should not autolink
*/
export declare const invalidSchemeRe: RegExp;
export declare const schemeUrlRe: RegExp;
export declare const tldUrlHostRe: RegExp;
/**
* Determines if the given character code represents a character that may start
* a scheme (ex: the 'h' in 'http')
*/
export declare const isSchemeStartChar: (code: number) => boolean;
/**
* Determines if the given character is a valid character in a scheme (such as
* 'http' or 'ssh+git'), but only after the start char (which is handled by
* {@link isSchemeStartChar}.
*/
export declare function isSchemeChar(charCode: number): boolean;
/**
* Determines if the character can begin a domain label, which must be an
* alphanumeric character and not an underscore or dash.
*
* A domain label is a segment of a hostname such as subdomain.google.com.
*/
export declare const isDomainLabelStartChar: (charCode: number) => boolean;
/**
* Determines if the character is part of a domain label (but not a domain label
* start character).
*
* A domain label is a segment of a hostname such as subdomain.google.com.
*/
export declare function isDomainLabelChar(charCode: number): boolean;
/**
* Determines if the character is a path character ("pchar") as defined by
* https://tools.ietf.org/html/rfc3986#appendix-A
*
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*
* Note that this implementation doesn't follow the spec exactly, but rather
* follows URL path characters found out in the wild (spec might be out of date?)
*/
export declare function isPathChar(charCode: number): boolean;
/**
* Determines if the character given may begin the "URL Suffix" section of a
* URI (i.e. the path, query, or hash section). These are the '/', '?' and '#'
* characters.
*
* See https://tools.ietf.org/html/rfc3986#appendix-A
*/
export declare function isUrlSuffixStartChar(charCode: number): boolean;
/**
* Determines if the top-level domain (TLD) read in the host is a known TLD.
*
* Example: 'com' would be a known TLD (for a host of 'google.com'), but
* 'local' would not (for a domain name of 'my-computer.local').
*/
export declare function isKnownTld(tld: string): boolean;
/**
* Determines if the given `url` is a valid scheme-prefixed URL.
*/
export declare function isValidSchemeUrl(url: string): boolean;
/**
* Determines if the given `url` is a match with a valid TLD.
*/
export declare function isValidTldMatch(url: string): boolean;
/**
* Determines if the given URL is a valid IPv4-prefixed URL.
*/
export declare function isValidIpV4Address(url: string): boolean;
+189
View File
@@ -0,0 +1,189 @@
import { isDigitChar, isAsciiLetterChar, isAlphaNumericOrMarkChar, isUrlSuffixAllowedSpecialChar, isUrlSuffixNotAllowedAsFinalChar, } from '../char-utils';
import { tldRegex } from './known-tlds';
/**
* Regular expression to match an http:// or https:// scheme.
*/
export var httpSchemeRe = /https?:\/\//i;
/**
* Regular expression to match an http:// or https:// scheme as the prefix of
* a string.
*/
export var httpSchemePrefixRe = new RegExp('^' + httpSchemeRe.source, 'i');
/**
* A regular expression used to determine the schemes we should not autolink
*/
export var invalidSchemeRe = /^(javascript|vbscript):/i;
// A regular expression used to determine if the URL is a scheme match (such as
// 'http://google.com', and as opposed to a "TLD match"). This regular
// expression is used to parse out the host along with if the URL has an
// authority component (i.e. '//')
//
// Capturing groups:
// 1. '//' if the URL has an authority component, empty string otherwise
// 2. The host (if one exists). Ex: 'google.com'
//
// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology
export var schemeUrlRe = /^[A-Za-z][-.+A-Za-z0-9]*:(\/\/)?([^:/]*)/;
// A regular expression used to determine if the URL is a TLD match (such as
// 'google.com', and as opposed to a "scheme match"). This regular
// expression is used to help parse out the TLD (top-level domain) of the host.
//
// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology
export var tldUrlHostRe = /^(?:\/\/)?([^/#?:]+)/; // optionally prefixed with protocol-relative '//' chars
/**
* Determines if the given character code represents a character that may start
* a scheme (ex: the 'h' in 'http')
*/
export var isSchemeStartChar = isAsciiLetterChar; // Equivalent to checking the RegExp `/[A-Za-z]/`, but aliased for clarity and maintainability
/**
* Determines if the given character is a valid character in a scheme (such as
* 'http' or 'ssh+git'), but only after the start char (which is handled by
* {@link isSchemeStartChar}.
*/
export function isSchemeChar(charCode) {
return (isAsciiLetterChar(charCode) ||
isDigitChar(charCode) ||
charCode === 43 /* Char.Plus */ || // '+'
charCode === 45 /* Char.Dash */ || // '-'
charCode === 46 /* Char.Dot */ // '.'
);
}
/**
* Determines if the character can begin a domain label, which must be an
* alphanumeric character and not an underscore or dash.
*
* A domain label is a segment of a hostname such as subdomain.google.com.
*/
export var isDomainLabelStartChar = isAlphaNumericOrMarkChar; // alias function for clarity
/**
* Determines if the character is part of a domain label (but not a domain label
* start character).
*
* A domain label is a segment of a hostname such as subdomain.google.com.
*/
export function isDomainLabelChar(charCode) {
return charCode === 95 /* Char.Underscore */ || isDomainLabelStartChar(charCode);
}
/**
* Determines if the character is a path character ("pchar") as defined by
* https://tools.ietf.org/html/rfc3986#appendix-A
*
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*
* Note that this implementation doesn't follow the spec exactly, but rather
* follows URL path characters found out in the wild (spec might be out of date?)
*/
export function isPathChar(charCode) {
return (isAlphaNumericOrMarkChar(charCode) ||
isUrlSuffixAllowedSpecialChar(charCode) ||
isUrlSuffixNotAllowedAsFinalChar(charCode) // characters in addition to those allowed by isUrlSuffixAllowedSpecialChar()
);
}
/**
* Determines if the character given may begin the "URL Suffix" section of a
* URI (i.e. the path, query, or hash section). These are the '/', '?' and '#'
* characters.
*
* See https://tools.ietf.org/html/rfc3986#appendix-A
*/
export function isUrlSuffixStartChar(charCode) {
return (charCode === 47 /* Char.Slash */ || // '/'
charCode === 63 /* Char.Question */ || // '?'
charCode === 35 /* Char.NumberSign */ // '#'
);
}
/**
* Determines if the top-level domain (TLD) read in the host is a known TLD.
*
* Example: 'com' would be a known TLD (for a host of 'google.com'), but
* 'local' would not (for a domain name of 'my-computer.local').
*/
export function isKnownTld(tld) {
return tldRegex.test(tld.toLowerCase()); // make sure the tld is lowercase for the regex
}
/**
* Determines if the given `url` is a valid scheme-prefixed URL.
*/
export function isValidSchemeUrl(url) {
// If the scheme is 'javascript:' or 'vbscript:', these link
// types can be dangerous. Don't link them.
if (invalidSchemeRe.test(url)) {
return false;
}
var schemeMatch = url.match(schemeUrlRe);
if (!schemeMatch) {
return false;
}
var isAuthorityMatch = !!schemeMatch[1];
var host = schemeMatch[2];
if (isAuthorityMatch) {
// Any match that has an authority ('//' chars) after the scheme is
// valid, such as 'http://anything'
return true;
}
// If there's no authority ('//' chars), check that we have a hostname
// that looks valid.
//
// The host must contain at least one '.' char and have a domain label
// with at least one letter to be considered valid.
//
// Accept:
// - git:domain.com (scheme followed by a host
// Do not accept:
// - git:something ('something' doesn't look like a host)
// - version:1.0 ('1.0' doesn't look like a host)
if (host.indexOf('.') === -1 || !/[A-Za-z]/.test(host)) {
// `letterRe` RegExp checks for a letter anywhere in the host string
return false;
}
return true;
}
/**
* Determines if the given `url` is a match with a valid TLD.
*/
export function isValidTldMatch(url) {
// TLD URL such as 'google.com', we need to confirm that we have a valid
// top-level domain
var tldUrlHostMatch = url.match(tldUrlHostRe);
if (!tldUrlHostMatch) {
// At this point, if the URL didn't match our TLD re, it must be invalid
// (highly unlikely to happen, but just in case)
return false;
}
var host = tldUrlHostMatch[0];
var hostLabels = host.split('.');
if (hostLabels.length < 2) {
// 0 or 1 host label, there's no TLD. Ex: 'localhost'
return false;
}
var tld = hostLabels[hostLabels.length - 1];
if (!isKnownTld(tld)) {
return false;
}
// TODO: Implement these conditions for TLD matcher:
// (
// this.longestDomainLabelLength <= 63 &&
// this.domainNameLength <= 255
// );
return true;
}
// Regular expression to confirm a valid IPv4 address (ex: '192.168.0.1')
// TODO: encode this into the state machine so that we don't need to run this
// regexp separately to confirm the match
var ipV4Re = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
// Regular expression used to split the IPv4 address itself from any port/path/query/hash
var ipV4PartRe = /[:/?#]/;
/**
* Determines if the given URL is a valid IPv4-prefixed URL.
*/
export function isValidIpV4Address(url) {
// Grab just the IP address
var ipV4Part = url.split(ipV4PartRe, 1)[0]; // only 1 result needed
return ipV4Re.test(ipV4Part);
}
//# sourceMappingURL=uri-utils.js.map
File diff suppressed because one or more lines are too long