chore: resolve linting errors & warnings

This commit is contained in:
M. George Hansen 2020-06-01 23:29:59 -07:00
parent 3649147824
commit dcbc07021d
11 changed files with 177 additions and 144 deletions

View file

@ -1,11 +1,19 @@
{ {
"root": true, "root": true,
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
}
},
"plugins": ["@typescript-eslint", "prettier"], "plugins": ["@typescript-eslint", "prettier"],
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended" "plugin:prettier/recommended"
] ],
"rules": {
"@typescript-eslint/no-namespace": "off"
}
} }

View file

@ -23,6 +23,7 @@ const renderPagesToHtml = async ({
// Ensure that we don't cache page modules when running in dev server. // Ensure that we don't cache page modules when running in dev server.
purgeModuleAndDepsFromCache(srcPath); purgeModuleAndDepsFromCache(srcPath);
// eslint-disable-next-line @typescript-eslint/no-var-requires
const pageSrc = require(srcPath); const pageSrc = require(srcPath);
if (!("page" in pageSrc)) { if (!("page" in pageSrc)) {
throw new Error( throw new Error(

View file

@ -36,11 +36,12 @@ const parseArgs = (
const opt = args.shift(); const opt = args.shift();
switch (opt) { switch (opt) {
case "-h": case "-h":
case "--help": case "--help": {
options.showHelp = true; options.showHelp = true;
break; break;
}
case "-r": case "-r":
case "--require": case "--require": {
const moduleName = args.shift(); const moduleName = args.shift();
if (moduleName == null) { if (moduleName == null) {
throw new UsageError( throw new UsageError(
@ -50,6 +51,7 @@ const parseArgs = (
} }
options.require.push(moduleName); options.require.push(moduleName);
break; break;
}
default: default:
throw new UsageError(`unknown option ${opt}`, globalHelpText); throw new UsageError(`unknown option ${opt}`, globalHelpText);
} }

View file

@ -30,7 +30,9 @@ export type Element = HTMLElement | string | boolean | undefined | null;
/** /**
* Custom HTMLElement factory that can be parameterized by props. * Custom HTMLElement factory that can be parameterized by props.
*/ */
export interface Component<P extends object = {}> { export interface Component<
P extends Record<string, unknown> = Record<string, never>
> {
( (
props: P & { props: P & {
children?: Element[]; children?: Element[];

View file

@ -47,6 +47,7 @@ export interface Config {
watch: string[]; watch: string[];
} }
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {}; const noop = () => {};
/** /**

View file

@ -16,7 +16,7 @@ import { HTMLAttributes } from "./jsx";
* *
* @return Fully-realized HTMLElement, ready for rendering. * @return Fully-realized HTMLElement, ready for rendering.
*/ */
export function createElement<P extends object>( export function createElement<P extends Record<string, unknown>>(
comp: Component<P>, comp: Component<P>,
props: P, props: P,
...children: Element[] ...children: Element[]
@ -37,8 +37,8 @@ export function createElement(
...children: Element[] ...children: Element[]
): HTMLElement; ): HTMLElement;
export function createElement( export function createElement(
type: string | Component<any>, type: string | Component<Record<string, unknown>>,
props: (HTMLAttributes & Record<string, any>) | null, props: HTMLAttributes | Record<string, unknown> | null,
...children: Element[] ...children: Element[]
): HTMLElement { ): HTMLElement {
// Flatten the children array so we can accept arrays as children. // Flatten the children array so we can accept arrays as children.
@ -50,5 +50,19 @@ export function createElement(
if (type !== type.toLowerCase()) { if (type !== type.toLowerCase()) {
console.warn(`constructed HTML5 tag with non-lowercase name ${type}`); console.warn(`constructed HTML5 tag with non-lowercase name ${type}`);
} }
return { tag: type, attributes: props || {}, children: normalizedChildren }; const attrs: Record<string, string | number | boolean> = {};
for (const [key, value] of Object.entries(props || {})) {
if (
typeof value !== "string" &&
typeof value !== "number" &&
typeof value !== "boolean"
) {
console.warn(
`non-primitive attribute ${key} = ${JSON.stringify(value)}`
);
continue;
}
attrs[key] = value;
}
return { tag: type, attributes: attrs, children: normalizedChildren };
} }

View file

@ -6,13 +6,4 @@
export { HTMLElement, Component } from "./component"; export { HTMLElement, Component } from "./component";
export { UserConfig as Config } from "./config"; export { UserConfig as Config } from "./config";
export { createElement } from "./create-element"; export { createElement } from "./create-element";
export * from "./jsx";
import { HTMLElement } from "./component";
import { IntrinsicElements as JsxIntrinsics } from "./jsx";
declare global {
namespace JSX {
type Element = HTMLElement;
type IntrinsicElements = JsxIntrinsics;
}
}

View file

@ -3,10 +3,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { HTMLElement } from "./component";
export interface RdfaAttributes { export interface RdfaAttributes {
about?: string; about?: string;
datatype?: string; datatype?: string;
inlist?: any; inlist?: boolean;
prefix?: string; prefix?: string;
property?: string; property?: string;
resource?: string; resource?: string;
@ -60,7 +63,7 @@ export interface HTMLAttributes extends RdfaAttributes, MicrodataAttributes {
dir?: "auto" | "rtl" | "ltr"; dir?: "auto" | "rtl" | "ltr";
disabled?: boolean; disabled?: boolean;
disableRemotePlayback?: boolean; disableRemotePlayback?: boolean;
download?: any; download?: boolean | string;
draggable?: boolean; draggable?: boolean;
encType?: string; encType?: string;
form?: string; form?: string;
@ -154,120 +157,125 @@ export interface HTMLAttributes extends RdfaAttributes, MicrodataAttributes {
wrap?: string; wrap?: string;
} }
export interface IntrinsicElements { declare global {
a: HTMLAttributes; namespace JSX {
abbr: HTMLAttributes; type Element = HTMLElement;
address: HTMLAttributes; type IntrinsicElements = {
area: HTMLAttributes; a: HTMLAttributes;
article: HTMLAttributes; abbr: HTMLAttributes;
aside: HTMLAttributes; address: HTMLAttributes;
audio: HTMLAttributes; area: HTMLAttributes;
b: HTMLAttributes; article: HTMLAttributes;
base: HTMLAttributes; aside: HTMLAttributes;
bdi: HTMLAttributes; audio: HTMLAttributes;
bdo: HTMLAttributes; b: HTMLAttributes;
big: HTMLAttributes; base: HTMLAttributes;
blockquote: HTMLAttributes; bdi: HTMLAttributes;
body: HTMLAttributes; bdo: HTMLAttributes;
br: HTMLAttributes; big: HTMLAttributes;
button: HTMLAttributes; blockquote: HTMLAttributes;
canvas: HTMLAttributes; body: HTMLAttributes;
caption: HTMLAttributes; br: HTMLAttributes;
cite: HTMLAttributes; button: HTMLAttributes;
code: HTMLAttributes; canvas: HTMLAttributes;
col: HTMLAttributes; caption: HTMLAttributes;
colgroup: HTMLAttributes; cite: HTMLAttributes;
data: HTMLAttributes; code: HTMLAttributes;
datalist: HTMLAttributes; col: HTMLAttributes;
dd: HTMLAttributes; colgroup: HTMLAttributes;
del: HTMLAttributes; data: HTMLAttributes;
details: HTMLAttributes; datalist: HTMLAttributes;
dfn: HTMLAttributes; dd: HTMLAttributes;
dialog: HTMLAttributes; del: HTMLAttributes;
div: HTMLAttributes; details: HTMLAttributes;
dl: HTMLAttributes; dfn: HTMLAttributes;
dt: HTMLAttributes; dialog: HTMLAttributes;
em: HTMLAttributes; div: HTMLAttributes;
embed: HTMLAttributes; dl: HTMLAttributes;
fieldset: HTMLAttributes; dt: HTMLAttributes;
figcaption: HTMLAttributes; em: HTMLAttributes;
figure: HTMLAttributes; embed: HTMLAttributes;
footer: HTMLAttributes; fieldset: HTMLAttributes;
form: HTMLAttributes; figcaption: HTMLAttributes;
h1: HTMLAttributes; figure: HTMLAttributes;
h2: HTMLAttributes; footer: HTMLAttributes;
h3: HTMLAttributes; form: HTMLAttributes;
h4: HTMLAttributes; h1: HTMLAttributes;
h5: HTMLAttributes; h2: HTMLAttributes;
h6: HTMLAttributes; h3: HTMLAttributes;
head: HTMLAttributes; h4: HTMLAttributes;
header: HTMLAttributes; h5: HTMLAttributes;
hgroup: HTMLAttributes; h6: HTMLAttributes;
hr: HTMLAttributes; head: HTMLAttributes;
html: HTMLAttributes; header: HTMLAttributes;
i: HTMLAttributes; hgroup: HTMLAttributes;
iframe: HTMLAttributes; hr: HTMLAttributes;
img: HTMLAttributes; html: HTMLAttributes;
input: HTMLAttributes; i: HTMLAttributes;
ins: HTMLAttributes; iframe: HTMLAttributes;
kbd: HTMLAttributes; img: HTMLAttributes;
keygen: HTMLAttributes; input: HTMLAttributes;
label: HTMLAttributes; ins: HTMLAttributes;
legend: HTMLAttributes; kbd: HTMLAttributes;
li: HTMLAttributes; keygen: HTMLAttributes;
link: HTMLAttributes; label: HTMLAttributes;
main: HTMLAttributes; legend: HTMLAttributes;
map: HTMLAttributes; li: HTMLAttributes;
mark: HTMLAttributes; link: HTMLAttributes;
marquee: HTMLAttributes; main: HTMLAttributes;
menu: HTMLAttributes; map: HTMLAttributes;
menuitem: HTMLAttributes; mark: HTMLAttributes;
meta: HTMLAttributes; marquee: HTMLAttributes;
meter: HTMLAttributes; menu: HTMLAttributes;
nav: HTMLAttributes; menuitem: HTMLAttributes;
noscript: HTMLAttributes; meta: HTMLAttributes;
object: HTMLAttributes; meter: HTMLAttributes;
ol: HTMLAttributes; nav: HTMLAttributes;
optgroup: HTMLAttributes; noscript: HTMLAttributes;
option: HTMLAttributes; object: HTMLAttributes;
output: HTMLAttributes; ol: HTMLAttributes;
p: HTMLAttributes; optgroup: HTMLAttributes;
param: HTMLAttributes; option: HTMLAttributes;
picture: HTMLAttributes; output: HTMLAttributes;
pre: HTMLAttributes; p: HTMLAttributes;
progress: HTMLAttributes; param: HTMLAttributes;
q: HTMLAttributes; picture: HTMLAttributes;
rp: HTMLAttributes; pre: HTMLAttributes;
rt: HTMLAttributes; progress: HTMLAttributes;
ruby: HTMLAttributes; q: HTMLAttributes;
s: HTMLAttributes; rp: HTMLAttributes;
samp: HTMLAttributes; rt: HTMLAttributes;
script: HTMLAttributes; ruby: HTMLAttributes;
section: HTMLAttributes; s: HTMLAttributes;
select: HTMLAttributes; samp: HTMLAttributes;
slot: HTMLAttributes; script: HTMLAttributes;
small: HTMLAttributes; section: HTMLAttributes;
source: HTMLAttributes; select: HTMLAttributes;
span: HTMLAttributes; slot: HTMLAttributes;
strong: HTMLAttributes; small: HTMLAttributes;
style: HTMLAttributes; source: HTMLAttributes;
sub: HTMLAttributes; span: HTMLAttributes;
summary: HTMLAttributes; strong: HTMLAttributes;
sup: HTMLAttributes; style: HTMLAttributes;
table: HTMLAttributes; sub: HTMLAttributes;
tbody: HTMLAttributes; summary: HTMLAttributes;
td: HTMLAttributes; sup: HTMLAttributes;
textarea: HTMLAttributes; table: HTMLAttributes;
tfoot: HTMLAttributes; tbody: HTMLAttributes;
th: HTMLAttributes; td: HTMLAttributes;
thead: HTMLAttributes; textarea: HTMLAttributes;
time: HTMLAttributes; tfoot: HTMLAttributes;
title: HTMLAttributes; th: HTMLAttributes;
tr: HTMLAttributes; thead: HTMLAttributes;
track: HTMLAttributes; time: HTMLAttributes;
u: HTMLAttributes; title: HTMLAttributes;
ul: HTMLAttributes; tr: HTMLAttributes;
var: HTMLAttributes; track: HTMLAttributes;
video: HTMLAttributes; u: HTMLAttributes;
wbr: HTMLAttributes; ul: HTMLAttributes;
var: HTMLAttributes;
video: HTMLAttributes;
wbr: HTMLAttributes;
};
}
} }

View file

@ -35,7 +35,7 @@ export const walkDir = async function* (
* @param modName Name of the module to purge from the require cache. * @param modName Name of the module to purge from the require cache.
*/ */
export const purgeModuleAndDepsFromCache = (modName: string): void => { export const purgeModuleAndDepsFromCache = (modName: string): void => {
var modPath = require.resolve(modName); const modPath = require.resolve(modName);
if (modPath == null) { if (modPath == null) {
return; return;
} }

View file

@ -6,7 +6,7 @@
import { areEqual, displayValue, matches } from "./utils"; import { areEqual, displayValue, matches } from "./utils";
class ExpectError extends Error { class ExpectError extends Error {
public constructor(reason: string, expected: any, actual: any) { public constructor(reason: string, expected: unknown, actual: unknown) {
super( super(
`${reason}\n` + `${reason}\n` +
`\texpected: ${displayValue(expected)}\n` + `\texpected: ${displayValue(expected)}\n` +
@ -45,7 +45,7 @@ export class Expect<T> {
* *
* @throws ExpectError If the actual value does not equal the expected value. * @throws ExpectError If the actual value does not equal the expected value.
*/ */
public toEqual(expected: T) { public toEqual(expected: T): void {
if (!areEqual(this.value, expected)) { if (!areEqual(this.value, expected)) {
throw new ExpectError( throw new ExpectError(
`value does not equal expected`, `value does not equal expected`,
@ -201,12 +201,12 @@ export function expect<T>(fn: () => T): FunctionExpect<T>;
* *
* @param value Value to place expectations upon. * @param value Value to place expectations upon.
*/ */
export function expect(value: any): Expect<any> { export function expect(value: unknown): Expect<unknown> {
if (typeof value === "string") { if (typeof value === "string") {
return new StringExpect(value); return new StringExpect(value);
} }
if (typeof value === "function") { if (typeof value === "function") {
return new FunctionExpect(value); return new FunctionExpect(value as () => unknown);
} }
return new Expect(value); return new Expect(value);
} }

View file

@ -31,7 +31,10 @@ const areArraysEqual = <T>(a: T[], b: T[]): boolean => {
return true; return true;
}; };
const areObjectsEqual = <T extends object>(a: T, b: T): boolean => { const areObjectsEqual = <T extends Record<string, unknown>>(
a: T,
b: T
): boolean => {
const aKeys = Object.keys(a) as Array<keyof T>; const aKeys = Object.keys(a) as Array<keyof T>;
const bKeys = Object.keys(b) as Array<keyof T>; const bKeys = Object.keys(b) as Array<keyof T>;
if (aKeys.length !== bKeys.length) { if (aKeys.length !== bKeys.length) {
@ -62,7 +65,10 @@ export const areEqual = <T>(a: T, b: T): boolean => {
return a.source === b.source; return a.source === b.source;
} }
if (typeof a === "object" && typeof b === "object") { if (typeof a === "object" && typeof b === "object") {
return areObjectsEqual(a as any, b); return areObjectsEqual(
a as Record<string, unknown>,
b as Record<string, unknown>
);
} }
return a === b; return a === b;
}; };
@ -95,7 +101,7 @@ export const matches = (value: string, pattern: string | RegExp): boolean => {
* *
* @return Rendered value to display. * @return Rendered value to display.
*/ */
export const displayValue = (value: any): string => { export const displayValue = (value: unknown): string => {
if (value === undefined) { if (value === undefined) {
return "undefined"; return "undefined";
} }