Skip to content

Commit

Permalink
ESLint + Prettier config (#582)
Browse files Browse the repository at this point in the history
* Install and configure ESLint and Prettier

* fix eslint errors and prettier warnings
  • Loading branch information
marcoroth committed Sep 30, 2022
1 parent a5acb81 commit f690a6a
Show file tree
Hide file tree
Showing 67 changed files with 1,128 additions and 391 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
@@ -0,0 +1,2 @@
dist/
node_modules/
29 changes: 29 additions & 0 deletions .eslintrc
@@ -0,0 +1,29 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"prettier"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"prefer-rest-params": "off",
"prettier/prettier": ["error"],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/ban-types": ["error", {
"types": {
"Function": false,
"Object": false,
"{}": false
}
}]
}
}
25 changes: 12 additions & 13 deletions .github/workflows/ci.yml
Expand Up @@ -8,18 +8,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '12.4.0'
- uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
cache: 'yarn'

- run: yarn install
- name: Install Dependencies
run: yarn install --frozen-lockfile

- name: Test
run: yarn test
- name: Test
run: yarn test

- name: Lint
run: yarn lint
2 changes: 2 additions & 0 deletions .prettierignore
@@ -0,0 +1,2 @@
dist/
node_modules/
5 changes: 5 additions & 0 deletions .prettierrc.json
@@ -0,0 +1,5 @@
{
"singleQuote": false,
"printWidth": 120,
"semi": false
}
10 changes: 9 additions & 1 deletion package.json
Expand Up @@ -39,19 +39,27 @@
"start": "concurrently \"npm:watch\" \"npm:start:examples\"",
"start:examples": "cd examples && yarn install && node server.js",
"test": "yarn build:test && karma start karma.conf.cjs",
"test:watch": "yarn test --auto-watch --no-single-run"
"test:watch": "yarn test --auto-watch --no-single-run",
"lint": "eslint . --ext .ts",
"format": "yarn lint --fix"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^13.0.0",
"@rollup/plugin-typescript": "^8.5.0",
"@types/qunit": "^2.9.0",
"@types/webpack-env": "^1.14.0",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"concurrently": "^6.2.1",
"eslint": "^8.23.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"karma": "^5.2.3",
"karma-chrome-launcher": "^3.1.0",
"karma-qunit": "^4.0.0",
"karma-sauce-launcher": "^4.3.6",
"karma-webpack": "^4.0.2",
"prettier": "^2.7.1",
"qunit": "^2.9.2",
"rimraf": "^3.0.2",
"rollup": "^2.53",
Expand Down
30 changes: 15 additions & 15 deletions src/core/action.ts
Expand Up @@ -15,13 +15,13 @@ export class Action {
}

constructor(element: Element, index: number, descriptor: Partial<ActionDescriptor>) {
this.element = element
this.index = index
this.eventTarget = descriptor.eventTarget || element
this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name")
this.element = element
this.index = index
this.eventTarget = descriptor.eventTarget || element
this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name")
this.eventOptions = descriptor.eventOptions || {}
this.identifier = descriptor.identifier || error("missing identifier")
this.methodName = descriptor.methodName || error("missing method name")
this.identifier = descriptor.identifier || error("missing identifier")
this.methodName = descriptor.methodName || error("missing method name")
}

toString() {
Expand All @@ -30,14 +30,14 @@ export class Action {
}

get params() {
const params:{ [key: string]: any } = {}
const params: { [key: string]: any } = {}
const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, "i")

for (const { name, value } of Array.from(this.element.attributes)) {
const match = name.match(pattern)
const key = match && match[1]
if (key) {
params[camelize(key)]= typecast(value)
params[camelize(key)] = typecast(value)
}
}
return params
Expand All @@ -49,13 +49,13 @@ export class Action {
}

const defaultEventNames: { [tagName: string]: (element: Element) => string } = {
"a": e => "click",
"button": e => "click",
"form": e => "submit",
"details": e => "toggle",
"input": e => e.getAttribute("type") == "submit" ? "click" : "input",
"select": e => "change",
"textarea": e => "input"
a: () => "click",
button: () => "click",
form: () => "submit",
details: () => "toggle",
input: (e) => (e.getAttribute("type") == "submit" ? "click" : "input"),
select: () => "change",
textarea: () => "input",
}

export function getDefaultEventNameForElement(element: Element): string | undefined {
Expand Down
16 changes: 8 additions & 8 deletions src/core/action_descriptor.ts
Expand Up @@ -34,7 +34,7 @@ export const defaultActionDescriptorFilters: ActionDescriptorFilters = {
} else {
return true
}
}
},
}

