diff --git a/package-lock.json b/package-lock.json index 8a3aa3554f754..1f040edd235e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25713,6 +25713,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", + "dev": true + }, "ua-parser-js": { "version": "0.7.18", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", diff --git a/package.json b/package.json index 46ebf924d604a..80da4126e0d7e 100644 --- a/package.json +++ b/package.json @@ -139,6 +139,7 @@ "source-map-loader": "0.2.4", "sprintf-js": "1.1.1", "stylelint-config-wordpress": "13.1.0", + "typescript": "3.5.3", "uuid": "3.3.2", "webpack": "4.8.3", "worker-farm": "1.7.0" @@ -189,13 +190,14 @@ "fixtures:server-registered": "docker-compose run -w /var/www/html/wp-content/plugins/gutenberg --rm wordpress ./bin/get-server-blocks.php > test/integration/full-content/server-registered.json", "fixtures:generate": "npm run fixtures:server-registered && cross-env GENERATE_MISSING_FIXTURES=y npm run test-unit", "fixtures:regenerate": "npm run fixtures:clean && npm run fixtures:generate", - "lint": "concurrently \"npm run lint-js\" \"npm run lint-pkg-json\" \"npm run lint-css\"", + "lint": "concurrently \"npm run lint-js\" \"npm run lint-pkg-json\" \"npm run lint-css\" \"npm run lint-types\"", "lint-js": "wp-scripts lint-js", "lint-js:fix": "npm run lint-js -- --fix", "lint-php": "docker-compose run --rm composer run-script lint", "lint-pkg-json": "wp-scripts lint-pkg-json ./packages", "lint-css": "wp-scripts lint-style '**/*.scss'", "lint-css:fix": "npm run lint-css -- --fix", + "lint-types": "tsc", "package-plugin": "./bin/build-plugin-zip.sh", "pot-to-php": "./bin/pot-to-php.js", "precommit": "lint-staged", diff --git a/packages/url/README.md b/packages/url/README.md index cfc6286d715b5..5b381e074f48c 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -30,7 +30,7 @@ const newURL = addQueryArgs( 'https://google.com', { q: 'test' } ); // https://g _Parameters_ -- _url_ `?string`: URL to which arguments should be appended. If omitted, only the resulting querystring is returned. +- _url_ `[string]`: URL to which arguments should be appended. If omitted, only the resulting querystring is returned. - _args_ `Object`: Query arguments to apply to URL. _Returns_ @@ -72,7 +72,7 @@ _Parameters_ _Returns_ -- `?string`: The authority part of the URL. +- `(string|void)`: The authority part of the URL. # **getFragment** @@ -91,7 +91,7 @@ _Parameters_ _Returns_ -- `?string`: The fragment part of the URL. +- `(string|void)`: The fragment part of the URL. # **getPath** @@ -110,7 +110,7 @@ _Parameters_ _Returns_ -- `?string`: The path part of the URL. +- `(string|void)`: The path part of the URL. # **getProtocol** @@ -129,7 +129,7 @@ _Parameters_ _Returns_ -- `?string`: The protocol part of the URL. +- `(string|void)`: The protocol part of the URL. # **getQueryArg** @@ -143,12 +143,12 @@ const foo = getQueryArg( 'https://wordpress.org?foo=bar&bar=baz', 'foo' ); // ba _Parameters_ -- _url_ `string`: URL -- _arg_ `string`: Query arg name +- _url_ `string`: URL. +- _arg_ `string`: Query arg name. _Returns_ -- `(Array|string)`: Query arg value. +- `(QueryArgParsed|undefined)`: Query arg value. # **getQueryString** @@ -167,7 +167,7 @@ _Parameters_ _Returns_ -- `?string`: The query string part of the URL. +- `(string|void)`: The query string part of the URL. # **hasQueryArg** @@ -181,8 +181,8 @@ const hasBar = hasQueryArg( 'https://wordpress.org?foo=bar&bar=baz', 'bar' ); // _Parameters_ -- _url_ `string`: URL -- _arg_ `string`: Query arg name +- _url_ `string`: URL. +- _arg_ `string`: Query arg name. _Returns_ @@ -331,11 +331,11 @@ const actualURL = prependHTTP( 'wordpress.org' ); // http://wordpress.org _Parameters_ -- _url_ `string`: The URL to test +- _url_ `string`: The URL to test. _Returns_ -- `string`: The updated URL +- `string`: The updated URL. # **removeQueryArgs** @@ -349,12 +349,12 @@ const newUrl = removeQueryArgs( 'https://wordpress.org?foo=bar&bar=baz&baz=fooba _Parameters_ -- _url_ `string`: URL -- _args_ `...string`: Query Args +- _url_ `string`: URL. +- _args_ `...string`: Query Args. _Returns_ -- `string`: Updated URL +- `string`: Updated URL. # **safeDecodeURI** diff --git a/packages/url/src/index.js b/packages/url/src/index.js index 6cc606c9d546b..afbf1de9e7c16 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -7,6 +7,14 @@ const URL_REGEXP = /^(?:https?:)?\/\/\S+$/i; const EMAIL_REGEXP = /^(mailto:)?[a-z0-9._%+-]+@[a-z0-9][a-z0-9.-]*\.[a-z]{2,63}$/i; const USABLE_HREF_REGEXP = /^(?:[a-z]+:|#|\?|\.|\/)/i; +/** + * @typedef {{[key: string]: QueryArgParsed}} QueryArgObject + */ + +/** + * @typedef {string|string[]|QueryArgObject} QueryArgParsed + */ + /** * Determines whether the given string looks like a URL. * @@ -50,7 +58,7 @@ export function isEmail( email ) { * const protocol2 = getProtocol( 'https://wordpress.org' ); // 'https:' * ``` * - * @return {?string} The protocol part of the URL. + * @return {string|void} The protocol part of the URL. */ export function getProtocol( url ) { const matches = /^([^\s:]+:)/.exec( url ); @@ -90,7 +98,7 @@ export function isValidProtocol( protocol ) { * const authority2 = getAuthority( 'https://localhost:8080/test/' ); // 'localhost:8080' * ``` * - * @return {?string} The authority part of the URL. + * @return {string|void} The authority part of the URL. */ export function getAuthority( url ) { const matches = /^[^\/\s:]+:(?:\/\/)?\/?([^\/\s#?]+)[\/#?]{0,1}\S*$/.exec( url ); @@ -130,7 +138,7 @@ export function isValidAuthority( authority ) { * const path2 = getPath( 'https://wordpress.org/help/faq/' ); // 'help/faq' * ``` * - * @return {?string} The path part of the URL. + * @return {string|void} The path part of the URL. */ export function getPath( url ) { const matches = /^[^\/\s:]+:(?:\/\/)?[^\/\s#?]+[\/]([^\s#?]+)[#?]{0,1}\S*$/.exec( url ); @@ -170,7 +178,7 @@ export function isValidPath( path ) { * const queryString2 = getQueryString( 'https://wordpress.org#fragment?query=false&search=hello' ); // 'query=false&search=hello' * ``` * - * @return {?string} The query string part of the URL. + * @return {string|void} The query string part of the URL. */ export function getQueryString( url ) { const matches = /^\S+?\?([^\s#]+)/.exec( url ); @@ -210,7 +218,7 @@ export function isValidQueryString( queryString ) { * const fragment2 = getFragment( 'https://wordpress.org#another-fragment?query=true' ); // '#another-fragment' * ``` * - * @return {?string} The fragment part of the URL. + * @return {string|void} The fragment part of the URL. */ export function getFragment( url ) { const matches = /^\S+?(#[^\s\?]*)/.exec( url ); @@ -244,9 +252,9 @@ export function isValidFragment( fragment ) { * includes query arguments, the arguments are merged with (and take precedent * over) the existing set. * - * @param {?string} url URL to which arguments should be appended. If omitted, - * only the resulting querystring is returned. - * @param {Object} args Query arguments to apply to URL. + * @param {string} [url=''] URL to which arguments should be appended. If omitted, + * only the resulting querystring is returned. + * @param {Object} args Query arguments to apply to URL. * * @example * ```js @@ -282,15 +290,15 @@ export function addQueryArgs( url = '', args ) { /** * Returns a single query argument of the url * - * @param {string} url URL - * @param {string} arg Query arg name + * @param {string} url URL. + * @param {string} arg Query arg name. * * @example * ```js * const foo = getQueryArg( 'https://wordpress.org?foo=bar&bar=baz', 'foo' ); // bar * ``` * - * @return {Array|string} Query arg value. + * @return {QueryArgParsed|undefined} Query arg value. */ export function getQueryArg( url, arg ) { const queryStringIndex = url.indexOf( '?' ); @@ -302,8 +310,8 @@ export function getQueryArg( url, arg ) { /** * Determines whether the URL contains a given query arg. * - * @param {string} url URL - * @param {string} arg Query arg name + * @param {string} url URL. + * @param {string} arg Query arg name. * * @example * ```js @@ -319,15 +327,15 @@ export function hasQueryArg( url, arg ) { /** * Removes arguments from the query string of the url * - * @param {string} url URL - * @param {...string} args Query Args + * @param {string} url URL. + * @param {...string} args Query Args. * * @example * ```js * const newUrl = removeQueryArgs( 'https://wordpress.org?foo=bar&bar=baz&baz=foobar', 'foo', 'bar' ); // https://wordpress.org?baz=foobar * ``` * - * @return {string} Updated URL + * @return {string} Updated URL. */ export function removeQueryArgs( url, ...args ) { const queryStringIndex = url.indexOf( '?' ); @@ -342,14 +350,14 @@ export function removeQueryArgs( url, ...args ) { /** * Prepends "http://" to a url, if it looks like something that is meant to be a TLD. * - * @param {string} url The URL to test + * @param {string} url The URL to test. * * @example * ```js * const actualURL = prependHTTP( 'wordpress.org' ); // http://wordpress.org * ``` * - * @return {string} The updated URL + * @return {string} The updated URL. */ export function prependHTTP( url ) { if ( ! USABLE_HREF_REGEXP.test( url ) && ! EMAIL_REGEXP.test( url ) ) { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000000..cee321c53693e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "checkJs": true, + "jsx": "preserve", + "lib": ["dom", "esnext"], + "module": "commonjs", + "noEmit": true, + "resolveJsonModule": true, + "target": "esnext", + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */ + + /* Additional Checks */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + }, + "include": [ + "./packages/url/**/*.js" + ], + "exclude": [ + "./packages/**/test/**", + "./packages/**/build/**", + "./packages/**/build-module/**" + ] +}