diff options
author | Mats Larsen <me@supergrecko.com> | 2023-01-29 19:06:14 +0100 |
---|---|---|
committer | Mats Larsen <me@supergrecko.com> | 2023-01-29 19:06:14 +0100 |
commit | 7350a6f6e92c01370e330e7395765645b5eb7faa (patch) | |
tree | e6ab46946ceb141391b8ba16fed29c1c7b7efd86 | |
parent | 8c748f16105f4440f78f4f4fa8d74f9cb8aa92df (diff) | |
download | compiler-explorer-gh-6023.tar.gz compiler-explorer-gh-6023.zip |
Tsify lib/handlers/formatting.jsgh-6023
-rw-r--r-- | lib/formatters/base.interfaces.ts | 1 | ||||
-rw-r--r-- | lib/formatters/index.ts | 9 | ||||
-rw-r--r-- | lib/handlers/formatting.ts (renamed from lib/handlers/formatting.js) | 65 | ||||
-rw-r--r-- | static/styles/themes/dark-theme.scss | 3 |
4 files changed, 49 insertions, 29 deletions
diff --git a/lib/formatters/base.interfaces.ts b/lib/formatters/base.interfaces.ts index 32f4b0cd8..855dd15b8 100644 --- a/lib/formatters/base.interfaces.ts +++ b/lib/formatters/base.interfaces.ts @@ -27,6 +27,7 @@ export interface FormatterInfo { exe: string; styles: string[]; type: string; + version: string; explicitVersion?: string; versionArgument?: string; versionReExp?: string; diff --git a/lib/formatters/index.ts b/lib/formatters/index.ts index f12b5e225..85c1ede57 100644 --- a/lib/formatters/index.ts +++ b/lib/formatters/index.ts @@ -23,10 +23,17 @@ // POSSIBILITY OF SUCH DAMAGE. import {makeKeyedTypeGetter} from '../keyed-type'; +import {Keyable} from '../keyed-type.interfaces'; import * as all from './_all'; +import {BaseFormatter} from './base'; +import {FormatterInfo} from './base.interfaces'; export {BaseFormatter} from './base'; export * from './_all'; -export const getFormatterTypeByKey = makeKeyedTypeGetter('formatter', all); +type FormatterClass = { + new (opts: FormatterInfo): BaseFormatter; +} & Keyable; + +export const getFormatterTypeByKey = makeKeyedTypeGetter<FormatterClass>('formatter', all); diff --git a/lib/handlers/formatting.js b/lib/handlers/formatting.ts index 4c0a5fe45..0457fd281 100644 --- a/lib/handlers/formatting.js +++ b/lib/handlers/formatting.ts @@ -22,77 +22,86 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +import express from 'express'; import _ from 'underscore'; import * as exec from '../exec'; -import {getFormatterTypeByKey} from '../formatters'; +import {BaseFormatter, getFormatterTypeByKey} from '../formatters'; import {logger} from '../logger'; +import {PropertyGetter} from '../properties.interfaces'; export class FormattingHandler { - constructor(ceProps) { - this.formatters = {}; - this.ceProps = ceProps; + private formatters: Record<string, BaseFormatter> = {}; + + public constructor(private ceProps: PropertyGetter) { const formatters = _.compact(ceProps('formatters', '').split(':')); - _.each(formatters, this.getFormatterInfo.bind(this)); + for (const formatter of formatters) { + this.getFormatterInfo(formatter); + } } - async getFormatterInfo(formatter) { - const exe = this.ceProps(`formatter.${formatter}.exe`); - const type = this.ceProps(`formatter.${formatter}.type`); + private async getFormatterInfo(formatterName: string): Promise<void> { + const exe = this.ceProps<string>(`formatter.${formatterName}.exe`); + const type = this.ceProps<string>(`formatter.${formatterName}.type`); if (!exe) { - return logger.warn(`Formatter ${formatter} does not have a valid executable. Skipping...`); + logger.warn(`Formatter ${formatterName} does not have a valid executable. Skipping...`); + return; } if (!type) { - return logger.warn(`Formatter ${formatter} does not have a formatter class. Skipping...`); + logger.warn(`Formatter ${formatterName} does not have a formatter class. Skipping...`); + return; } - const versionArg = this.ceProps(`formatter.${formatter}.version`, '--version'); - const versionRe = this.ceProps(`formatter.${formatter}.versionRe`, '.*'); - const hasExplicitVersion = this.ceProps(`formatter.${formatter}.explicitVersion`, '') !== ''; + const versionArgument = this.ceProps<string>(`formatter.${formatterName}.version`, '--version'); + const versionRegExp = this.ceProps<string>(`formatter.${formatterName}.versionRe`, '.*'); + const hasExplicitVersion = this.ceProps(`formatter.${formatterName}.explicitVersion`, '') !== ''; try { - const result = await exec.execute(exe, [versionArg], {}); - const match = result.stdout.match(versionRe); + const result = await exec.execute(exe, [versionArgument], {}); + const match = result.stdout.match(versionRegExp); const formatterClass = getFormatterTypeByKey(type); - const styleList = this.ceProps(`formatter.${formatter}.styles`); + const styleList = this.ceProps<string>(`formatter.${formatterName}.styles`); const styles = styleList === '' ? [] : styleList.split(':'); // If there is an explicit version, grab it. Otherwise try to filter the output const version = hasExplicitVersion - ? this.ceProps(`formatter.${formatter}.explicitVersion`) + ? this.ceProps<string>(`formatter.${formatterName}.explicitVersion`) : match ? match[0] : result.stdout; - this.formatters[formatter] = new formatterClass({ - name: this.ceProps(`formatter.${formatter}.name`, exe), + this.formatters[formatterName] = new formatterClass({ + name: this.ceProps(`formatter.${formatterName}.name`, exe), exe, version, styles, type, }); - } catch (err) { + } catch (err: unknown) { logger.warn(`Error while fetching tool info for ${exe}:`, {err}); } } - async handle(req, res) { + public async handle(req: express.Request, res: express.Response): Promise<void> { const name = req.params.tool; const formatter = this.formatters[name]; // Ensure the formatter exists if (!formatter) { - return res.status(422).send({ + res.status(422).send({ exit: 2, answer: `Unknown format tool '${name}'`, }); + return; } // Ensure there is source code to format if (!req.body || !req.body.source) { - return res.send({exit: 0, answer: ''}); + res.send({exit: 0, answer: ''}); + return; } // Ensure the wanted style is valid for the formatter const style = req.body.base; if (!formatter.isValidStyle(style)) { - return res.status(422).send({ + res.status(422).send({ exit: 3, answer: `Style '${style}' is not supported`, }); + return; } try { // Perform the actual formatting @@ -105,16 +114,18 @@ export class FormattingHandler { exit: result.code, answer: result.stdout || result.stderr || '', }); - } catch (err) { + } catch (err: unknown) { res.status(500).send({ exit: 1, thrown: true, - answer: err.message || 'Internal server error', + answer: + (err && Object.hasOwn(err, 'message') && (err as Record<'message', 'string'>).message) || + 'Internal server error', }); } } - async internalFormat(formatterName, style, source) { + async internalFormat(formatterName: string, style: string, source: string): Promise<[string, string]> { const formatter = this.formatters[formatterName]; // Ensure the formatter exists if (!formatter) { diff --git a/static/styles/themes/dark-theme.scss b/static/styles/themes/dark-theme.scss index d10b48a41..65791676d 100644 --- a/static/styles/themes/dark-theme.scss +++ b/static/styles/themes/dark-theme.scss @@ -492,7 +492,8 @@ textarea.form-control { border-color: #474747 !important; } -.popover .arrow::after, .popover .arrow::before { +.popover .arrow::after, +.popover .arrow::before { border-left-color: #151515 !important; border-right-color: #151515 !important; } |