// capture nos.: 12 23 4 43 1 5 56 7 768 9 98
Expand All @@ -44,11 +44,11 @@ export function parseActionDescriptorString(descriptorString: string): Partial<A
const source = descriptorString.trim()
const matches = source.match(descriptorPattern) || []
return {
eventTarget: parseEventTarget(matches[4]),
eventName: matches[2],
eventTarget: parseEventTarget(matches[4]),
eventName: matches[2],
eventOptions: matches[9] ? parseEventOptions(matches[9]) : {},
identifier: matches[5],
methodName: matches[7]
identifier: matches[5],
methodName: matches[7],
}
}

Expand All @@ -61,9 +61,9 @@ function parseEventTarget(eventTargetName: string): EventTarget | undefined {
}

function parseEventOptions(eventOptions: string): AddEventListenerOptions {
return eventOptions.split(":").reduce((options, token) =>
Object.assign(options, { [token.replace(/^!/, "")]: !/^!/.test(token) })
, {})
return eventOptions
.split(":")
.reduce((options, token) => Object.assign(options, { [token.replace(/^!/, "")]: !/^!/.test(token) }), {})
}

export function stringifyEventTarget(eventTarget: EventTarget) {
Expand Down
10 changes: 5 additions & 5 deletions src/core/application.ts
Expand Up @@ -14,7 +14,7 @@ export class Application implements ErrorHandler {
readonly router: Router
readonly actionDescriptorFilters: ActionDescriptorFilters
logger: Logger = console
debug: boolean = false
debug = false

static start(element?: Element, schema?: Schema): Application {
const application = new Application(element, schema)
Expand Down Expand Up @@ -57,7 +57,7 @@ export class Application implements ErrorHandler {
load(definitions: Definition[]): void
load(head: Definition | Definition[], ...rest: Definition[]) {
const definitions = Array.isArray(head) ? head : [head, ...rest]
definitions.forEach(definition => {
definitions.forEach((definition) => {
if ((definition.controllerConstructor as any).shouldLoad) {
this.router.loadDefinition(definition)
}
Expand All @@ -68,13 +68,13 @@ export class Application implements ErrorHandler {
unload(identifiers: string[]): void
unload(head: string | string[], ...rest: string[]) {
const identifiers = Array.isArray(head) ? head : [head, ...rest]
identifiers.forEach(identifier => this.router.unloadIdentifier(identifier))
identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier))
}

// Controllers

get controllers(): Controller[] {
return this.router.contexts.map(context => context.controller)
return this.router.contexts.map((context) => context.controller)
}

getControllerForElementAndIdentifier(element: Element, identifier: string): Controller | null {
Expand Down Expand Up @@ -108,7 +108,7 @@ export class Application implements ErrorHandler {
}

function domReady() {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
if (document.readyState == "loading") {
document.addEventListener("DOMContentLoaded", () => resolve())
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/core/binding_observer.ts
Expand Up @@ -19,7 +19,7 @@ export class BindingObserver implements ValueListObserverDelegate<Action> {
constructor(context: Context, delegate: BindingObserverDelegate) {
this.context = context
this.delegate = delegate
this.bindingsByAction = new Map
this.bindingsByAction = new Map()
}

start() {
Expand Down Expand Up @@ -72,7 +72,7 @@ export class BindingObserver implements ValueListObserverDelegate<Action> {
}

private disconnectAllActions() {
this.bindings.forEach(binding => this.delegate.bindingDisconnected(binding))
this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding))
this.bindingsByAction.clear()
}

Expand Down
19 changes: 9 additions & 10 deletions src/core/blessing.ts
Expand Up @@ -23,14 +23,14 @@ function getBlessedProperties<T>(constructor: Constructor<T>) {
return blessings.reduce((blessedProperties, blessing) => {
const properties = blessing(constructor)
for (const key in properties) {
const descriptor = blessedProperties[key] || {} as PropertyDescriptor
const descriptor = blessedProperties[key] || ({} as PropertyDescriptor)
blessedProperties[key] = Object.assign(descriptor, properties[key])
}
return blessedProperties
}, {} as PropertyDescriptorMap)
}

function getShadowProperties<T>(prototype: any, properties: PropertyDescriptorMap) {
function getShadowProperties(prototype: any, properties: PropertyDescriptorMap) {
return getOwnKeys(properties).reduce((shadowProperties, key) => {
const descriptor = getShadowedDescriptor(prototype, properties, key)
if (descriptor) {
Expand All @@ -55,10 +55,7 @@ function getShadowedDescriptor(prototype: any, properties: PropertyDescriptorMap

const getOwnKeys = (() => {
if (typeof Object.getOwnPropertySymbols == "function") {
return (object: any) => [
...Object.getOwnPropertyNames(object),
...Object.getOwnPropertySymbols(object)
]
return (object: any) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)]
} else {
return Object.getOwnPropertyNames
}
Expand All @@ -71,18 +68,20 @@ const extend = (() => {
}

extended.prototype = Object.create(constructor.prototype, {
constructor: { value: extended }
constructor: { value: extended },
})

Reflect.setPrototypeOf(extended, constructor)
return extended as any
}

function testReflectExtension() {
const a = function(this: any) { this.a.call(this) } as any
const a = function (this: any) {
this.a.call(this)
} as any
const b = extendWithReflect(a)
b.prototype.a = function() {}
return new b
b.prototype.a = function () {}
return new b()
}

try {
Expand Down
8 changes: 4 additions & 4 deletions src/core/class_properties.ts
Expand Up @@ -21,19 +21,19 @@ function propertiesForClassDefinition(key: string) {
const attribute = classes.getAttributeName(key)
throw new Error(`Missing attribute "${attribute}"`)
}
}
},
},

[`${key}Classes`]: {
get(this: Controller) {
return this.classes.getAll(key)
}
},
},

[`has${capitalize(key)}Class`]: {
get(this: Controller) {
return this.classes.has(key)
}
}
},
},
}
}
2 changes: 1 addition & 1 deletion src/core/constructor.ts
@@ -1 +1 @@
export type Constructor<T> = new(...args: any[]) => T
export type Constructor<T> = new (...args: any[]) => T
7 changes: 5 additions & 2 deletions src/core/controller.ts
Expand Up @@ -7,7 +7,7 @@ import { ValuePropertiesBlessing, ValueDefinitionMap } from "./value_properties"
export type ControllerConstructor = Constructor<Controller>

export class Controller<ElementType extends Element = Element> {
static blessings = [ ClassPropertiesBlessing, TargetPropertiesBlessing, ValuePropertiesBlessing ]
static blessings = [ClassPropertiesBlessing, TargetPropertiesBlessing, ValuePropertiesBlessing]
static targets: string[] = []
static values: ValueDefinitionMap = {}

Expand Down Expand Up @@ -61,7 +61,10 @@ export class Controller<ElementType extends Element = Element> {
// Override in your subclass to respond when the controller is disconnected from the DOM
}

dispatch(eventName: string, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {
dispatch(
eventName: string,
{ target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}
) {
const type = prefix ? `${prefix}:${eventName}` : eventName
const event = new CustomEvent(type, { detail, bubbles, cancelable })
target.dispatchEvent(event)
Expand Down
2 changes: 1 addition & 1 deletion src/core/definition.ts
Expand Up @@ -9,6 +9,6 @@ export interface Definition {
export function blessDefinition(definition: Definition): Definition {
return {
identifier: definition.identifier,
controllerConstructor: bless(definition.controllerConstructor)
controllerConstructor: bless(definition.controllerConstructor),
}
}

0 comments on commit f690a6a

Please sign in to comment.