From 92b3a4fc9bfb76a7cf28ee692db3af11ca38fea0 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Mon, 29 Jul 2019 23:44:40 -0400 Subject: [PATCH] chore(ts): Convert src/sentry/static/sentry/app/utils.jsx to typescript --- src/sentry/static/sentry/app/types/index.tsx | 2 + .../sentry/app/{utils.jsx => utils.tsx} | 82 ++++++++++--------- 2 files changed, 44 insertions(+), 40 deletions(-) rename src/sentry/static/sentry/app/{utils.jsx => utils.tsx} (69%) diff --git a/src/sentry/static/sentry/app/types/index.tsx b/src/sentry/static/sentry/app/types/index.tsx index 14944bfa4945fc..4b26db967337b1 100644 --- a/src/sentry/static/sentry/app/types/index.tsx +++ b/src/sentry/static/sentry/app/types/index.tsx @@ -12,6 +12,8 @@ export type Project = { isMember: boolean; teams: Team[]; features: string[]; + + isBookmarked: boolean; }; export type Team = { diff --git a/src/sentry/static/sentry/app/utils.jsx b/src/sentry/static/sentry/app/utils.tsx similarity index 69% rename from src/sentry/static/sentry/app/utils.jsx rename to src/sentry/static/sentry/app/utils.tsx index 0dda3c1a3c3a20..0645d28be85f15 100644 --- a/src/sentry/static/sentry/app/utils.jsx +++ b/src/sentry/static/sentry/app/utils.tsx @@ -1,6 +1,7 @@ import _ from 'lodash'; +import {Project} from 'app/types/index'; -function arrayIsEqual(arr, other, deep) { +function arrayIsEqual(arr?: any[], other?: any[], deep?: boolean): boolean { // if the other array is a falsy value, return if (!arr && !other) { return true; @@ -18,7 +19,7 @@ function arrayIsEqual(arr, other, deep) { return arr.every((val, idx) => valueIsEqual(val, other[idx], deep)); } -export function valueIsEqual(value, other, deep) { +export function valueIsEqual(value?: any, other?: any, deep?: boolean): boolean { if (value === other) { return true; } else if (_.isArray(value) || _.isArray(other)) { @@ -33,8 +34,8 @@ export function valueIsEqual(value, other, deep) { return false; } -function objectMatchesSubset(obj, other, deep) { - let k; +function objectMatchesSubset(obj?: object, other?: object, deep?: boolean): boolean { + let k: string; if (obj === other) { return true; @@ -61,21 +62,14 @@ function objectMatchesSubset(obj, other, deep) { return true; } -// XXX(dcramer): the previous mechanism of using _.map here failed -// miserably if a param was named 'length' -export function objectToArray(obj) { - const result = []; - for (const key in obj) { - result.push([key, obj[key]]); - } - return result; -} +// TODO: instances of objectToArray should be refactored +export const objectToArray = Object.entries; -export function intcomma(x) { +export function intcomma(x: number): string { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } -export function sortArray(arr, score_fn) { +export function sortArray(arr: Array, score_fn: (entry: T) => string): Array { arr.sort((a, b) => { const a_score = score_fn(a), b_score = score_fn(b); @@ -94,7 +88,7 @@ export function sortArray(arr, score_fn) { return arr; } -export function objectIsEmpty(obj) { +export function objectIsEmpty(obj: object): boolean { for (const prop in obj) { if (obj.hasOwnProperty(prop)) { return false; @@ -104,22 +98,22 @@ export function objectIsEmpty(obj) { return true; } -export function trim(str) { +export function trim(str: string): string { return str.replace(/^\s+|\s+$/g, ''); } /** * Replaces slug special chars with a space */ -export function explodeSlug(slug) { +export function explodeSlug(slug: string): string { return trim(slug.replace(/[-_]+/g, ' ')); } -export function defined(item) { +export function defined(item: any): boolean { return !_.isUndefined(item) && item !== null; } -export function nl2br(str) { +export function nl2br(str: string): string { return str.replace(/(?:\r\n|\r|\n)/g, '
'); } @@ -127,7 +121,7 @@ export function nl2br(str) { * This function has a critical security impact, make sure to check all usages before changing this function. * In some parts of our code we rely on that this only really is a string starting with http(s). */ -export function isUrl(str) { +export function isUrl(str: any): boolean { return ( !!str && _.isString(str) && @@ -135,24 +129,24 @@ export function isUrl(str) { ); } -export function escape(str) { +export function escape(str: string): string { return str .replace(/&/g, '&') .replace(//g, '>'); } -export function percent(value, totalValue, precise) { +export function percent(value: number, totalValue: number): number { return (value / totalValue) * 100; } -export function toTitleCase(str) { +export function toTitleCase(str: string): string { return str.replace(/\w\S*/g, txt => { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } -export function formatBytes(bytes) { +export function formatBytes(bytes: number): string { const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const thresh = 1024; if (bytes < thresh) { @@ -167,7 +161,7 @@ export function formatBytes(bytes) { return bytes.toFixed(1) + ' ' + units[u]; } -export function getShortVersion(version) { +export function getShortVersion(version: string): string { if (version.length < 12) { return version; } @@ -184,29 +178,29 @@ export function getShortVersion(version) { return version; } -export function parseRepo(repo) { - if (!repo) { - return repo; - } else { +export function parseRepo(repo: T): T { + if (typeof repo === 'string') { const re = /(?:github\.com|bitbucket\.org)\/([^\/]+\/[^\/]+)/i; const match = repo.match(re); const parsedRepo = match ? match[1] : repo; - return parsedRepo; + return parsedRepo as any; } + + return repo; } /** * Converts a multi-line textarea input value into an array, * eliminating empty lines */ -export function extractMultilineFields(value) { +export function extractMultilineFields(value: string): Array { return value .split('\n') .map(f => trim(f)) .filter(f => f !== ''); } -function projectDisplayCompare(a, b) { +function projectDisplayCompare(a: Project, b: Project): number { if (a.isBookmarked !== b.isBookmarked) { return a.isBookmarked ? -1 : 1; } @@ -214,7 +208,7 @@ function projectDisplayCompare(a, b) { } // Sort a list of projects by bookmarkedness, then by id -export function sortProjects(projects) { +export function sortProjects(projects: Array): Array { return projects.sort(projectDisplayCompare); } @@ -225,13 +219,21 @@ export const buildTeamId = id => `team:${id}`; /** * Removes the organization / project scope prefix on feature names. */ -export function descopeFeatureName(feature) { - return typeof feature.match !== 'function' - ? feature - : feature.match(/(?:^(?:projects|organizations):)?(.*)/).pop(); +export function descopeFeatureName(feature: T): T | string { + if (typeof feature !== 'string') { + return feature; + } + + const results = feature.match(/(?:^(?:projects|organizations):)?(.*)/); + + if (results && results.length > 0) { + return results.pop()!; + } + + return feature; } -export function isWebpackChunkLoadingError(error) { +export function isWebpackChunkLoadingError(error: Error): boolean { return ( error && typeof error.message === 'string' && @@ -239,7 +241,7 @@ export function isWebpackChunkLoadingError(error) { ); } -export function deepFreeze(object) { +export function deepFreeze(object: {[x: string]: any}) { // Retrieve the property names defined on object const propNames = Object.getOwnPropertyNames(object); // Freeze properties before freezing self