From 6648fd40a5daa9f5d95d4ec90d488cba2d35443b Mon Sep 17 00:00:00 2001 From: Jon Ursenbach Date: Tue, 8 Apr 2025 17:40:25 -0700 Subject: [PATCH] feat: enabling `isolatedDeclarations` --- src/fixtures/runCustomFixtures.ts | 2 +- src/helpers/code-builder.ts | 12 ++++++------ src/helpers/escape.ts | 6 +++--- src/helpers/headers.ts | 8 ++++---- src/helpers/reducer.ts | 5 ++++- src/helpers/shell.ts | 4 ++-- src/helpers/utils.ts | 4 ++-- src/index.test.ts | 2 +- src/index.ts | 22 +++++++++++++++------- src/targets/index.ts | 29 +++++++++++++++++++++++++---- src/targets/php/helpers.ts | 4 ++-- src/targets/powershell/common.ts | 4 ++-- tsconfig.json | 2 +- 13 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/fixtures/runCustomFixtures.ts b/src/fixtures/runCustomFixtures.ts index 60a665d8..013abdc8 100644 --- a/src/fixtures/runCustomFixtures.ts +++ b/src/fixtures/runCustomFixtures.ts @@ -22,7 +22,7 @@ export interface CustomFixture { }[]; } -export const runCustomFixtures = ({ targetId, clientId, tests }: CustomFixture) => { +export const runCustomFixtures = ({ targetId, clientId, tests }: CustomFixture): void => { describe(`custom fixtures for ${targetId}:${clientId}`, () => { it.each(tests.map(t => [t.it, t]))('%s', async (_, { expected: fixtureFile, options, input: request }) => { const opts: HTTPSnippetOptions = {}; diff --git a/src/helpers/code-builder.ts b/src/helpers/code-builder.ts index 4fbf8747..80fbf424 100644 --- a/src/helpers/code-builder.ts +++ b/src/helpers/code-builder.ts @@ -24,7 +24,7 @@ export class CodeBuilder { indentationCharacter: string = DEFAULT_INDENTATION_CHARACTER; - lineJoin = DEFAULT_LINE_JOIN; + lineJoin: string = DEFAULT_LINE_JOIN; /** * Helper object to format and aggragate lines of code. @@ -46,7 +46,7 @@ export class CodeBuilder { /** * Add the line at the beginning of the current lines */ - unshift = (line: string, indentationLevel?: number) => { + unshift = (line: string, indentationLevel?: number): void => { const newLine = this.indentLine(line, indentationLevel); this.code.unshift(newLine); }; @@ -54,7 +54,7 @@ export class CodeBuilder { /** * Add the line at the end of the current lines */ - push = (line: string, indentationLevel?: number) => { + push = (line: string, indentationLevel?: number): void => { const newLine = this.indentLine(line, indentationLevel); this.code.push(newLine); }; @@ -62,14 +62,14 @@ export class CodeBuilder { /** * Add an empty line at the end of current lines */ - blank = () => { + blank = (): void => { this.code.push(''); }; /** * Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added */ - join = () => { + join = (): string => { const unreplacedCode = this.code.join(this.lineJoin); const replacedOutput = this.postProcessors.reduce((accumulator, replacer) => replacer(accumulator), unreplacedCode); return replacedOutput; @@ -79,7 +79,7 @@ export class CodeBuilder { * Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step. * To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on. */ - addPostProcessor = (postProcessor: PostProcessor) => { + addPostProcessor = (postProcessor: PostProcessor): void => { this.postProcessors = [...this.postProcessors, postProcessor]; }; } diff --git a/src/helpers/escape.ts b/src/helpers/escape.ts index 4330fc88..c47925eb 100644 --- a/src/helpers/escape.ts +++ b/src/helpers/escape.ts @@ -30,7 +30,7 @@ export interface EscapeOptions { * See https://tc39.es/ecma262/multipage/structured-data.html#sec-quotejsonstring * for the complete original algorithm. */ -export function escapeString(rawValue: any, options: EscapeOptions = {}) { +export function escapeString(rawValue: any, options: EscapeOptions = {}): string { const { delimiter = '"', escapeChar = '\\', escapeNewlines = true } = options; const stringValue = rawValue.toString(); @@ -79,7 +79,7 @@ export function escapeString(rawValue: any, options: EscapeOptions = {}) { * * If value is not a string, it will be stringified with .toString() first. */ -export const escapeForSingleQuotes = (value: any) => escapeString(value, { delimiter: "'" }); +export const escapeForSingleQuotes = (value: any): string => escapeString(value, { delimiter: "'" }); /** * Make a string value safe to insert literally into a snippet within double quotes, @@ -88,4 +88,4 @@ export const escapeForSingleQuotes = (value: any) => escapeString(value, { delim * * If value is not a string, it will be stringified with .toString() first. */ -export const escapeForDoubleQuotes = (value: any) => escapeString(value, { delimiter: '"' }); +export const escapeForDoubleQuotes = (value: any): string => escapeString(value, { delimiter: '"' }); diff --git a/src/helpers/headers.ts b/src/helpers/headers.ts index aff751f8..c1c288b6 100644 --- a/src/helpers/headers.ts +++ b/src/helpers/headers.ts @@ -3,13 +3,13 @@ type Headers = Record; /** * Given a headers object retrieve a specific header out of it via a case-insensitive key. */ -export const getHeaderName = (headers: Headers, name: string) => +export const getHeaderName = (headers: Headers, name: string): string | undefined => Object.keys(headers).find(header => header.toLowerCase() === name.toLowerCase()); /** * Given a headers object retrieve the contents of a header out of it via a case-insensitive key. */ -export const getHeader = (headers: Headers, name: string) => { +export const getHeader = (headers: Headers, name: string): T | undefined => { const headerName = getHeaderName(headers, name); if (!headerName) { return undefined; @@ -20,12 +20,12 @@ export const getHeader = (headers: Headers, name: string) => { /** * Determine if a given case-insensitive header exists within a header object. */ -export const hasHeader = (headers: Headers, name: string) => Boolean(getHeaderName(headers, name)); +export const hasHeader = (headers: Headers, name: string): boolean => Boolean(getHeaderName(headers, name)); /** * Determines if a given MIME type is JSON, or a variant of such. */ -export const isMimeTypeJSON = (mimeType: string) => +export const isMimeTypeJSON = (mimeType: string): boolean => ['application/json', 'application/x-json', 'text/json', 'text/x-json', '+json'].some( type => mimeType.indexOf(type) > -1, ); diff --git a/src/helpers/reducer.ts b/src/helpers/reducer.ts index 8311daba..7306af0c 100644 --- a/src/helpers/reducer.ts +++ b/src/helpers/reducer.ts @@ -1,6 +1,9 @@ export type ReducedHelperObject = Record; -export const reducer = (accumulator: ReducedHelperObject, pair: T) => { +export const reducer = ( + accumulator: ReducedHelperObject, + pair: T, +): ReducedHelperObject => { const currentValue = accumulator[pair.name]; if (currentValue === undefined) { accumulator[pair.name] = pair.value; diff --git a/src/helpers/shell.ts b/src/helpers/shell.ts index 5f8b7e1c..e06c341a 100644 --- a/src/helpers/shell.ts +++ b/src/helpers/shell.ts @@ -2,7 +2,7 @@ * Use 'strong quoting' using single quotes so that we only need to deal with nested single quote characters. * see: http://wiki.bash-hackers.org/syntax/quoting#strong_quoting */ -export const quote = (value = '') => { +export const quote = (value = ''): string => { const safe = /^[a-z0-9-_/.@%^=:]+$/i; const isShellSafe = safe.test(value); @@ -15,4 +15,4 @@ export const quote = (value = '') => { return `'${value.replace(/'/g, "'\\''")}'`; }; -export const escape = (value: string) => value.replace(/\r/g, '\\r').replace(/\n/g, '\\n'); +export const escape = (value: string): string => value.replace(/\r/g, '\\r').replace(/\n/g, '\\n'); diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 526cf61c..8a8df05a 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -6,7 +6,7 @@ export interface AvailableTarget extends TargetInfo { clients: ClientInfo[]; } -export const availableTargets = () => +export const availableTargets = (): AvailableTarget[] => Object.keys(targets).map(targetId => ({ ...targets[targetId as TargetId].info, clients: Object.keys(targets[targetId as TargetId].clientsById).map( @@ -14,7 +14,7 @@ export const availableTargets = () => ), })); -export const extname = (targetId: TargetId, clientId: ClientId) => { +export const extname = (targetId: TargetId, clientId: ClientId): '' | `.${string}` => { const target = targets[targetId]; if (!target) { return ''; diff --git a/src/index.test.ts b/src/index.test.ts index b062bd32..b2563107 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -16,7 +16,7 @@ describe('HTTPSnippet', () => { // @ts-expect-error intentionally incorrect const result = snippet.convert(null); - expect(result).toBe(false); + expect(result).toStrictEqual([false]); }); describe('repair malformed `postData`', () => { diff --git a/src/index.ts b/src/index.ts index 6bcb98c4..088bb5a4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -105,7 +105,7 @@ export class HTTPSnippet { } } - init() { + init(): HTTPSnippet { this.initCalled = true; this.requests = this.entries.map(({ request }) => { @@ -134,7 +134,15 @@ export class HTTPSnippet { return this; } - prepare(harRequest: HarRequest, options: HTTPSnippetOptions) { + prepare( + harRequest: HarRequest, + options: HTTPSnippetOptions, + ): Request & { + allHeaders: Record; + fullUrl: string; + url: any; + uriObj: any; + } { const request: Request = { ...harRequest, fullUrl: '', @@ -308,12 +316,12 @@ export class HTTPSnippet { ...urlWithParsedQuery, query: null, search: null, - }); //? + }); const fullUrl = urlFormat({ ...urlWithParsedQuery, ...uriObj, - }); //? + }); return { ...request, @@ -324,7 +332,7 @@ export class HTTPSnippet { }; } - convert(targetId: TargetId, clientId?: ClientId, options?: Options) { + convert(targetId: TargetId, clientId?: ClientId, options?: Options): (string | false)[] { if (!this.initCalled) { this.init(); } @@ -335,7 +343,7 @@ export class HTTPSnippet { const target = targets[targetId]; if (!target) { - return false; + return [false]; } const { convert } = target.clientsById[clientId || target.info.default]; @@ -343,7 +351,7 @@ export class HTTPSnippet { return results; } - installation(targetId: TargetId, clientId?: ClientId, options?: Options) { + installation(targetId: TargetId, clientId?: ClientId, options?: Options): (string | false)[] { if (!this.initCalled) { this.init(); } diff --git a/src/targets/index.ts b/src/targets/index.ts index 742101c5..5a60b783 100644 --- a/src/targets/index.ts +++ b/src/targets/index.ts @@ -100,7 +100,28 @@ export interface Target { info: TargetInfo; } -export const targets = { +type supportedTargets = + | 'c' + | 'clojure' + | 'csharp' + | 'go' + | 'http' + | 'java' + | 'javascript' + | 'json' + | 'kotlin' + | 'node' + | 'objc' + | 'ocaml' + | 'php' + | 'powershell' + | 'python' + | 'r' + | 'ruby' + | 'shell' + | 'swift'; + +export const targets: Record = { c, clojure, csharp, @@ -181,7 +202,7 @@ export const isTarget = (target: Target): target is Target => { return true; }; -export const addTarget = (target: Target) => { +export const addTarget = (target: Target): void => { if (!isTarget(target)) { return; } @@ -228,11 +249,11 @@ export const isClient = (client: Client): client is Client => { return true; }; -export const addClientPlugin = (plugin: ClientPlugin) => { +export const addClientPlugin = (plugin: ClientPlugin): void => { addTargetClient(plugin.target, plugin.client); }; -export const addTargetClient = (targetId: TargetId, client: Client) => { +export const addTargetClient = (targetId: TargetId, client: Client): void => { if (!isClient(client)) { return; } diff --git a/src/targets/php/helpers.ts b/src/targets/php/helpers.ts index 96a9ff3b..33d9ce3e 100644 --- a/src/targets/php/helpers.ts +++ b/src/targets/php/helpers.ts @@ -1,6 +1,6 @@ import { escapeString } from '../../helpers/escape.js'; -export const convertType = (obj: any[] | any, indent?: string, lastIndent?: string) => { +export const convertType = (obj: any[] | any, indent?: string, lastIndent?: string): unknown => { lastIndent = lastIndent || ''; indent = indent || ''; @@ -41,7 +41,7 @@ export const convertType = (obj: any[] | any, indent?: string, lastIndent?: stri } }; -export const supportedMethods = [ +export const supportedMethods: string[] = [ 'ACL', 'BASELINE_CONTROL', 'CHECKIN', diff --git a/src/targets/powershell/common.ts b/src/targets/powershell/common.ts index f1dd5417..80db499b 100644 --- a/src/targets/powershell/common.ts +++ b/src/targets/powershell/common.ts @@ -6,8 +6,8 @@ import { getHeader } from '../../helpers/headers.js'; export type PowershellCommand = 'Invoke-RestMethod' | 'Invoke-WebRequest'; -export const generatePowershellConvert = (command: PowershellCommand) => { - const convert: Converter = ({ method, headersObj, cookies, uriObj, fullUrl, postData, allHeaders }) => { +export const generatePowershellConvert = (command: PowershellCommand): Converter => { + const convert: Converter = ({ method, headersObj, cookies, uriObj, fullUrl, postData, allHeaders }) => { const { push, join } = new CodeBuilder(); const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']; diff --git a/tsconfig.json b/tsconfig.json index 227dd958..75e9eab4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "allowJs": true, "declaration": true, "downlevelIteration": true, "esModuleInterop": true, + "isolatedDeclarations": true, "lib": ["DOM", "ES2020"], "module": "ESNext", "moduleResolution": "Bundler",