From e5bb5ce4cec546cc32022335a40d702f98477743 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Wed, 8 Dec 2021 19:11:16 +0100 Subject: [PATCH] chore: update @ionic/prettier-config (#32) --- package-lock.json | 22 ++-- package.json | 2 +- src/cli.ts | 12 +- src/formatting.ts | 19 +--- src/index.ts | 6 +- src/markdown.ts | 26 ++--- src/output.ts | 65 ++++------- src/parse.ts | 185 +++++++++++-------------------- src/test/fixtures/definitions.ts | 5 +- src/test/fixtures/index.ts | 5 +- src/test/formatting.spec.ts | 29 ++--- src/test/parse.spec.ts | 35 +++--- src/transpile.ts | 12 +- 13 files changed, 150 insertions(+), 273 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a91913..80762c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ }, "devDependencies": { "@capacitor/cli": "^3.0.1", - "@ionic/prettier-config": "^1.0.1", + "@ionic/prettier-config": "^2.0.0", "@stencil/core": "^2.6.0", "@types/github-slugger": "^1.3.0", "@types/jest": "^26.0.23", @@ -551,10 +551,13 @@ "dev": true }, "node_modules/@ionic/prettier-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-1.0.1.tgz", - "integrity": "sha512-/v8UOW7rxkw/hvrRe/QfjlQsdjkm3sfAHoE3uqffO5BoNGijQMARrT32JT9Ei0g6KySXPyxxW+7LzPHrQmfzCw==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-2.0.0.tgz", + "integrity": "sha512-ageMx54B9qqS1scnFW3kQW2NW8HyXwUM/p9c1YSWFKr6Yct7YVNbJFY3EcFapaNTiDnwo+GLlPRt+wST6E8AfA==", + "dev": true, + "peerDependencies": { + "prettier": "^2.0.0" + } }, "node_modules/@ionic/utils-array": { "version": "2.1.5", @@ -10161,10 +10164,11 @@ } }, "@ionic/prettier-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-1.0.1.tgz", - "integrity": "sha512-/v8UOW7rxkw/hvrRe/QfjlQsdjkm3sfAHoE3uqffO5BoNGijQMARrT32JT9Ei0g6KySXPyxxW+7LzPHrQmfzCw==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-2.0.0.tgz", + "integrity": "sha512-ageMx54B9qqS1scnFW3kQW2NW8HyXwUM/p9c1YSWFKr6Yct7YVNbJFY3EcFapaNTiDnwo+GLlPRt+wST6E8AfA==", + "dev": true, + "requires": {} }, "@ionic/utils-array": { "version": "2.1.5", diff --git a/package.json b/package.json index 06122b1..2c3f24e 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@capacitor/cli": "^3.0.1", - "@ionic/prettier-config": "^1.0.1", + "@ionic/prettier-config": "^2.0.0", "@stencil/core": "^2.6.0", "@types/github-slugger": "^1.3.0", "@types/jest": "^26.0.23", diff --git a/src/cli.ts b/src/cli.ts index 871372f..a992c4a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -24,15 +24,13 @@ export async function run(config: { cwd: string; args: string[] }) { try { if (!args.api) { - throw new Error( - `Please provide the primary interface name using the "--api" arg`, - ); + throw new Error(`Please provide the primary interface name using the "--api" arg`); } const tsconfigPath = getTsconfigPath(config.cwd, args.project); if (!tsconfigPath) { throw new Error( - `Unable to find project's tsconfig.json file. Use the "--project" arg to specify the exact path.`, + `Unable to find project's tsconfig.json file. Use the "--project" arg to specify the exact path.` ); } @@ -42,9 +40,7 @@ export async function run(config: { cwd: string; args: string[] }) { }; if (!args['output-json'] && !args['output-readme']) { - throw new Error( - `Please provide an output path with either "--output-readme" or "--output-json" args, or both.`, - ); + throw new Error(`Please provide an output path with either "--output-readme" or "--output-json" args, or both.`); } if (args['output-json']) { @@ -74,7 +70,7 @@ function getTsconfigPath(cwd: string, cliTsConfigPath: string) { if (cliTsConfigPath) { return normalizePath(cwd, cliTsConfigPath); } - return ts.findConfigFile(cwd, f => fs.existsSync(f)); + return ts.findConfigFile(cwd, (f) => fs.existsSync(f)); } function logOutput(outputPath: string | undefined) { diff --git a/src/formatting.ts b/src/formatting.ts index de8065b..8618e67 100644 --- a/src/formatting.ts +++ b/src/formatting.ts @@ -15,12 +15,7 @@ export function formatType(data: DocsData, c: string | undefined) { tokens.shift(); } else { for (let i = tokens.length - 1; i >= 0; i--) { - if ( - tokens[i] === 'undefined' && - tokens[i - 1] === ' ' && - tokens[i - 2] === '|' && - tokens[i - 3] === ' ' - ) { + if (tokens[i] === 'undefined' && tokens[i - 1] === ' ' && tokens[i - 2] === '|' && tokens[i - 3] === ' ') { tokens.splice(i - 3, 4); i = i - 4; } @@ -92,25 +87,23 @@ export function formatMethodSignatureForSlug(m: DocsInterfaceMethod) { function linkToken(data: DocsData, token: string) { const t = token.replace(/`/g, ''); - const i = data.interfaces.find(i => { + const i = data.interfaces.find((i) => { return ( i.name === t || - i.methods.some(m => i.name + '.' + m.name === t) || - i.properties.some(p => i.name + '.' + p.name === t) + i.methods.some((m) => i.name + '.' + m.name === t) || + i.properties.some((p) => i.name + '.' + p.name === t) ); }); if (i) { return `${token}`; } - const ta = data.typeAliases.find(ta => ta.name === t); + const ta = data.typeAliases.find((ta) => ta.name === t); if (ta) { return `${token}`; } - const e = data.enums.find( - e => e.name === t || e.members.some(m => e.name + '.' + m.name === t), - ); + const e = data.enums.find((e) => e.name === t || e.members.some((m) => e.name + '.' + m.name === t)); if (e) { return `${token}`; } diff --git a/src/index.ts b/src/index.ts index 3ad4508..3e7071e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,5 @@ export { generate } from './generate'; -export { - outputJson, - outputReadme, - replaceMarkdownPlaceholders, -} from './output'; +export { outputJson, outputReadme, replaceMarkdownPlaceholders } from './output'; export { parse } from './parse'; export { run } from './cli'; export * from './types'; diff --git a/src/markdown.ts b/src/markdown.ts index 71e44cf..53b82b0 100644 --- a/src/markdown.ts +++ b/src/markdown.ts @@ -8,7 +8,7 @@ export class MarkdownTable { addRow(data: string[], isHeader = false) { const colData: ColumnData[] = []; - data.forEach(text => { + data.forEach((text) => { const col: ColumnData = { text: escapeMarkdownTableColumn(text), width: text.length, @@ -36,11 +36,7 @@ export class MarkdownTable { const row = this.rows[r]; if (row && !row.isHeader) { const column = row.columns[c]; - if ( - column && - typeof column.text === 'string' && - column.text.trim().length > 0 - ) { + if (column && typeof column.text === 'string' && column.text.trim().length > 0) { isEmptyColumn = false; break; } @@ -80,15 +76,15 @@ const createTable = (rows: RowData[]) => { normalizeColumCount(rows); normalizeColumnWidth(rows); - const th = rows.find(r => r.isHeader); + const th = rows.find((r) => r.isHeader); if (th) { const headerRow = createRow(th); content.push(headerRow); content.push(createBorder(th)); } - const tds = rows.filter(r => !r.isHeader); - tds.forEach(td => { + const tds = rows.filter((r) => !r.isHeader); + tds.forEach((td) => { content.push(createRow(td)); }); @@ -101,7 +97,7 @@ const createBorder = (th: RowData) => { isHeader: false, }; - th.columns.forEach(c => { + th.columns.forEach((c) => { const borderCol: ColumnData = { text: '', width: c.width, @@ -118,7 +114,7 @@ const createBorder = (th: RowData) => { const createRow = (row: RowData) => { const content: string[] = ['| ']; - row.columns.forEach(c => { + row.columns.forEach((c) => { content.push(c.text); content.push(' | '); }); @@ -129,13 +125,13 @@ const createRow = (row: RowData) => { const normalizeColumCount = (rows: RowData[]) => { let columnCount = 0; - rows.forEach(r => { + rows.forEach((r) => { if (r.columns.length > columnCount) { columnCount = r.columns.length; } }); - rows.forEach(r => { + rows.forEach((r) => { while (r.columns.length < columnCount) { r.columns.push({ text: ``, @@ -151,14 +147,14 @@ const normalizeColumnWidth = (rows: RowData[]) => { for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) { let longestText = 0; - rows.forEach(r => { + rows.forEach((r) => { const col = r.columns[columnIndex]; if (col.text.length > longestText) { longestText = col.text.length; } }); - rows.forEach(r => { + rows.forEach((r) => { const col = r.columns[columnIndex]; col.width = longestText; while (col.text.length < longestText) { diff --git a/src/output.ts b/src/output.ts index d8f1117..401abaa 100644 --- a/src/output.ts +++ b/src/output.ts @@ -1,10 +1,6 @@ import fs from 'fs'; import path from 'path'; -import { - formatDescription, - formatType, - formatMethodSignature, -} from './formatting'; +import { formatDescription, formatType, formatMethodSignature } from './formatting'; import { promisify } from 'util'; import { MarkdownTable } from './markdown'; import { slugify } from './parse'; @@ -35,7 +31,7 @@ export async function outputReadme(readmeFilePath: string, data: DocsData) { content = await readFile(readmeFilePath, 'utf8'); } catch (e) { throw new Error( - `Unable to read: "${readmeFilePath}".\n\nIf this is the correct path, please create the file first, then run again.`, + `Unable to read: "${readmeFilePath}".\n\nIf this is the correct path, please create the file first, then run again.` ); } @@ -71,8 +67,7 @@ function replaceMarkdownDocsIndex(content: string, data: DocsData) { const endInnerIndex = content.indexOf(INDEX_END); if (endInnerIndex > -1) { const inner = content.substring(startOuterIndex + INDEX_START.length); - const startInnderIndex = - startOuterIndex + INDEX_START.length + inner.indexOf('>') + 1; + const startInnderIndex = startOuterIndex + INDEX_START.length + inner.indexOf('>') + 1; const start = content.substring(0, startInnderIndex); const end = content.substring(endInnerIndex); return `${start}\n\n${markdownIndex(data)}\n\n${end}`; @@ -88,8 +83,7 @@ function replaceMarkdownDocsConfig(content: string, data: DocsData) { const endInnerIndex = content.indexOf(CONFIG_END); if (endInnerIndex > -1) { const inner = content.substring(startOuterIndex + CONFIG_START.length); - const startInnerIndex = - startOuterIndex + CONFIG_START.length + inner.indexOf('>') + 1; + const startInnerIndex = startOuterIndex + CONFIG_START.length + inner.indexOf('>') + 1; const start = content.substring(0, startInnerIndex); const end = content.substring(endInnerIndex); return `${start}\n${UPDATE_MSG}\n\n${markdownConfig(data)}\n\n${end}`; @@ -105,8 +99,7 @@ function replaceMarkdownDocsApi(content: string, data: DocsData) { const endInnerIndex = content.indexOf(API_END); if (endInnerIndex > -1) { const inner = content.substring(startOuterIndex + API_START.length); - const startInnerIndex = - startOuterIndex + API_START.length + inner.indexOf('>') + 1; + const startInnerIndex = startOuterIndex + API_START.length + inner.indexOf('>') + 1; const start = content.substring(0, startInnerIndex); const end = content.substring(endInnerIndex); return `${start}\n${UPDATE_MSG}\n\n${markdownApi(data)}\n\n${end}`; @@ -119,7 +112,7 @@ function replaceMarkdownDocsApi(content: string, data: DocsData) { function markdownIndex(data: DocsData) { const o: string[] = []; - data?.api?.methods.forEach(m => { + data?.api?.methods.forEach((m) => { o.push(`* [\`${formatMethodSignature(m)}\`](#${m.slug})`); }); @@ -146,14 +139,14 @@ function markdownApi(data: DocsData) { o.push(``); } - data!.api!.methods.forEach(m => { + data!.api!.methods.forEach((m) => { o.push(methodsTable(data, m)); }); if (data.interfaces.length > 0) { o.push(`### Interfaces`); o.push(``); - data.interfaces.forEach(i => { + data.interfaces.forEach((i) => { o.push(interfaceTable(data, i)); }); o.push(``); @@ -162,7 +155,7 @@ function markdownApi(data: DocsData) { if (data.typeAliases.length > 0) { o.push(`### Type Aliases`); o.push(``); - data.typeAliases.forEach(i => { + data.typeAliases.forEach((i) => { o.push(typeAliasTable(data, i)); }); o.push(``); @@ -171,7 +164,7 @@ function markdownApi(data: DocsData) { if (data.enums.length > 0) { o.push(`### Enums`); o.push(``); - data.enums.forEach(i => { + data.enums.forEach((i) => { o.push(enumTable(data, i)); }); o.push(``); @@ -222,7 +215,7 @@ function methodsTable(data: DocsData, m: DocsInterfaceMethod) { function markdownConfig(data: DocsData) { const o: string[] = []; if (data.pluginConfigs) { - data!.pluginConfigs!.forEach(c => { + data!.pluginConfigs!.forEach((c) => { o.push(configInterfaceTable(data, c)); o.push(buildExamples(c)); }); @@ -243,9 +236,7 @@ function buildExamples(c: DocsConfigInterface) { o.push(` "${c.name}": {`); c.properties.forEach((p, i) => { o.push( - ` "${p.name}": ${p.tags.find(t => t.name === 'example')?.text}${ - i === c.properties.length - 1 ? '' : ',' - }`, + ` "${p.name}": ${p.tags.find((t) => t.name === 'example')?.text}${i === c.properties.length - 1 ? '' : ','}` ); }); o.push(` }`); @@ -257,19 +248,15 @@ function buildExamples(c: DocsConfigInterface) { o.push(`In \`capacitor.config.ts\`:`); o.push(``); o.push(`\`\`\`ts`); - o.push( - `/// `, - ); + o.push(`/// `); o.push(``); o.push(`import { CapacitorConfig } from '@capacitor/cli';`); o.push(``); o.push(`const config: CapacitorConfig = {`); o.push(` plugins: {`); o.push(` ${c.name}: {`); - c.properties.forEach(p => { - o.push(` ${p.name}: ${p.tags.find(t => t.name === 'example')?.text},`); + c.properties.forEach((p) => { + o.push(` ${p.name}: ${p.tags.find((t) => t.name === 'example')?.text},`); }); o.push(` },`); o.push(` },`); @@ -286,7 +273,7 @@ function createMethodParamTable(data: DocsData, parameters: DocsMethodParam[]) { t.addHeader([`Param`, `Type`, `Description`]); - parameters.forEach(p => { + parameters.forEach((p) => { const nm = `**\`${p.name}\`**`; const ty = formatType(data, p.type); const docs = formatDescription(data, p.docs); @@ -313,7 +300,7 @@ function interfaceTable(data: DocsData, i: DocsInterface) { t.addHeader([`Prop`, `Type`, `Description`, `Default`, `Since`]); - i.properties.forEach(m => { + i.properties.forEach((m) => { const defaultValue = getTagText(m.tags, 'default'); t.addRow([ @@ -335,12 +322,8 @@ function interfaceTable(data: DocsData, i: DocsInterface) { t.addHeader([`Method`, `Signature`, `Description`]); - i.methods.forEach(m => { - t.addRow([ - `**${m.name}**`, - formatDescription(data, m.signature), - formatDescription(data, m.docs), - ]); + i.methods.forEach((m) => { + t.addRow([`**${m.name}**`, formatDescription(data, m.signature), formatDescription(data, m.docs)]); }); t.removeEmptyColumns(); @@ -364,7 +347,7 @@ function configInterfaceTable(data: DocsData, i: DocsConfigInterface) { t.addHeader([`Prop`, `Type`, `Description`, `Default`, `Since`]); - i.properties.forEach(m => { + i.properties.forEach((m) => { const defaultValue = getTagText(m.tags, 'default'); t.addRow([ @@ -396,7 +379,7 @@ function typeAliasTable(data: DocsData, t: DocsTypeAlias) { } const type = t.types - .map(ty => formatType(data, ty.text).formatted) + .map((ty) => formatType(data, ty.text).formatted) .join(' | ') .replace(/\<\/code\> \| \/g, ` | `); @@ -417,7 +400,7 @@ function enumTable(data: DocsData, i: DocsEnum) { t.addHeader([`Members`, `Value`, `Description`, `Since`]); - i.members.forEach(m => { + i.members.forEach((m) => { t.addRow([ `**\`${m.name}\`**`, formatType(data, m.value).formatted, @@ -436,9 +419,7 @@ function enumTable(data: DocsData, i: DocsEnum) { function getTagText(tags: DocsTagInfo[], tagName: string) { if (tags) { - const tag = tags.find( - t => t.name === tagName && typeof t.text === 'string', - ); + const tag = tags.find((t) => t.name === tagName && typeof t.text === 'string'); if (tag) { return tag.text!; } diff --git a/src/parse.ts b/src/parse.ts index 788e7e4..aa57170 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -33,38 +33,25 @@ export function parse(opts: DocsParseOptions) { const typeAliases: DocsTypeAlias[] = []; const pluginConfigs: DocsInterface[] = []; - tsSourceFiles.forEach(tsSourceFile => { - parseSourceFile( - tsSourceFile, - typeChecker, - interfaces, - typeAliases, - enums, - pluginConfigs, - ); + tsSourceFiles.forEach((tsSourceFile) => { + parseSourceFile(tsSourceFile, typeChecker, interfaces, typeAliases, enums, pluginConfigs); }); return (api: string) => { - let apiInterface = interfaces.find(i => i.name === api) || null; + let apiInterface = interfaces.find((i) => i.name === api) || null; /** * Add methods of import(many is used in `extends`) */ const allImportObject = interfaces - .filter( - i => apiInterface?.importObject.includes(i.name) && i.name !== api, - ) - .map(i => i.importObject); + .filter((i) => apiInterface?.importObject.includes(i.name) && i.name !== api) + .map((i) => i.importObject); const otherMethod = - interfaces - .filter(i => [...new Set(allImportObject.flat())].includes(i.name)) - .map(d => d.methods) || null; + interfaces.filter((i) => [...new Set(allImportObject.flat())].includes(i.name)).map((d) => d.methods) || null; if (apiInterface !== null && otherMethod && otherMethod.length > 0) { - apiInterface.methods = [ - ...new Set(apiInterface?.methods.concat(otherMethod.flat(1))), - ]; + apiInterface.methods = [...new Set(apiInterface?.methods.concat(otherMethod.flat(1)))]; } const data: DocsData = { @@ -88,19 +75,16 @@ function collectInterfaces( i: DocsInterface, interfaces: DocsInterface[], typeAliases: DocsTypeAlias[], - enums: DocsEnum[], + enums: DocsEnum[] ) { - if ( - i.name !== data.api?.name && - !data.interfaces.some(di => di.name === i.name) - ) { + if (i.name !== data.api?.name && !data.interfaces.some((di) => di.name === i.name)) { data.interfaces.push(i); } - i.methods.forEach(m => { + i.methods.forEach((m) => { collectUsed(data, m.complexTypes, interfaces, typeAliases, enums); }); - i.properties.forEach(p => { + i.properties.forEach((p) => { collectUsed(data, p.complexTypes, interfaces, typeAliases, enums); }); } @@ -110,22 +94,22 @@ function collectUsed( complexTypes: string[], interfaces: DocsInterface[], typeAliases: DocsTypeAlias[], - enums: DocsEnum[], + enums: DocsEnum[] ) { - complexTypes.forEach(typeName => { - const fi = interfaces.find(i => i.name === typeName); - if (fi && !data.interfaces.some(i => i.name === fi.name)) { + complexTypes.forEach((typeName) => { + const fi = interfaces.find((i) => i.name === typeName); + if (fi && !data.interfaces.some((i) => i.name === fi.name)) { collectInterfaces(data, fi, interfaces, typeAliases, enums); } - const ei = enums.find(en => en.name === typeName); - if (ei && !data.enums.some(en => en.name === ei.name)) { + const ei = enums.find((en) => en.name === typeName); + if (ei && !data.enums.some((en) => en.name === ei.name)) { data.enums.push(ei); } - const ti = typeAliases.find(ty => ty.name === typeName); - if (ti && !data.typeAliases.some(ty => ty.name === ti.name)) { + const ti = typeAliases.find((ty) => ty.name === typeName); + if (ti && !data.typeAliases.some((ty) => ty.name === ti.name)) { data.typeAliases.push(ti); - ti.types.forEach(type => { + ti.types.forEach((type) => { collectUsed(data, type.complexTypes, interfaces, typeAliases, enums); }); } @@ -138,7 +122,7 @@ function parseSourceFile( interfaces: DocsInterface[], typeAliases: DocsTypeAlias[], enums: DocsEnum[], - pluginConfigs: DocsInterface[], + pluginConfigs: DocsInterface[] ) { const statements = tsSourceFile.statements; const interfaceDeclarations = statements.filter(ts.isInterfaceDeclaration); @@ -146,49 +130,42 @@ function parseSourceFile( const enumDeclarations = statements.filter(ts.isEnumDeclaration); const moduleDeclarations = statements.filter(ts.isModuleDeclaration); - interfaceDeclarations.forEach(interfaceDeclaration => { + interfaceDeclarations.forEach((interfaceDeclaration) => { interfaces.push(getInterface(typeChecker, interfaceDeclaration)); }); - enumDeclarations.forEach(enumDeclaration => { + enumDeclarations.forEach((enumDeclaration) => { enums.push(getEnum(typeChecker, enumDeclaration)); }); - typeAliasDeclarations.forEach(typeAliasDeclaration => { + typeAliasDeclarations.forEach((typeAliasDeclaration) => { typeAliases.push(getTypeAlias(typeChecker, typeAliasDeclaration)); }); moduleDeclarations - .filter(m => m?.name?.text === '@capacitor/cli') - .forEach(moduleDeclaration => { + .filter((m) => m?.name?.text === '@capacitor/cli') + .forEach((moduleDeclaration) => { getPluginsConfig(typeChecker, moduleDeclaration, pluginConfigs); }); } -function getInterface( - typeChecker: ts.TypeChecker, - node: ts.InterfaceDeclaration, -) { +function getInterface(typeChecker: ts.TypeChecker, node: ts.InterfaceDeclaration) { const interfaceName = node.name.text; - const methods = node.members - .filter(ts.isMethodSignature) - .reduce((methods, methodSignature) => { - const m = getInterfaceMethod(typeChecker, methodSignature); - if (m) { - methods.push(m); - } - return methods; - }, [] as DocsInterfaceMethod[]); - - const properties = node.members - .filter(ts.isPropertySignature) - .reduce((properties, properytSignature) => { - const p = getInterfaceProperty(typeChecker, properytSignature); - if (p) { - properties.push(p); - } - return properties; - }, [] as DocsInterfaceProperty[]); + const methods = node.members.filter(ts.isMethodSignature).reduce((methods, methodSignature) => { + const m = getInterfaceMethod(typeChecker, methodSignature); + if (m) { + methods.push(m); + } + return methods; + }, [] as DocsInterfaceMethod[]); + + const properties = node.members.filter(ts.isPropertySignature).reduce((properties, properytSignature) => { + const p = getInterfaceProperty(typeChecker, properytSignature); + if (p) { + properties.push(p); + } + return properties; + }, [] as DocsInterfaceProperty[]); const symbol = typeChecker.getSymbolAtLocation(node.name); const docs = symbol ? serializeSymbol(typeChecker, symbol) : null; @@ -214,7 +191,7 @@ function getEnum(typeChecker: ts.TypeChecker, node: ts.EnumDeclaration) { const en: DocsEnum = { name: enumName, slug: slugify(enumName), - members: node.members.map(enumMember => { + members: node.members.map((enumMember) => { const symbol = typeChecker.getSymbolAtLocation(enumMember.name); const docs = symbol ? serializeSymbol(typeChecker, symbol) : null; @@ -232,10 +209,7 @@ function getEnum(typeChecker: ts.TypeChecker, node: ts.EnumDeclaration) { return en; } -function getTypeAlias( - typeChecker: ts.TypeChecker, - node: ts.TypeAliasDeclaration, -) { +function getTypeAlias(typeChecker: ts.TypeChecker, node: ts.TypeAliasDeclaration) { const symbol = typeChecker.getSymbolAtLocation(node.name); const docs = symbol ? serializeSymbol(typeChecker, symbol) : null; @@ -264,7 +238,7 @@ function getTypeAlias( ]; } } else if (ts.isUnionTypeNode(node.type) && node.type.types) { - typeAlias.types = node.type.types.map(t => { + typeAlias.types = node.type.types.map((t) => { const referencedTypes = new Set(getAllTypeReferences(t)); referencedTypes.delete('Promise'); const typeRef: DocsTypeAliasReference = { @@ -288,20 +262,15 @@ function getTypeAlias( return typeAlias; } -function getInterfaceMethod( - typeChecker: ts.TypeChecker, - methodSignature: ts.MethodSignature, -) { - const flags = - ts.TypeFormatFlags.WriteArrowStyleSignature | - ts.TypeFormatFlags.NoTruncation; +function getInterfaceMethod(typeChecker: ts.TypeChecker, methodSignature: ts.MethodSignature) { + const flags = ts.TypeFormatFlags.WriteArrowStyleSignature | ts.TypeFormatFlags.NoTruncation; const signature = typeChecker.getSignatureFromDeclaration(methodSignature); if (!signature) { return null; } const tags = signature.getJsDocTags(); - if (tags.some(t => t.name === 'hidden')) { + if (tags.some((t) => t.name === 'hidden')) { return null; } @@ -309,20 +278,12 @@ function getInterfaceMethod( const returnTypeNode = typeChecker.typeToTypeNode( returnType, methodSignature, - ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.NoTypeReduction, + ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.NoTypeReduction ); const returnString = typeToString(typeChecker, returnType); - const signatureString = typeChecker.signatureToString( - signature, - methodSignature, - flags, - ts.SignatureKind.Call, - ); + const signatureString = typeChecker.signatureToString(signature, methodSignature, flags, ts.SignatureKind.Call); - const referencedTypes = new Set([ - ...getAllTypeReferences(returnTypeNode), - ...getAllTypeReferences(methodSignature), - ]); + const referencedTypes = new Set([...getAllTypeReferences(returnTypeNode), ...getAllTypeReferences(methodSignature)]); referencedTypes.delete('Promise'); const methodName = methodSignature.name.getText(); @@ -330,7 +291,7 @@ function getInterfaceMethod( const m: DocsInterfaceMethod = { name: methodName, signature: signatureString, - parameters: signature.parameters.map(symbol => { + parameters: signature.parameters.map((symbol) => { const doc = serializeSymbol(typeChecker, symbol); const type = typeChecker.getTypeAtLocation(symbol.valueDeclaration); const param: DocsMethodParam = { @@ -342,9 +303,7 @@ function getInterfaceMethod( }), returns: returnString, tags, - docs: ts.displayPartsToString( - signature.getDocumentationComment(typeChecker), - ), + docs: ts.displayPartsToString(signature.getDocumentationComment(typeChecker)), complexTypes: Array.from(referencedTypes), slug: '', }; @@ -354,10 +313,7 @@ function getInterfaceMethod( return m; } -function getInterfaceProperty( - typeChecker: ts.TypeChecker, - properytSignature: ts.PropertySignature, -) { +function getInterfaceProperty(typeChecker: ts.TypeChecker, properytSignature: ts.PropertySignature) { const symbol = typeChecker.getSymbolAtLocation(properytSignature.name); if (!symbol) { return null; @@ -383,7 +339,7 @@ function getInterfaceProperty( function getPluginsConfig( typeChecker: ts.TypeChecker, moduleDeclaration: ts.ModuleDeclaration, - pluginConfigs: DocsConfigInterface[], + pluginConfigs: DocsConfigInterface[] ) { const body = moduleDeclaration.body as ts.ModuleBlock; if (!Array.isArray(body.statements)) { @@ -392,16 +348,14 @@ function getPluginsConfig( const pluginConfigInterfaces = body.statements.filter( (s: ts.InterfaceDeclaration) => - s?.name?.text === 'PluginsConfig' && - Array.isArray(s?.members) && - s.members.length > 0, + s?.name?.text === 'PluginsConfig' && Array.isArray(s?.members) && s.members.length > 0 ) as ts.InterfaceDeclaration[]; - pluginConfigInterfaces.forEach(pluginConfigInterface => { + pluginConfigInterfaces.forEach((pluginConfigInterface) => { pluginConfigInterface.members .filter(ts.isPropertySignature) - .filter(p => p?.type && (p?.type as ts.TypeLiteralNode).members) - .forEach(properytSignature => { + .filter((p) => p?.type && (p?.type as ts.TypeLiteralNode).members) + .forEach((properytSignature) => { const typeLiteral = properytSignature.type as ts.TypeLiteralNode; const nm = properytSignature.name.getText(); @@ -412,10 +366,10 @@ function getPluginsConfig( slug: slugify(nm), properties: typeLiteral.members .filter(ts.isPropertySignature) - .map(propertySignature => { + .map((propertySignature) => { return getInterfaceProperty(typeChecker, propertySignature); }) - .filter(p => p != null) as DocsInterfaceProperty[], + .filter((p) => p != null) as DocsInterfaceProperty[], docs: docs?.docs || '', }; @@ -426,11 +380,7 @@ function getPluginsConfig( }); } -function typeToString( - checker: ts.TypeChecker, - type: ts.Type, - typeNode?: ts.TypeNode, -) { +function typeToString(checker: ts.TypeChecker, type: ts.Type, typeNode?: ts.TypeNode) { if (typeNode && ts.isTypeReferenceNode(typeNode)) { return typeNode.getText(); } @@ -445,10 +395,7 @@ function typeToString( return checker.typeToString(type, undefined, TYPE_FORMAT_FLAGS); } -function serializeSymbol( - checker: ts.TypeChecker, - symbol: ts.Symbol, -): DocsJsDoc { +function serializeSymbol(checker: ts.TypeChecker, symbol: ts.Symbol): DocsJsDoc { if (!checker || !symbol) { return { tags: [], @@ -456,9 +403,7 @@ function serializeSymbol( }; } return { - tags: symbol - .getJsDocTags() - .map(tag => ({ text: tag.text, name: tag.name })), + tags: symbol.getJsDocTags().map((tag) => ({ text: tag.text, name: tag.name })), docs: ts.displayPartsToString(symbol.getDocumentationComment(checker)), }; } @@ -470,7 +415,7 @@ function getAllTypeReferences(node: ts.Node | undefined) { if (ts.isTypeReferenceNode(node)) { referencedTypes.push(getEntityName(node.typeName)); if (node.typeArguments) { - node.typeArguments.filter(ts.isTypeReferenceNode).forEach(tr => { + node.typeArguments.filter(ts.isTypeReferenceNode).forEach((tr) => { const typeName = tr.typeName as ts.Identifier; if (typeName && typeName.escapedText) { referencedTypes.push(typeName.escapedText.toString()); diff --git a/src/test/fixtures/definitions.ts b/src/test/fixtures/definitions.ts index 5e61ef0..17bac0b 100644 --- a/src/test/fixtures/definitions.ts +++ b/src/test/fixtures/definitions.ts @@ -65,10 +65,7 @@ export interface HapticsPlugin { * * @since 1.0.0 */ - addListener( - eventName: 'vibrate', - listenerFunc: VibrateListener, - ): Promise; + addListener(eventName: 'vibrate', listenerFunc: VibrateListener): Promise; /** * Add a listener. Callback has VibrateOptions. diff --git a/src/test/fixtures/index.ts b/src/test/fixtures/index.ts index 76ad0fa..54c7532 100644 --- a/src/test/fixtures/index.ts +++ b/src/test/fixtures/index.ts @@ -2,10 +2,7 @@ * Mocked for testing purposes */ import type { HapticsPlugin } from './definitions'; -import type { - HapticsImpactStyle, - HapticsNotificationType, -} from './definitions'; +import type { HapticsImpactStyle, HapticsNotificationType } from './definitions'; const Haptics: HapticsPlugin = {} as any; diff --git a/src/test/formatting.spec.ts b/src/test/formatting.spec.ts index 31aca1c..eccc5f6 100644 --- a/src/test/formatting.spec.ts +++ b/src/test/formatting.spec.ts @@ -45,40 +45,30 @@ describe('formatting', () => { }); it('formatDescription', () => { - const r = formatDescription( - d, - `Hey SomeInterface and SomeInterface.prop and SomeEnum and SomeEnum.Value!`, - ); + const r = formatDescription(d, `Hey SomeInterface and SomeInterface.prop and SomeEnum and SomeEnum.Value!`); expect(r).toEqual( - `Hey SomeInterface and SomeInterface.prop and SomeEnum and SomeEnum.Value!`, + `Hey SomeInterface and SomeInterface.prop and SomeEnum and SomeEnum.Value!` ); }); it('formatType interface promise w/ union', () => { - const r = formatType( - d, - `Promise>`, - ); + const r = formatType(d, `Promise>`); expect(r.type).toEqual(`Promise>`); expect(r.formatted).toEqual( - `Promise<SomeInterface | SomeEnum | Promise<void>>`, + `Promise<SomeInterface | SomeEnum | Promise<void>>` ); }); it('formatType interface promise', () => { const r = formatType(d, `Promise`); expect(r.type).toEqual(`Promise`); - expect(r.formatted).toEqual( - `Promise<SomeInterface>`, - ); + expect(r.formatted).toEqual(`Promise<SomeInterface>`); }); it('formatType interface', () => { const r = formatType(d, `SomeInterface`); expect(r.type).toEqual(`SomeInterface`); - expect(r.formatted).toEqual( - `SomeInterface`, - ); + expect(r.formatted).toEqual(`SomeInterface`); }); it('formatType remove undefined', () => { @@ -130,12 +120,7 @@ describe('formatting', () => { 'number', '>', ]); - expect(tokenize('Promise')).toEqual([ - 'Promise', - '<', - 'string', - '>', - ]); + expect(tokenize('Promise')).toEqual(['Promise', '<', 'string', '>']); expect(tokenize('Hello')).toEqual(['Hello']); expect(tokenize('')).toEqual([]); }); diff --git a/src/test/parse.spec.ts b/src/test/parse.spec.ts index e2c614a..1a6e8cf 100644 --- a/src/test/parse.spec.ts +++ b/src/test/parse.spec.ts @@ -6,8 +6,7 @@ describe('parse', () => { tsconfigPath: path.join(__dirname, 'fixtures', 'tsconfig.json'), }); - const { api, interfaces, enums, typeAliases, pluginConfigs } = - apiFinder('HapticsPlugin'); + const { api, interfaces, enums, typeAliases, pluginConfigs } = apiFinder('HapticsPlugin'); it('api', () => { expect(api.name).toBe(`HapticsPlugin`); @@ -17,7 +16,7 @@ describe('parse', () => { expect(typeAliases).toHaveLength(2); expect(enums).toHaveLength(2); - const iNames = interfaces.map(i => i.name); + const iNames = interfaces.map((i) => i.name); expect(iNames).not.toContain(`HapticsPlugin`); // main api expect(iNames).not.toContain(`HapticsImpactStyle`); // enum expect(iNames).not.toContain(`HapticsNotificationType`); // enum @@ -28,12 +27,12 @@ describe('parse', () => { expect(iNames).toContain(`VibrateOptions`); expect(iNames).toContain(`VibrateListenerEvent`); - const tNames = typeAliases.map(t => t.name); + const tNames = typeAliases.map((t) => t.name); expect(tNames).toContain(`VibrateListener`); expect(tNames).not.toContain(`VibrateListenerEvent`); expect(tNames).not.toContain(`VibrateOptions`); - const eNames = enums.map(i => i.name); + const eNames = enums.map((i) => i.name); expect(eNames).not.toContain(`HapticsPlugin`); // main api expect(eNames).toContain(`HapticsImpactStyle`); // enum expect(eNames).toContain(`HapticsNotificationType`); // enum @@ -51,9 +50,7 @@ describe('parse', () => { expect(enums[0].members).toHaveLength(3); expect(enums[0].members[0].name).toBe(`Heavy`); expect(enums[0].members[0].value).toBe(`'HEAVY'`); - expect(enums[0].members[0].docs).toBe( - `A collision between small, light user interface elements`, - ); + expect(enums[0].members[0].docs).toBe(`A collision between small, light user interface elements`); expect(enums[0].members[0].tags).toHaveLength(1); expect(enums[0].members[0].tags[0].name).toBe(`since`); expect(enums[0].members[0].tags[0].text).toBe(`1.0.0`); @@ -66,9 +63,7 @@ describe('parse', () => { expect(m0.name).toBe(`impact`); expect(m0.docs).toBe(`Trigger a haptics "impact" feedback`); expect(m0.slug).toBe(`impact`); - expect(m0.signature).toBe( - `(options: HapticsImpactOptions, x?: number | undefined) => Promise`, - ); + expect(m0.signature).toBe(`(options: HapticsImpactOptions, x?: number | undefined) => Promise`); expect(m0.returns).toBe(`Promise`); expect(m0.parameters).toHaveLength(2); expect(m0.parameters[0].name).toBe(`options`); @@ -91,9 +86,7 @@ describe('parse', () => { expect(m3.name).toBe(`addListener`); expect(m3.slug).toBe(`addlistenervibrate`); expect(m3.docs).toBe(`Add a listener. Callback has VibrateOptions.`); - expect(m3.signature).toBe( - `(eventName: 'vibrate', listenerFunc: VibrateListener) => Promise`, - ); + expect(m3.signature).toBe(`(eventName: 'vibrate', listenerFunc: VibrateListener) => Promise`); expect(m3.complexTypes).toContain(`VibrateListener`); expect(m3.parameters).toHaveLength(2); expect(m3.parameters[1].name).toBe('listenerFunc'); @@ -102,15 +95,13 @@ describe('parse', () => { const m4 = api.methods[4]; expect(m4.name).toBe(`removeAllListeners`); - expect(m4.docs).toBe( - `Remove all the listeners that are attached to this plugin`, - ); + expect(m4.docs).toBe(`Remove all the listeners that are attached to this plugin`); expect(m4.signature).toBe(`() => void`); expect(m4.returns).toBe(`void`); }); it('interface properties', () => { - const i = interfaces.find(i => i.name === 'HapticsImpactOptions'); + const i = interfaces.find((i) => i.name === 'HapticsImpactOptions'); expect(i.slug).toBe(`hapticsimpactoptions`); expect(i.methods).toHaveLength(0); expect(i.properties).toHaveLength(3); @@ -124,26 +115,26 @@ describe('parse', () => { expect(p0.complexTypes[0]).toBe(`HapticsImpactStyle`); expect(p0.type).toBe(`HapticsImpactStyle`); - const i1 = interfaces.find(i => i.name === 'VibrateListenerEvent'); + const i1 = interfaces.find((i) => i.name === 'VibrateListenerEvent'); expect(i1.name).toBe('VibrateListenerEvent'); expect(i1.properties).toHaveLength(3); expect(i1.properties[2].type).toBe('RepeatSchedule'); }); it('type typeAliases', () => { - const t0 = typeAliases.find(i => i.name === 'VibrateListener'); + const t0 = typeAliases.find((i) => i.name === 'VibrateListener'); expect(t0.slug).toBe(`vibratelistener`); expect(t0.docs).toBe(`The vibrate listener callback function.`); expect(t0.types).toHaveLength(1); - const t1 = typeAliases.find(i => i.name === 'RepeatSchedule'); + const t1 = typeAliases.find((i) => i.name === 'RepeatSchedule'); expect(t1.slug).toBe(`repeatschedule`); expect(t1.types).toHaveLength(4); }); it('Plugins Config', () => { expect(pluginConfigs).toHaveLength(1); - const p = pluginConfigs.find(i => i.name === `Haptics`); + const p = pluginConfigs.find((i) => i.name === `Haptics`); expect(p.slug).toBe(`haptics`); expect(p.docs).toBe(`Haptics can be configured with this options:`); diff --git a/src/transpile.ts b/src/transpile.ts index fe42a55..c01e2c3 100644 --- a/src/transpile.ts +++ b/src/transpile.ts @@ -8,14 +8,12 @@ export function getTsProgram(opts: DocsParseOptions) { let options: ts.CompilerOptions; if (typeof opts.tsconfigPath === 'string') { - const configResult = ts.readConfigFile(opts.tsconfigPath, p => - fs.readFileSync(p, 'utf-8'), - ); + const configResult = ts.readConfigFile(opts.tsconfigPath, (p) => fs.readFileSync(p, 'utf-8')); if (configResult.error) { throw new Error( `Unable to read tsconfig path: "${opts.tsconfigPath}". ` + - ts.flattenDiagnosticMessageText(configResult.error.messageText, '\n'), + ts.flattenDiagnosticMessageText(configResult.error.messageText, '\n') ); } const tsconfigDir = path.dirname(opts.tsconfigPath); @@ -24,7 +22,7 @@ export function getTsProgram(opts: DocsParseOptions) { }); options = configResult.config.compilerOptions; } else if (Array.isArray(opts.inputFiles) && opts.inputFiles.length > 0) { - opts.inputFiles.forEach(i => { + opts.inputFiles.forEach((i) => { if (!path.isAbsolute(i)) { throw new Error(`inputFile "${i}" must be absolute`); } @@ -32,9 +30,7 @@ export function getTsProgram(opts: DocsParseOptions) { options = {}; rootNames = [...opts.inputFiles]; } else { - throw new Error( - `Either "tsconfigPath" or "inputFiles" option must be provided`, - ); + throw new Error(`Either "tsconfigPath" or "inputFiles" option must be provided`); } // same defaults as transpile() for faster parse-only transpiling