diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b947077 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/.prettierrc b/.prettierrc index 950d7f9..775cd9a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,3 +1,7 @@ { - "endOfLine": "lf" + "endOfLine": "lf", + "singleQuote": false, + "trailingComma": "all", + "tabWidth": 4, + "semi": true } diff --git a/package-lock.json b/package-lock.json index 0cb6186..39083e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1219,9 +1219,9 @@ "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", "dev": true }, "prettier-linter-helpers": { diff --git a/package.json b/package.json index 1ce78b7..f8e6116 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-react": "^7.20.0", - "prettier": "^2.0.5", + "prettier": "=2.2.1", "ts-node": "^8.10.2", "typescript": "~3.9.3" }, diff --git a/src/build.ts b/src/build.ts index beeaeb2..c36e521 100644 --- a/src/build.ts +++ b/src/build.ts @@ -27,7 +27,7 @@ const renderPagesToHtml = async ({ const pageSrc = require(srcPath); if (!("page" in pageSrc)) { throw new Error( - `page source at ${srcPath} does not export a "page" variable` + `page source at ${srcPath} does not export a "page" variable`, ); } let compiledHtml; @@ -35,7 +35,7 @@ const renderPagesToHtml = async ({ compiledHtml = renderPage(pageSrc.page()); } catch (error) { throw new Error( - `failed to compile ${srcPath}: ${error.stack ?? error}` + `failed to compile ${srcPath}: ${error.stack ?? error}`, ); } const relPath = path.relative(pagesDir, path.dirname(srcPath)); @@ -48,7 +48,7 @@ const renderPagesToHtml = async ({ (async () => { await fs.mkdir(path.dirname(destPath), { recursive: true }); await fs.writeFile(destPath, compiledHtml); - })() + })(), ); } await Promise.all(deferred); @@ -73,7 +73,7 @@ const copyStaticAssets = async ({ (async () => { await fs.mkdir(path.dirname(destPath), { recursive: true }); await fs.copyFile(assetPath, destPath); - })() + })(), ); } await Promise.all(deferred); diff --git a/src/cli/commands/dev.ts b/src/cli/commands/dev.ts index bc2f97e..63b9374 100644 --- a/src/cli/commands/dev.ts +++ b/src/cli/commands/dev.ts @@ -26,7 +26,7 @@ const injectLiveReloadScript = (htmlContents: string, port: number): string => }; - ` + `, ); const guessMimeType = (ext: string): string => { @@ -126,7 +126,7 @@ const portFromServer = (server: Pick): number => { } if (typeof addrInfo === "string") { throw new Error( - `server address is a string (this should never happen!)` + `server address is a string (this should never happen!)`, ); } return addrInfo.port; @@ -187,7 +187,7 @@ const startHttpServer = async (publicDir: string): Promise => { }; const startWebSocketServer = async ( - httpServer: http.Server + httpServer: http.Server, ): Promise => { // Attempt to load the ws module, aborting if it isn't available. let ws; @@ -209,7 +209,7 @@ const startWebSocketServer = async ( const watchFolders = async ( folders: string[], - listener: (eventType: "update" | "remove", fileName: string) => void + listener: (eventType: "update" | "remove", fileName: string) => void, ): Promise => { // Try to load node-watch, falling back to fs watch if node-watch isn't // available. @@ -223,7 +223,7 @@ const watchFolders = async ( } console.warn( `'node-watch' module not found, falling back to fs.watch (may ` + - `result in file watch issues on some OSes)` + `result in file watch issues on some OSes)`, ); } // NOTE: fs.watch has significant cross-platform issues, including @@ -279,7 +279,7 @@ const devCommand: Command = { const httpServer = await startHttpServer(outDir); const wsServer = await startWebSocketServer(httpServer); const watchedFolders = config.watch.filter((filePath) => - existsSync(filePath) + existsSync(filePath), ); await watchFolders(watchedFolders, async (event, filePath) => { console.log(`${filePath}:${event} triggering rebuild...`); diff --git a/src/cli/index.ts b/src/cli/index.ts index f7a6151..3d198ef 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -24,7 +24,7 @@ interface Options { } const parseArgs = ( - args: string[] + args: string[], ): { options: Options; commandName?: string; commandArgs: string[] } => { const options: Options = { showHelp: false, @@ -46,7 +46,7 @@ const parseArgs = ( if (moduleName == null) { throw new UsageError( `-r requires a valid module name`, - globalHelpText + globalHelpText, ); } options.require.push(moduleName); @@ -84,7 +84,7 @@ const _main = async (args: string[]): Promise => { default: throw new UsageError( `unknown command ${commandName}`, - globalHelpText + globalHelpText, ); } // NOTE: Should this just delegate to the command? diff --git a/src/component.ts b/src/component.ts index 18db150..c95d599 100644 --- a/src/component.ts +++ b/src/component.ts @@ -41,7 +41,7 @@ export interface Component

{ ( props: P & { children?: Element[]; - } + }, ): HTMLElement; } diff --git a/src/create-element.ts b/src/create-element.ts index 9e239cd..d46308d 100644 --- a/src/create-element.ts +++ b/src/create-element.ts @@ -60,7 +60,7 @@ export function createElement( typeof value !== "boolean" ) { console.warn( - `non-primitive attribute ${key} = ${JSON.stringify(value)}` + `non-primitive attribute ${key} = ${JSON.stringify(value)}`, ); continue; } diff --git a/src/render.ts b/src/render.ts index 174461f..4566d70 100644 --- a/src/render.ts +++ b/src/render.ts @@ -63,7 +63,7 @@ const startTag = (elem: HTMLElement): string => { output += ` ${normalizedAttrName}=""`; } else { output += ` ${normalizedAttrName}="${escapeAttr( - attrValue.toString() + attrValue.toString(), )}"`; } } @@ -94,13 +94,13 @@ export const renderPage = (rootElem: Element): string => { if (typeof rootElem !== "object" || !("tag" in rootElem)) { throw new Error( `root page element must be a valid HTMLElement, got ${JSON.stringify( - rootElem - )}` + rootElem, + )}`, ); } if (rootElem.tag.toLowerCase() !== "html") { throw new Error( - `attempted to render page with non-HTML root element ${rootElem.tag}` + `attempted to render page with non-HTML root element ${rootElem.tag}`, ); } diff --git a/src/utils/index.ts b/src/utils/index.ts index 83f5f0a..2cce921 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -16,7 +16,7 @@ export { decacheModule } from "./decache-module"; * @return Generator that yields the files found while walking the directory. */ export const walkDir = async function* ( - dirPath: string + dirPath: string, ): AsyncGenerator { const dirEnts = await fs.readdir(dirPath, { withFileTypes: true }); for (const dirEnt of dirEnts) { diff --git a/test/e2e/build.tsx b/test/e2e/build.tsx index aafb10c..9daba49 100644 --- a/test/e2e/build.tsx +++ b/test/e2e/build.tsx @@ -7,7 +7,11 @@ import { promises as fs } from "fs"; import * as path from "path"; import { - npmCmd, runCommand, WEBSNACKS_BIN_PATH, WEBSNACKS_REPO_ROOT, withTempDir + npmCmd, + runCommand, + WEBSNACKS_BIN_PATH, + WEBSNACKS_REPO_ROOT, + withTempDir, } from "../helpers/e2e"; import { testSuite } from "../lib"; @@ -35,7 +39,7 @@ testSuite("build command", ({ test }) => { }), { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "websnacks.ts"), @@ -48,7 +52,7 @@ testSuite("build command", ({ test }) => { `, { encoding: "utf8", - } + }, ); const pagesPath = path.join(tempDirPath, "pages"); await fs.mkdir(pagesPath); @@ -60,7 +64,7 @@ testSuite("build command", ({ test }) => { `, { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "package.json"), @@ -69,7 +73,7 @@ testSuite("build command", ({ test }) => { websnacks: `file:${WEBSNACKS_REPO_ROOT}`, }, }), - { encoding: "utf8" } + { encoding: "utf8" }, ); await runCommand(npmCmd, ["install", "--silent"], { cwd: tempDirPath, @@ -79,7 +83,7 @@ testSuite("build command", ({ test }) => { [WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"], { cwd: tempDirPath, - } + }, ); await cmd.complete; }); @@ -108,7 +112,7 @@ testSuite("build command", ({ test }) => { }), { encoding: "utf8", - } + }, ); const pagesPath = path.join(tempDirPath, "pages"); await fs.mkdir(pagesPath); @@ -120,7 +124,7 @@ testSuite("build command", ({ test }) => { `, { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "package.json"), @@ -129,7 +133,7 @@ testSuite("build command", ({ test }) => { websnacks: `file:${WEBSNACKS_REPO_ROOT}`, }, }), - { encoding: "utf8" } + { encoding: "utf8" }, ); await runCommand(npmCmd, ["install", "--silent"], { cwd: tempDirPath, @@ -139,7 +143,7 @@ testSuite("build command", ({ test }) => { [WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"], { cwd: tempDirPath, - } + }, ); await cmd.complete; }); diff --git a/test/e2e/dev.tsx b/test/e2e/dev.tsx index d23e399..a32c183 100644 --- a/test/e2e/dev.tsx +++ b/test/e2e/dev.tsx @@ -7,7 +7,12 @@ import { promises as fs } from "fs"; import * as path from "path"; import { - npmCmd, runCommand, wait, WEBSNACKS_BIN_PATH, WEBSNACKS_REPO_ROOT, withTempDir + npmCmd, + runCommand, + wait, + WEBSNACKS_BIN_PATH, + WEBSNACKS_REPO_ROOT, + withTempDir, } from "../helpers/e2e"; import { testSuite } from "../lib"; @@ -35,7 +40,7 @@ testSuite("dev command", ({ test, expect }) => { }), { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "websnacks.ts"), @@ -48,7 +53,7 @@ testSuite("dev command", ({ test, expect }) => { `, { encoding: "utf8", - } + }, ); const pagesPath = path.join(tempDirPath, "pages"); await fs.mkdir(pagesPath); @@ -60,7 +65,7 @@ testSuite("dev command", ({ test, expect }) => { `, { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "package.json"), @@ -69,7 +74,7 @@ testSuite("dev command", ({ test, expect }) => { websnacks: `file:${WEBSNACKS_REPO_ROOT}`, }, }), - { encoding: "utf8" } + { encoding: "utf8" }, ); await runCommand(npmCmd, ["install", "--silent"], { cwd: tempDirPath, @@ -79,7 +84,7 @@ testSuite("dev command", ({ test, expect }) => { [WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"], { cwd: tempDirPath, - } + }, ); // FIXME: This test is a bit brittle due to relying on timeouts. await wait(10_000); @@ -112,7 +117,7 @@ testSuite("dev command", ({ test, expect }) => { }), { encoding: "utf8", - } + }, ); const pagesPath = path.join(tempDirPath, "pages"); await fs.mkdir(pagesPath); @@ -124,7 +129,7 @@ testSuite("dev command", ({ test, expect }) => { `, { encoding: "utf8", - } + }, ); await fs.writeFile( path.join(tempDirPath, "package.json"), @@ -133,7 +138,7 @@ testSuite("dev command", ({ test, expect }) => { websnacks: `file:${WEBSNACKS_REPO_ROOT}`, }, }), - { encoding: "utf8" } + { encoding: "utf8" }, ); await runCommand(npmCmd, ["install", "--silent"], { cwd: tempDirPath, @@ -143,7 +148,7 @@ testSuite("dev command", ({ test, expect }) => { [WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"], { cwd: tempDirPath, - } + }, ); // FIXME: This test is a bit brittle due to relying on timeouts. await wait(10_000); diff --git a/test/helpers/e2e.ts b/test/helpers/e2e.ts index 1e5cdec..de31b74 100644 --- a/test/helpers/e2e.ts +++ b/test/helpers/e2e.ts @@ -36,7 +36,7 @@ const TEMP_PATH = path.resolve(__dirname, "..", "..", ".temp"); * directory path as its only argument. */ export const withTempDir = async ( - op: (tempDirPath: string) => Promise | void + op: (tempDirPath: string) => Promise | void, ): Promise => { await fs.mkdir(TEMP_PATH, { recursive: true }); const tempDirPath = await fs.mkdtemp(`${TEMP_PATH}/`); @@ -57,7 +57,7 @@ export const WEBSNACKS_REPO_ROOT = path.resolve(__dirname, "..", ".."); export const WEBSNACKS_BIN_PATH = path.join( WEBSNACKS_REPO_ROOT, "bin", - "websnacks.js" + "websnacks.js", ); /** @@ -113,7 +113,7 @@ const DEFAULT_CLI_OPTIONS = { export const runCommand = ( command: string, args: string[] = [], - options?: CliOptions + options?: CliOptions, ): AsyncCommand => { const optionsWithDefaults = { ...DEFAULT_CLI_OPTIONS, ...options }; const process = spawn(command, args, { @@ -138,8 +138,8 @@ export const runCommand = ( process.kill(); reject( new Error( - `max timeout of ${optionsWithDefaults.timeoutMs}ms reached` - ) + `max timeout of ${optionsWithDefaults.timeoutMs}ms reached`, + ), ); }, optionsWithDefaults.timeoutMs); process.on("exit", (code) => { diff --git a/test/lib/expect.ts b/test/lib/expect.ts index 3744310..1a4bd8e 100644 --- a/test/lib/expect.ts +++ b/test/lib/expect.ts @@ -10,7 +10,7 @@ class ExpectError extends Error { super( `${reason}\n` + `\texpected: ${displayValue(expected)}\n` + - `\tactual : ${displayValue(actual)}` + `\tactual : ${displayValue(actual)}`, ); } } @@ -50,7 +50,7 @@ export class Expect { throw new ExpectError( `value does not equal expected`, expected, - this.value + this.value, ); } } @@ -73,7 +73,7 @@ export class StringExpect extends Expect { throw new ExpectError( `value does not match expected pattern`, pattern, - this.value + this.value, ); } } @@ -91,7 +91,7 @@ export class StringExpect extends Expect { throw new ExpectError( `value does not start with expected prefix`, prefix, - this.value + this.value, ); } } @@ -109,7 +109,7 @@ export class StringExpect extends Expect { throw new ExpectError( `value does not end with expected suffix`, suffix, - this.value + this.value, ); } } @@ -138,14 +138,14 @@ export class FunctionExpect extends Expect<() => T> { throw new ExpectError( `function threw non-Error value`, pattern, - error + error, ); } if (!matches(error.message, pattern)) { throw new ExpectError( `thrown Error's message does not match pattern`, pattern, - error.message + error.message, ); } return; @@ -153,7 +153,7 @@ export class FunctionExpect extends Expect<() => T> { throw new ExpectError( `function did not throw expected error`, pattern, - null + null, ); } } diff --git a/test/lib/harness.ts b/test/lib/harness.ts index 3650145..57034c9 100644 --- a/test/lib/harness.ts +++ b/test/lib/harness.ts @@ -40,7 +40,7 @@ const runTest = async (test: Test): Promise => { error instanceof Error ? error : new Error( - `threw non-error object: ${displayValue(error)}` + `threw non-error object: ${displayValue(error)}`, ), }; } @@ -86,7 +86,7 @@ export interface TestSuiteContext { */ export const testSuite = ( suiteName: string, - def: (ctx: TestSuiteContext) => void + def: (ctx: TestSuiteContext) => void, ): void => { const tests: Test[] = []; const test = (name: string, runTest: () => void | Promise): void => { @@ -104,14 +104,14 @@ export const testSuite = ( if (testResult.result === "fail") { console.error( `[TEST FAILURE] "${suiteName}": "${testResult.testName}": ` + - `${testResult.error.stack}\n` + `${testResult.error.stack}\n`, ); continue; } passed += 1; } console.info( - `[TEST] suite "${suiteName}": ${passed} of ${tests.length} succeeded\n\n` + `[TEST] suite "${suiteName}": ${passed} of ${tests.length} succeeded\n\n`, ); if (passed < tests.length) { process.exitCode = 1; diff --git a/test/lib/utils.ts b/test/lib/utils.ts index cdccd73..76896c5 100644 --- a/test/lib/utils.ts +++ b/test/lib/utils.ts @@ -33,7 +33,7 @@ const areArraysEqual = (a: T[], b: T[]): boolean => { const areObjectsEqual = >( a: T, - b: T + b: T, ): boolean => { const aKeys = Object.keys(a) as Array; const bKeys = Object.keys(b) as Array; @@ -67,7 +67,7 @@ export const areEqual = (a: T, b: T): boolean => { if (typeof a === "object" && typeof b === "object") { return areObjectsEqual( a as Record, - b as Record + b as Record, ); } return a === b; diff --git a/test/test-suites/rendering.tsx b/test/test-suites/rendering.tsx index ef567dd..7caa8b2 100644 --- a/test/test-suites/rendering.tsx +++ b/test/test-suites/rendering.tsx @@ -10,7 +10,7 @@ import { testSuite } from "../lib"; testSuite("renderPage", ({ test, expect }) => { test("throws an Error when root elem is not html tag", () => { expect(() => renderPage(

)).toThrowErrorMatching( - "attempted to render page with non-HTML root element div" + "attempted to render page with non-HTML root element div", ); }); @@ -21,10 +21,10 @@ testSuite("renderPage", ({ test, expect }) => { test("escapes HTML in tag names", () => { const html = renderPage( - {createElement("div> + {createElement("div>, ); expect(html).toEqual( - "" + "", ); }); @@ -32,10 +32,10 @@ testSuite("renderPage", ({ test, expect }) => { const html = renderPage(
- + , ); expect(html).toEqual( - '
' + '
', ); }); @@ -48,17 +48,17 @@ testSuite("renderPage", ({ test, expect }) => {
- + , ); expect(html).toEqual( - "
" + "
", ); }); test("renders text nodes", () => { const html = renderPage(There are three lights!); expect(html).toEqual( - "There are three lights!" + "There are three lights!", ); }); @@ -80,10 +80,10 @@ testSuite("renderPage", ({ test, expect }) => { ))}{" "} lights! - + , ); expect(html).toEqual( - "There are
1
2
3
lights!" + "There are
1
2
3
lights!", ); }); @@ -97,10 +97,10 @@ testSuite("renderPage", ({ test, expect }) => { const html = renderPage( There are ! - + , ); expect(html).toEqual( - "There are
3 lights
!" + "There are
3 lights
!", ); }); @@ -111,10 +111,10 @@ testSuite("renderPage", ({ test, expect }) => {
test of
fragments
- + , ); expect(html).toEqual( - "
test of
fragments
" + "
test of
fragments
", ); }); });