Migrated to ESLint

This commit is contained in:
squidfunk 2021-02-07 17:43:13 +01:00
parent 4744d5f3f0
commit 208c9ac3fd
65 changed files with 1968 additions and 393 deletions

1
.eslintcache Normal file

File diff suppressed because one or more lines are too long

351
.eslintrc Normal file
View File

@ -0,0 +1,351 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json"
},
"plugins": [
"@typescript-eslint",
"eslint-plugin-eslint-comments",
"eslint-plugin-import",
"eslint-plugin-jsdoc",
"eslint-plugin-no-null"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"settings": {
"import/extensions": [
".ts",
".tsx",
".js",
".jsx",
".json"
],
"import/parsers": {
"@typescript-eslint/parser": [
".ts",
".tsx"
]
}
},
"rules": {
"array-bracket-spacing": "warn",
"arrow-parens": [
"warn",
"as-needed"
],
"block-spacing": "warn",
"brace-style": [
"warn",
"1tbs",
{
"allowSingleLine": true
}
],
"comma-dangle": [
"error",
"never"
],
"comma-spacing": "warn",
"comma-style": "error",
"computed-property-spacing": "warn",
"curly": "off",
"eqeqeq": [
"error",
"smart"
],
"func-call-spacing": "warn",
"keyword-spacing": "warn",
"lines-around-comment": [
"error",
{
"allowBlockStart": true,
"allowBlockEnd": true,
"beforeBlockComment": true,
"ignorePattern": "@ts-ignore"
}
],
"lines-between-class-members": "warn",
"max-classes-per-file": "error",
"new-parens": "error",
"no-caller": "error",
"no-case-declarations": "off",
"no-console": "error",
"no-duplicate-imports": "error",
"no-eval": "error",
"no-extra-bind": "error",
"no-multiple-empty-lines": [
"error",
{
"max": 1
}
],
"no-new-func": "error",
"no-new-wrappers": "error",
"no-restricted-globals": [
"error",
{
"name": "fdescribe",
"message": "Did you mean 'describe'?"
},
{
"name": "xdescribe",
"message": "Did you mean 'describe'?"
},
{
"name": "fit",
"message": "Did you mean 'it'?"
},
{
"name": "xit",
"message": "Did you mean 'xit'?"
}
],
"no-return-await": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-tabs": "error",
"no-template-curly-in-string": "error",
"no-throw-literal": "off",
"no-trailing-spaces": "warn",
"no-undef-init": "error",
"no-underscore-dangle": "error",
"no-var": "error",
"no-whitespace-before-property": "warn",
"object-shorthand": "error",
"one-var": [
"error",
"never"
],
"prefer-exponentiation-operator": "error",
"prefer-object-spread": "error",
"prefer-template": "error",
"quote-props": [
"error",
"consistent-as-needed"
],
"quotes": [
"error",
"double",
{
"avoidEscape": true
}
],
"radix": "error",
"semi": "off",
"sort-imports": [
"error",
{
"ignoreDeclarationSort": true
}
],
"space-before-blocks": "warn",
"space-before-function-paren": [
"warn",
{
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": "warn",
"space-infix-ops": "warn",
"space-unary-ops": "warn",
"spaced-comment": "warn",
"switch-colon-spacing": "warn",
"template-tag-spacing": "warn",
/* Plugin: @typescript-eslint */
"@typescript-eslint/array-type": "off",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/dot-notation": "error",
"@typescript-eslint/explicit-member-accessibility": "error",
"@typescript-eslint/indent": [
"warn",
2,
{
"FunctionDeclaration": {
"parameters": 1,
"body": 1
},
"FunctionExpression": {
"parameters": 1,
"body": 1
},
"MemberExpression": "off",
"ObjectExpression": 1,
"SwitchCase": 1,
"ignoreComments": true,
"ignoredNodes": [
"ArrowFunctionExpression > *",
"CallExpression > ObjectExpression",
"ConditionalExpression > ConditionalExpression",
"TSTypeReference > *"
],
"offsetTernaryExpressions": true
}
],
"@typescript-eslint/member-delimiter-style": [
"error",
{
"multiline": {
"delimiter": "none"
},
"singleline": {
"delimiter": "comma",
"requireLast": false
}
}
],
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "enumMember",
"format": [
"UPPER_CASE"
]
}
],
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-extraneous-class": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-parameter-properties": "off",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-shadow": [
"error",
{
"hoist": "never"
}
],
"@typescript-eslint/no-throw-literal": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/prefer-for-of": "off",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/semi": [
"error",
"never"
],
"@typescript-eslint/triple-slash-reference": "off",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unbound-method": "error",
"@typescript-eslint/unified-signatures": "error",
/* Plugin: eslint-plugin-eslint-comments */
"eslint-comments/no-unused-disable": "error",
"eslint-comments/no-unused-enable": "error",
"eslint-comments/no-use": [
"warn",
{
"allow": [
"eslint-disable-line",
"eslint-disable-next-line"
]
}
],
/* Plugin: eslint-plugin-import */
"import/first": "error",
"import/newline-after-import": "error",
"import/no-default-export": "error",
"import/no-duplicates": "error",
"import/no-mutable-exports": "error",
"import/no-self-import": "error",
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
},
"newlines-between": "always",
"groups": [
[
"builtin",
"external"
],
[
"internal"
],
[
"index"
],
[
"parent"
],
[
"sibling"
]
],
"pathGroups": [
{
"pattern": "~/**",
"group": "index",
"position": "before"
},
{
"pattern": "_/**",
"group": "index",
"position": "after"
}
],
"pathGroupsExcludedImportTypes": [
"builtin"
]
}
],
/* Plugin: eslint-plugin-jsdoc */
"jsdoc/check-alignment": "warn",
"jsdoc/check-param-names": [
"warn",
{
"checkDestructured": false
}
],
"jsdoc/check-syntax": "warn",
"jsdoc/check-tag-names": [
"warn",
{
"definedTags": [
"internal"
]
}
],
"jsdoc/empty-tags": "warn",
"jsdoc/newline-after-description": "warn",
"jsdoc/no-bad-blocks": "warn",
"jsdoc/no-defaults": "warn",
"jsdoc/no-types": "warn",
"jsdoc/require-hyphen-before-param-description": "warn",
"jsdoc/require-jsdoc": "warn",
"jsdoc/require-param-description": "warn",
"jsdoc/require-param-name": "warn",
"jsdoc/require-param": [
"warn",
{
"checkDestructured": false,
"checkDestructuredRoots": true
}
],
"jsdoc/require-returns-check": "warn",
"jsdoc/require-returns-description": "warn",
"jsdoc/require-returns": [
"warn",
{
"checkGetters": false,
"forceReturnsWithAsync": true
}
],
/* Plugin: eslint-plugin-no-null */
"no-null/no-null": "error"
}
}

View File

@ -1,41 +1,138 @@
{
"extends": [
"stylelint-config-recommended",
"stylelint-config-standard",
"stylelint-config-rational-order"
],
"plugins": [
"stylelint-order",
"stylelint-scss"
],
"rules": {
"at-rule-empty-line-before": null,
"at-rule-empty-line-before": [
"always",
{
"except": [
"blockless-after-same-name-blockless",
"first-nested"
],
"ignore": [
"after-comment"
],
"ignoreAtRules": [
"if",
"else",
"elseif"
]
}
],
"at-rule-no-unknown": null,
"at-rule-no-vendor-prefix": true,
"block-opening-brace-space-before": null,
"block-closing-brace-newline-after": ["always", {
"ignoreAtRules": [
"if",
"else",
"elseif"
]
}],
"color-hex-case": "upper",
"block-closing-brace-newline-after": [
"always",
{
"ignoreAtRules": [
"if",
"else",
"elseif"
]
}
],
"color-hex-length": "long",
"color-named": "never",
"comment-empty-line-before": ["always", {
"ignore": ["stylelint-commands"]
}],
"comment-empty-line-before": [
"always",
{
"ignore": [
"stylelint-commands"
]
}
],
"custom-property-empty-line-before": null,
"custom-property-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"declaration-no-important": true,
"declaration-block-single-line-max-declarations": 0,
"function-url-no-scheme-relative": true,
"function-url-quotes": "always",
"font-family-name-quotes": "always-where-recommended",
"font-weight-notation": "numeric",
"function-url-quotes": "always",
"no-descending-specificity": null,
"keyframes-name-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"linebreaks": "unix",
"media-feature-name-no-unknown": null,
"no-empty-first-line": true,
"no-unknown-animations": true,
"property-no-vendor-prefix": [true, {"ignoreProperties": ["line-clamp", "box-orient"]}],
"selector-class-pattern": "^[a-z0-9]+(-[a-z0-9]+)*(__[a-z]+)?(--[a-z]+)?$",
"selector-descendant-combinator-no-non-space": null,
"property-no-unknown": null,
"property-no-vendor-prefix": [
true,
{
"ignoreProperties": [
"line-clamp",
"box-orient"
]
}
],
"selector-max-empty-lines": 0,
"selector-max-id": 0,
"selector-max-type": 1,
"selector-max-universal": 1,
"selector-no-qualifying-type": true,
"selector-pseudo-class-no-unknown": null,
"selector-pseudo-element-no-unknown": null,
"string-quotes": "double",
"unit-allowed-list": ["px", "em", "deg", "ms", "%", "mm", "vh", "vw", "dppx"],
"value-keyword-case": "lower",
"value-no-vendor-prefix": [true, {"ignoreValues": ["box"]}]
"unicode-bom": "never",
"unit-allowed-list": [
"%",
"dppx",
"deg",
"em",
"mm",
"ms",
"px",
"vh",
"vw"
],
"value-no-vendor-prefix": true,
"scss/at-each-key-value-single-line": true,
"scss/at-else-closing-brace-newline-after": "always-last-in-chain",
"scss/at-extend-no-missing-placeholder": true,
"scss/at-function-parentheses-space-before": "never",
"scss/at-function-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"scss/at-if-closing-brace-newline-after": "always-last-in-chain",
"scss/at-if-no-null": true,
"scss/at-import-no-partial-leading-underscore": true,
"scss/at-import-partial-extension": "never",
"scss/at-mixin-argumentless-call-parentheses": "always",
"scss/at-mixin-parentheses-space-before": "never",
"scss/at-mixin-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"scss/at-rule-conditional-no-parentheses": true,
"scss/comment-no-empty": true,
"scss/comment-no-loud": true,
"scss/declaration-nested-properties": "never",
"scss/dimension-no-non-numeric-values": true,
"scss/dollar-variable-colon-newline-after": "always-multi-line",
"scss/dollar-variable-colon-space-after": "always-single-line",
"scss/dollar-variable-colon-space-before": "never",
"scss/dollar-variable-default": [
true,
{
"ignore": "local"
}
],
"scss/dollar-variable-first-in-block": [
true,
{
"ignore": ["comments"],
"except": ["function"]
}
],
"scss/dollar-variable-no-missing-interpolation": true,
"scss/dollar-variable-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"scss/double-slash-comment-whitespace-inside": "always",
"scss/no-dollar-variables": true,
"scss/no-global-function-names": true,
"scss/no-duplicate-dollar-variables": true,
"scss/no-duplicate-mixins": true,
"scss/operator-no-unspaced": true,
"scss/partial-no-import": true,
"scss/percent-placeholder-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
"scss/selector-no-redundant-nesting-selector": true
}
}

View File

@ -294,7 +294,7 @@ following transformations, which can be customized by [extending the theme][20]:
*
* @param query - Query value
*
* @return Transformed query value
* @returns Transformed query value
*/
export function defaultTransform(query: string): string {
return query

1414
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,12 +24,12 @@
"url": "https://github.com/squidfunk/mkdocs-material.git"
},
"scripts": {
"build": "npm run clean && npx webpack --mode production",
"clean": "npx rimraf material",
"lint": "npm run lint:ts && npm run lint:scss",
"lint:scss": "npx stylelint \"src/assets/**/*.scss\"",
"lint:ts": "npx tslint -p tsconfig.json \"src/**/*.ts\"",
"start": "npx webpack --mode development --watch"
"build": "npm run clean && webpack --mode production",
"clean": "rimraf material",
"lint": "npm run lint:*",
"lint:scss": "stylelint \"src/assets/**/*.scss\"",
"lint:ts": "eslint --cache \"src/**/*.ts\"",
"start": "webpack --mode development --watch"
},
"dependencies": {
"clipboard": "^2.0.6",
@ -55,9 +55,16 @@
"@types/resize-observer-browser": "^0.1.5",
"@types/webpack": "^4.41.26",
"@types/webpack-assets-manifest": "^3.0.1",
"@typescript-eslint/eslint-plugin": "4.14.0",
"@typescript-eslint/parser": "^4.14.0",
"autoprefixer": "10.2.1",
"copy-webpack-plugin": "^6.4.1",
"css-loader": "^5.0.1",
"eslint": "^7.19.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^31.0.8",
"eslint-plugin-no-null": "^1.0.2",
"event-hooks-webpack-plugin": "^2.2.0",
"expose-loader": "^1.0.3",
"github-types": "^1.0.0",
@ -79,8 +86,8 @@
"sass-loader": "^10.1.1",
"stylelint": "^13.8.0",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-recommended": "^3.0.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.18.0",
"ts-loader": "^8.0.14",
"ts-node": "^9.1.1",

View File

@ -78,7 +78,7 @@ export interface Config {
/**
* Retrieve global configuration and make base URL absolute
*/
let config: Config = JSON.parse(getElementOrThrow("#__config").textContent!)
const config: Config = JSON.parse(getElementOrThrow("#__config").textContent!)
config.base = new URL(config.base, getLocation())
.toString()
.replace(/\/$/, "")
@ -90,7 +90,7 @@ config.base = new URL(config.base, getLocation())
/**
* Retrieve global configuration
*
* @return Global configuration
* @returns Global configuration
*/
export function configuration(): Config {
return config
@ -113,7 +113,7 @@ export function flag(feature: Feature): boolean {
* @param key - Key to be translated
* @param value - Value to be replaced
*
* @return Translation
* @returns Translation
*/
export function translation(
key: Translation, value?: string | number

View File

@ -34,7 +34,7 @@ import { mapTo } from "rxjs/operators"
* automatically updated when a new document is emitted. This enabled features
* like instant loading.
*
* @return Document subject
* @returns Document subject
*/
export function watchDocument(): Subject<Document> {
const document$ = new ReplaySubject<Document>()

View File

@ -0,0 +1,5 @@
{
"rules": {
"jsdoc/require-jsdoc": "off"
}
}

View File

@ -32,7 +32,7 @@
* @param selector - Query selector
* @param node - Node of reference
*
* @return Element or nothing
* @returns Element or nothing
*/
export function getElement<T extends keyof HTMLElementTagNameMap>(
selector: T, node?: ParentNode
@ -56,7 +56,7 @@ export function getElement<T extends HTMLElement>(
* @param selector - Query selector
* @param node - Node of reference
*
* @return Element
* @returns Element
*/
export function getElementOrThrow<T extends keyof HTMLElementTagNameMap>(
selector: T, node?: ParentNode
@ -80,7 +80,7 @@ export function getElementOrThrow<T extends HTMLElement>(
/**
* Retrieve the currently active element
*
* @return Element or nothing
* @returns Element or nothing
*/
export function getActiveElement(): HTMLElement | undefined {
return document.activeElement instanceof HTMLElement
@ -96,7 +96,7 @@ export function getActiveElement(): HTMLElement | undefined {
* @param selector - Query selector
* @param node - Node of reference
*
* @return Elements
* @returns Elements
*/
export function getElements<T extends keyof HTMLElementTagNameMap>(
selector: T, node?: ParentNode
@ -121,7 +121,7 @@ export function getElements<T extends HTMLElement>(
*
* @param tagName - Tag name
*
* @return Element
* @returns Element
*/
export function createElement<T extends keyof HTMLElementTagNameMap>(
tagName: T

View File

@ -36,7 +36,7 @@ import { getActiveElement } from "../_"
* @param value - Whether the element should be focused
*/
export function setElementFocus(
el: HTMLElement, value: boolean = true
el: HTMLElement, value = true
): void {
if (value)
el.focus()
@ -51,7 +51,7 @@ export function setElementFocus(
*
* @param el - Element
*
* @return Element focus observable
* @returns Element focus observable
*/
export function watchElementFocus(
el: HTMLElement

View File

@ -44,7 +44,7 @@ export interface ElementOffset {
*
* @param el - Element
*
* @return Element offset
* @returns Element offset
*/
export function getElementOffset(el: HTMLElement): ElementOffset {
return {
@ -60,7 +60,7 @@ export function getElementOffset(el: HTMLElement): ElementOffset {
*
* @param el - Element
*
* @return Element offset observable
* @returns Element offset observable
*/
export function watchElementOffset(
el: HTMLElement

View File

@ -92,7 +92,7 @@ const observer$ = defer(() => of(
*
* @param el - Element
*
* @return Element size
* @returns Element size
*/
export function getElementSize(el: HTMLElement): ElementSize {
return {
@ -106,7 +106,7 @@ export function getElementSize(el: HTMLElement): ElementSize {
*
* @param el - Element
*
* @return Element size
* @returns Element size
*/
export function getElementContentSize(el: HTMLElement): ElementSize {
return {
@ -127,7 +127,7 @@ export function getElementContentSize(el: HTMLElement): ElementSize {
*
* @param el - Element
*
* @return Element size observable
* @returns Element size observable
*/
export function watchElementSize(
el: HTMLElement

View File

@ -44,7 +44,7 @@ export interface Key {
*
* @param el - Element
*
* @return Test result
* @returns Test result
*/
export function isSusceptibleToKeyboard(el: HTMLElement): boolean {
switch (el.tagName) {
@ -66,7 +66,7 @@ export function isSusceptibleToKeyboard(el: HTMLElement): boolean {
/**
* Watch keyboard
*
* @return Keyboard observable
* @returns Keyboard observable
*/
export function watchKeyboard(): Observable<Key> {
return fromEvent<KeyboardEvent>(window, "keydown")

View File

@ -34,7 +34,7 @@ import { BehaviorSubject, Subject } from "rxjs"
* tracked without setting them and `Location` is a singleton which represents
* the current location.
*
* @return URL
* @returns URL
*/
export function getLocation(): URL {
return new URL(location.href)
@ -54,7 +54,7 @@ export function setLocation(url: URL): void {
/**
* Watch location
*
* @return Location subject
* @returns Location subject
*/
export function watchLocation(): Subject<URL> {
return new BehaviorSubject<URL>(getLocation())

View File

@ -23,8 +23,7 @@
import { Observable, fromEvent, of } from "rxjs"
import { filter, map, share, startWith, switchMap } from "rxjs/operators"
import { createElement } from "browser"
import { getElement } from "~/browser/element"
import { createElement, getElement } from "~/browser"
/* ----------------------------------------------------------------------------
* Functions
@ -33,7 +32,7 @@ import { getElement } from "~/browser/element"
/**
* Retrieve location hash
*
* @return Location hash
* @returns Location hash
*/
export function getLocationHash(): string {
return location.hash.substring(1)
@ -61,7 +60,7 @@ export function setLocationHash(hash: string): void {
/**
* Watch location hash
*
* @return Location hash observable
* @returns Location hash observable
*/
export function watchLocationHash(): Observable<string> {
return fromEvent<HashChangeEvent>(window, "hashchange")
@ -76,7 +75,7 @@ export function watchLocationHash(): Observable<string> {
/**
* Watch location target
*
* @return Location target observable
* @returns Location target observable
*/
export function watchLocationTarget(): Observable<HTMLElement> {
return watchLocationHash()

View File

@ -32,7 +32,7 @@ import { filter, map, mapTo, startWith } from "rxjs/operators"
*
* @param query - Media query
*
* @return Media observable
* @returns Media observable
*/
export function watchMedia(query: string): Observable<boolean> {
const media = matchMedia(query)
@ -46,7 +46,7 @@ export function watchMedia(query: string): Observable<boolean> {
/**
* Watch print mode, cross-browser
*
* @return Print observable
* @returns Print observable
*/
export function watchPrint(): Observable<void> {
return merge(

View File

@ -44,8 +44,8 @@ export type Toggle =
* Toggle map
*/
const toggles: Record<Toggle, HTMLInputElement> = {
drawer: getElementOrThrow(`[data-md-toggle=drawer]`),
search: getElementOrThrow(`[data-md-toggle=search]`)
drawer: getElementOrThrow("[data-md-toggle=drawer]"),
search: getElementOrThrow("[data-md-toggle=search]")
}
/* ----------------------------------------------------------------------------
@ -57,7 +57,7 @@ const toggles: Record<Toggle, HTMLInputElement> = {
*
* @param name - Toggle
*
* @return Toggle value
* @returns Toggle value
*/
export function getToggle(name: Toggle): boolean {
return toggles[name].checked
@ -86,7 +86,7 @@ export function setToggle(name: Toggle, value: boolean): void {
*
* @param name - Toggle
*
* @return Toggle value observable
* @returns Toggle value observable
*/
export function watchToggle(name: Toggle): Observable<boolean> {
const el = toggles[name]

View File

@ -69,7 +69,7 @@ interface WatchAtOptions {
/**
* Watch viewport
*
* @return Viewport observable
* @returns Viewport observable
*/
export function watchViewport(): Observable<Viewport> {
return combineLatest([
@ -88,7 +88,7 @@ export function watchViewport(): Observable<Viewport> {
* @param el - Element
* @param options - Options
*
* @return Viewport observable
* @returns Viewport observable
*/
export function watchViewportAt(
el: HTMLElement, { viewport$, header$ }: WatchAtOptions

View File

@ -45,7 +45,7 @@ export interface ViewportOffset {
* On iOS Safari, viewport offset can be negative due to overflow scrolling.
* As this may induce strange behaviors downstream, we'll just limit it to 0.
*
* @return Viewport offset
* @returns Viewport offset
*/
export function getViewportOffset(): ViewportOffset {
return {
@ -70,7 +70,7 @@ export function setViewportOffset(
/**
* Watch viewport offset
*
* @return Viewport offset observable
* @returns Viewport offset observable
*/
export function watchViewportOffset(): Observable<ViewportOffset> {
return merge(

View File

@ -42,7 +42,7 @@ export interface ViewportSize {
/**
* Retrieve viewport size
*
* @return Viewport size
* @returns Viewport size
*/
export function getViewportSize(): ViewportSize {
return {
@ -56,7 +56,7 @@ export function getViewportSize(): ViewportSize {
/**
* Watch viewport size
*
* @return Viewport size observable
* @returns Viewport size observable
*/
export function watchViewportSize(): Observable<ViewportSize> {
return fromEvent(window, "resize", { passive: true })

View File

@ -81,7 +81,7 @@ interface WatchOptions<T extends WorkerMessage> {
* @param worker - Web worker
* @param options - Options
*
* @return Worker message observable
* @returns Worker message observable
*/
export function watchWorker<T extends WorkerMessage>(
worker: Worker, { tx$ }: WatchOptions<T>
@ -90,8 +90,8 @@ export function watchWorker<T extends WorkerMessage>(
/* Intercept messages from worker-like objects */
const rx$ = fromEvent<MessageEvent>(worker, "message")
.pipe<T>(
map(({ data }) => data)
)
map(({ data }) => data)
)
/* Send and receive messages, return hot observable */
return tx$

View File

@ -22,7 +22,7 @@
import { Observable, merge } from "rxjs"
import { getElements, Viewport } from "~/browser"
import { Viewport, getElements } from "~/browser"
import { Component } from "../../_"
import { CodeBlock, mountCodeBlock } from "../code"
@ -64,7 +64,7 @@ interface MountOptions {
* @param el - Content element
* @param options - Options
*
* @return Content component observable
* @returns Content component observable
*/
export function mountContent(
el: HTMLElement, { target$, viewport$, print$ }: MountOptions

View File

@ -32,9 +32,9 @@ import {
import { resetFocusable, setFocusable } from "~/actions"
import {
Viewport,
getElementContentSize,
getElementSize,
Viewport,
watchMedia
} from "~/browser"
import { renderClipboardButton } from "~/templates"
@ -89,7 +89,7 @@ let index = 0
* @param el - Code block element
* @param options - Options
*
* @return Code block observable
* @returns Code block observable
*/
export function watchCodeBlock(
el: HTMLElement, { viewport$ }: WatchOptions
@ -117,7 +117,7 @@ export function watchCodeBlock(
* @param el - Code block element
* @param options - Options
*
* @return Code block component observable
* @returns Code block component observable
*/
export function mountCodeBlock(
el: HTMLElement, options: MountOptions

View File

@ -71,7 +71,7 @@ interface MountOptions {
* @param el - Details element
* @param options - Options
*
* @return Details observable
* @returns Details observable
*/
export function watchDetails(
el: HTMLDetailsElement, { target$, print$ }: WatchOptions
@ -94,7 +94,7 @@ export function watchDetails(
* @param el - Details element
* @param options - Options
*
* @return Details component observable
* @returns Details component observable
*/
export function mountDetails(
el: HTMLDetailsElement, options: MountOptions

View File

@ -54,7 +54,7 @@ const sentinel = createElement("table")
*
* @param el - Data table element
*
* @return Data table component observable
* @returns Data table component observable
*/
export function mountDataTable(
el: HTMLElement

View File

@ -23,8 +23,8 @@
import {
Observable,
Subject,
merge,
animationFrameScheduler,
merge,
of
} from "rxjs"
import {
@ -81,10 +81,10 @@ interface MountOptions {
/**
* Watch dialog
*
* @param el - Dialog element
* @param _el - Dialog element
* @param options - Options
*
* @return Dialog observable
* @returns Dialog observable
*/
export function watchDialog(
_el: HTMLElement, { message$ }: WatchOptions
@ -102,14 +102,13 @@ export function watchDialog(
)
}
/**
* Mount dialog
*
* @param el - Dialog element
* @param options - Options
*
* @return Dialog component observable
* @returns Dialog component observable
*/
export function mountDialog(
el: HTMLElement, { message$ }: MountOptions

View File

@ -20,7 +20,13 @@
* IN THE SOFTWARE.
*/
import { Observable, defer, of, Subject, animationFrameScheduler } from "rxjs"
import {
Observable,
Subject,
animationFrameScheduler,
defer,
of
} from "rxjs"
import {
combineLatestWith,
distinctUntilChanged,
@ -70,7 +76,7 @@ interface MountOptions {
*
* @param el - Header element
*
* @return Header observable
* @returns Header observable
*/
export function watchHeader(
el: HTMLElement
@ -106,7 +112,7 @@ export function watchHeader(
* @param el - Header element
* @param options - Options
*
* @return Header component observable
* @returns Header component observable
*/
export function mountHeader(
el: HTMLElement, { header$, main$ }: MountOptions

View File

@ -20,7 +20,7 @@
* IN THE SOFTWARE.
*/
import { Observable, animationFrameScheduler, Subject } from "rxjs"
import { Observable, Subject, animationFrameScheduler } from "rxjs"
import {
distinctUntilKeyChanged,
finalize,
@ -84,7 +84,7 @@ interface MountOptions {
* @param el - Heading element
* @param options - Options
*
* @return Header title observable
* @returns Header title observable
*/
export function watchHeaderTitle(
el: HTMLHeadingElement, { viewport$, header$ }: WatchOptions
@ -107,7 +107,7 @@ export function watchHeaderTitle(
* @param el - Header title element
* @param options - Options
*
* @return Header title component observable
* @returns Header title component observable
*/
export function mountHeaderTitle(
el: HTMLElement, options: MountOptions

View File

@ -75,7 +75,7 @@ interface WatchOptions {
* @param el - Main area element
* @param options - Options
*
* @return Main area observable
* @returns Main area observable
*/
export function watchMain(
el: HTMLElement, { viewport$, header$ }: WatchOptions

View File

@ -25,11 +25,15 @@ import { filter, sample, take } from "rxjs/operators"
import { configuration } from "~/_"
import { getElementOrThrow } from "~/browser"
import { isSearchQueryMessage, isSearchReadyMessage, setupSearchWorker } from "~/integrations"
import {
isSearchQueryMessage,
isSearchReadyMessage,
setupSearchWorker
} from "~/integrations"
import { Component } from "../../_"
import { mountSearchQuery, SearchQuery } from "../query"
import { mountSearchResult, SearchResult } from "../result"
import { SearchQuery, mountSearchQuery } from "../query"
import { SearchResult, mountSearchResult } from "../result"
/* ----------------------------------------------------------------------------
* Types
@ -51,7 +55,7 @@ export type Search =
*
* @param url - Search index URL
*
* @return Promise resolving with search index
* @returns Promise resolving with search index
*/
function fetchSearchIndex(url: string) {
return __search?.index || fetch(url, { credentials: "same-origin" })
@ -67,7 +71,7 @@ function fetchSearchIndex(url: string) {
*
* @param el - Search element
*
* @return Search component observable
* @returns Search component observable
*/
export function mountSearch(
el: HTMLElement

View File

@ -49,10 +49,10 @@ import {
watchElementFocus
} from "~/browser"
import {
defaultTransform,
SearchWorker,
SearchMessageType,
SearchQueryMessage,
SearchMessageType
SearchWorker,
defaultTransform
} from "~/integrations"
import { Component } from "../../_"
@ -80,9 +80,8 @@ export interface SearchQuery {
* is delayed by `1ms` so the input's empty state is allowed to propagate.
*
* @param el - Search query element
* @param transform - Transformation function
*
* @return Search query observable
* @returns Search query observable
*/
export function watchSearchQuery(
el: HTMLInputElement
@ -113,9 +112,8 @@ export function watchSearchQuery(
*
* @param el - Search query element
* @param worker - Search worker
* @param transform - Transformation function
*
* @return Search query component observable
* @returns Search query component observable
*/
export function mountSearchQuery(
el: HTMLInputElement, { tx$ }: SearchWorker

View File

@ -80,7 +80,7 @@ interface MountOptions {
* @param worker - Search worker
* @param options - Options
*
* @return Search result list component observable
* @returns Search result list component observable
*/
export function mountSearchResult(
el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions

View File

@ -95,7 +95,7 @@ interface MountOptions {
* @param el - Sidebar element
* @param options - Options
*
* @return Sidebar observable
* @returns Sidebar observable
*/
export function watchSidebar(
el: HTMLElement, { viewport$, main$ }: WatchOptions
@ -129,7 +129,7 @@ export function watchSidebar(
* @param el - Sidebar element
* @param options - Options
*
* @return Sidebar component observable
* @returns Sidebar component observable
*/
export function mountSidebar(
el: HTMLElement, { header$, ...options }: MountOptions

View File

@ -20,7 +20,7 @@
* IN THE SOFTWARE.
*/
import { Observable, Subject, defer, of, NEVER } from "rxjs"
import { NEVER, Observable, Subject, defer, of } from "rxjs"
import {
catchError,
filter,
@ -35,10 +35,7 @@ import { renderSourceFacts } from "~/templates"
import { hash } from "~/utilities"
import { Component } from "../../_"
import {
fetchSourceFacts,
SourceFacts
} from "../facts"
import { SourceFacts, fetchSourceFacts } from "../facts"
/* ----------------------------------------------------------------------------
* Types
@ -69,7 +66,7 @@ let fetch$: Observable<Source>
*
* @param el - Repository information element
*
* @return Repository information observable
* @returns Repository information observable
*/
export function watchSource(
el: HTMLAnchorElement
@ -108,7 +105,7 @@ export function watchSource(
*
* @param el - Repository information element
*
* @return Repository information component observable
* @returns Repository information component observable
*/
export function mountSource(
el: HTMLAnchorElement

View File

@ -43,7 +43,7 @@ export type SourceFacts = string[]
*
* @param url - Repository URL
*
* @return Repository facts observable
* @returns Repository facts observable
*/
export function fetchSourceFacts(
url: string
@ -53,12 +53,12 @@ export function fetchSourceFacts(
/* GitHub repository */
case "github":
const [, user, repo] = url.match(/^.+github\.com\/([^\/]+)\/?([^\/]+)?/i)!
const [, user, repo] = url.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i)!
return fetchSourceFactsFromGitHub(user, repo)
/* GitLab repository */
case "gitlab":
const [, base, slug] = url.match(/^.+?([^\/]*gitlab[^\/]+)\/(.+?)\/?$/i)!
const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i)!
return fetchSourceFactsFromGitLab(base, slug)
/* Everything else */

View File

@ -43,7 +43,7 @@ import { SourceFacts } from "../_"
* @param user - GitHub user
* @param repo - GitHub repository
*
* @return Repository facts observable
* @returns Repository facts observable
*/
export function fetchSourceFactsFromGitHub(
user: string, repo?: string

View File

@ -43,7 +43,7 @@ import { SourceFacts } from "../_"
* @param base - GitLab base
* @param project - GitLab project
*
* @return Repository facts observable
* @returns Repository facts observable
*/
export function fetchSourceFactsFromGitLab(
base: string, project: string

View File

@ -20,7 +20,7 @@
* IN THE SOFTWARE.
*/
import { Observable, animationFrameScheduler, Subject } from "rxjs"
import { Observable, Subject, animationFrameScheduler } from "rxjs"
import {
distinctUntilKeyChanged,
finalize,
@ -76,7 +76,7 @@ interface MountOptions {
* @param el - Navigation tabs element
* @param options - Options
*
* @return Navigation tabs observable
* @returns Navigation tabs observable
*/
export function watchTabs(
el: HTMLElement, { viewport$, header$ }: WatchOptions
@ -98,7 +98,7 @@ export function watchTabs(
* @param el - Navigation tabs element
* @param options - Options
*
* @return Navigation tabs component observable
* @returns Navigation tabs component observable
*/
export function mountTabs(
el: HTMLElement, options: MountOptions

View File

@ -46,9 +46,9 @@ import {
setAnchorState
} from "~/actions"
import {
Viewport,
getElement,
getElements,
Viewport,
watchElementSize
} from "~/browser"
@ -109,7 +109,7 @@ interface MountOptions {
* @param anchors - Anchor elements
* @param options - Options
*
* @return Table of contents observable
* @returns Table of contents observable
*/
export function watchTableOfContents(
anchors: HTMLAnchorElement[], { viewport$, header$ }: WatchOptions
@ -236,7 +236,7 @@ export function watchTableOfContents(
* @param el - Anchor list element
* @param options - Options
*
* @return Table of contents component observable
* @returns Table of contents component observable
*/
export function mountTableOfContents(
el: HTMLElement, options: MountOptions

View File

@ -21,9 +21,10 @@
*/
import "focus-visible"
import { merge, NEVER, Observable, Subject } from "rxjs"
import { NEVER, Observable, Subject, merge } from "rxjs"
import { switchMap } from "rxjs/operators"
import { translation } from "./_"
import {
getElementOrThrow,
getElements,
@ -48,7 +49,6 @@ import {
import {
setupClipboardJS
} from "./integrations"
import { translation } from "./_"
/* ----------------------------------------------------------------------------
* Program
@ -72,7 +72,7 @@ const header = getElementOrThrow("[data-md-component=header]")
const main = getElementOrThrow("[data-md-component=main]")
const header$ = watchHeader(header)
const main$ = watchMain(main, { header$: header$, viewport$ })
const main$ = watchMain(main, { header$, viewport$ })
/* Setup Clipboard.js integration */
const message$ = new Subject<string>()
@ -127,12 +127,19 @@ const app$ = merge(
.map(child => mountTableOfContents(child, { viewport$, header$ })),
)
// eslint-disable-next-line
app$.subscribe(console.log)
/* ------------------------------------------------------------------------- */
// put this somewhere else
/**
* Test
*
* @param toggle$ - Toggle observable
* @param factory - Observable factory
*
* @returns New observable
*/
function at<T>(
toggle$: Observable<boolean>, factory: () => Observable<T>
) {

View File

@ -31,7 +31,7 @@ import { share } from "rxjs/operators"
/**
* Set up Clipboard.js integration
*
* @return Clipboard.js event observable
* @returns Clipboard.js event observable
*/
export function setupClipboardJS(): Observable<ClipboardJS.Event> {
if (!ClipboardJS.isSupported())

View File

@ -0,0 +1,6 @@
{
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off"
}
}

View File

@ -113,7 +113,7 @@ export type SearchResult = Array<SearchDocument & SearchMetadata>
* @param a - 1st list of strings
* @param b - 2nd list of strings
*
* @return Difference
* @returns Difference
*/
function difference(a: string[], b: string[]): string[] {
const [x, y] = [new Set(a), new Set(b)]
@ -168,7 +168,7 @@ export class Search {
/* If no index was given, create it */
if (typeof index === "undefined") {
this.index = lunr(function() {
this.index = lunr(function () {
/* Set up multi-language support */
if (config.lang.length === 1 && config.lang[0] !== "en") {
@ -222,7 +222,7 @@ export class Search {
*
* @param query - Query value
*
* @return Search results
* @returns Search results
*/
public search(query: string): SearchResult[] {
if (query) {
@ -283,7 +283,6 @@ export class Search {
/* Log errors to console (for now) */
} catch {
// tslint:disable-next-line no-console
console.warn(`Invalid query: ${query} see https://bit.ly/2s3ChXG`)
}
}

View File

@ -51,7 +51,7 @@ export type SearchDocumentMap = Map<string, SearchDocument>
*
* @param docs - Search index documents
*
* @return Search document map
* @returns Search document map
*/
export function setupSearchDocumentMap(
docs: SearchIndexDocument[]

View File

@ -31,7 +31,7 @@ import { SearchIndexConfig } from "../_"
*
* @param value - Value
*
* @return Highlighted value
* @returns Highlighted value
*/
export type SearchHighlightFn = (value: string) => string
@ -40,7 +40,7 @@ export type SearchHighlightFn = (value: string) => string
*
* @param query - Query value
*
* @return Search highlight function
* @returns Search highlight function
*/
export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn
@ -53,7 +53,7 @@ export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn
*
* @param config - Search index configuration
*
* @return Search highlight factory function
* @returns Search highlight factory function
*/
export function setupSearchHighlighter(
config: SearchIndexConfig
@ -79,6 +79,6 @@ export function setupSearchHighlighter(
/* Highlight string value */
return value => value
.replace(match, highlight)
.replace(/<\/mark>(\s+)<mark[^>]*>/img, "\$1")
.replace(/<\/mark>(\s+)<mark[^>]*>/img, "$1")
}
}

View File

@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}

View File

@ -48,7 +48,7 @@ export type SearchQueryTerms = Record<string, boolean>
*
* @param value - Query value
*
* @return Search query clauses
* @returns Search query clauses
*/
export function parseSearchQuery(
value: string
@ -67,7 +67,7 @@ export function parseSearchQuery(
* @param query - Search query clauses
* @param terms - Search terms
*
* @return Search query terms
* @returns Search query terms
*/
export function getSearchQueryTerms(
query: SearchQueryClause[], terms: string[]

View File

@ -0,0 +1,5 @@
{
"rules": {
"no-control-regex": "off"
}
}

View File

@ -29,7 +29,7 @@
*
* @param value - Query value
*
* @return Transformed query value
* @returns Transformed query value
*/
export type SearchTransformFn = (value: string) => string
@ -56,7 +56,7 @@ export type SearchTransformFn = (value: string) => string
*
* @param query - Query value
*
* @return Transformed query value
* @returns Transformed query value
*/
export function defaultTransform(query: string): string {
return query

View File

@ -52,7 +52,7 @@ export type SearchWorker = WorkerHandler<SearchMessage>
*
* @param data - Search index
*
* @return Search index
* @returns Search index
*/
function setupSearchIndex(
{ config, docs, index }: SearchIndex
@ -91,7 +91,7 @@ function setupSearchIndex(
* @param url - Worker URL
* @param index - Promise resolving with search index
*
* @return Search worker
* @returns Search worker
*/
export function setupSearchWorker(
url: string, index: Promise<SearchIndex>

View File

@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/no-misused-promises": "off"
}
}

View File

@ -72,7 +72,7 @@ let index: Search
*
* @param config - Search index configuration
*
* @return Promise resolving with no result
* @returns Promise resolving with no result
*/
async function setupSearchLanguages(
config: SearchIndexConfig
@ -116,7 +116,7 @@ async function setupSearchLanguages(
*
* @param message - Source message
*
* @return Target message
* @returns Target message
*/
export async function handler(
message: SearchMessage

View File

@ -89,7 +89,7 @@ export type SearchMessage =
*
* @param message - Search worker message
*
* @return Test result
* @returns Test result
*/
export function isSearchSetupMessage(
message: SearchMessage
@ -102,7 +102,7 @@ export function isSearchSetupMessage(
*
* @param message - Search worker message
*
* @return Test result
* @returns Test result
*/
export function isSearchReadyMessage(
message: SearchMessage
@ -115,7 +115,7 @@ export function isSearchReadyMessage(
*
* @param message - Search worker message
*
* @return Test result
* @returns Test result
*/
export function isSearchQueryMessage(
message: SearchMessage
@ -128,7 +128,7 @@ export function isSearchQueryMessage(
*
* @param message - Search worker message
*
* @return Test result
* @returns Test result
*/
export function isSearchResultMessage(
message: SearchMessage

View File

@ -32,7 +32,7 @@ import { h } from "~/utilities"
*
* @param id - Unique identifier
*
* @return Element
* @returns Element
*/
export function renderClipboardButton(id: string) {
return (

View File

@ -50,7 +50,7 @@ const enum Flag {
* @param section - Search document
* @param flag - Render flags
*
* @return Element
* @returns Element
*/
function renderSearchDocument(
document: SearchDocument & SearchMetadata, flag: Flag
@ -103,7 +103,7 @@ function renderSearchDocument(
* @param result - Search result
* @param threshold - Score threshold
*
* @return Element
* @returns Element
*/
export function renderSearchResult(
result: SearchResult, threshold: number = Infinity

View File

@ -32,7 +32,7 @@ import { h } from "~/utilities"
*
* @param facts - Repository facts
*
* @return Element
* @returns Element
*/
export function renderSourceFacts(facts: SourceFacts) {
return (

View File

@ -31,7 +31,7 @@ import { h } from "utilities"
*
* @param table - Table element
*
* @return Element
* @returns Element
*/
export function renderTable(table: HTMLElement) {
return (

View File

@ -0,0 +1,6 @@
{
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-namespace": "off"
}
}

View File

@ -81,7 +81,7 @@ function appendChild(el: HTMLElement, child: Child | Child[]): void {
* @param attributes - HTML attributes
* @param children - Child elements
*
* @return Element
* @returns Element
*/
export function h(
tag: string, attributes: Attributes | null, ...children: Child[]

View File

@ -35,7 +35,7 @@
* @param value - Value to be truncated
* @param n - Number of characters
*
* @return Truncated value
* @returns Truncated value
*/
export function truncate(value: string, n: number): string {
let i = n
@ -60,7 +60,7 @@ export function truncate(value: string, n: number): string {
*
* @param value - Original value
*
* @return Rounded value
* @returns Rounded value
*/
export function round(value: number): string {
if (value > 999) {
@ -78,7 +78,7 @@ export function round(value: number): string {
*
* @param value - Value to be hashed
*
* @return Hash as 32bit integer
* @returns Hash as 32bit integer
*/
export function hash(value: string): number {
let h = 0

View File

@ -78,7 +78,7 @@ $break-devices: () !default;
@error "Invalid value: #{$value}";
}
}
@return $min, $max;
@returns $min, $max;
}
///
@ -96,7 +96,7 @@ $break-devices: () !default;
@if type-of($current) == list or type-of($current) == number {
$current: (default: $current);
}
@return break-select-min-max($current);
@returns break-select-min-max($current);
}
// ----------------------------------------------------------------------------

View File

@ -28,7 +28,7 @@
/// Strip units from a number
///
@function strip-units($number) {
@return $number / ($number * 0 + 1);
@returns $number / ($number * 0 + 1);
}
///
@ -52,7 +52,7 @@
@function px2em($size, $base: 16px) {
@if unit($size) == px {
@if unit($base) == px {
@return ($size / $base) * 1em;
@returns ($size / $base) * 1em;
} @else {
@error "Invalid base: #{$base} - unit must be 'px'";
}
@ -67,7 +67,7 @@
@function px2rem($size, $base: 20px) {
@if unit($size) == px {
@if unit($base) == px {
@return ($size / $base) * 1.0rem;
@returns ($size / $base) * 1.0rem;
} @else {
@error "Invalid base: #{$base} - unit must be 'px'";
}

View File

@ -1,116 +0,0 @@
{
"extends": [
"tslint:latest",
"tslint-sonarts"
],
"rules": {
"arrow-parens": [
true,
"ban-single-arg-parens"
],
"ban": [
true,
["fit"],
["fdescribe"],
["xit"],
["xdescribe"],
{
"name": "Object.assign",
"message": "Use the spread operator instead."
}
],
"class-name": true,
"comment-format": [
true,
"check-space"
],
"cognitive-complexity": false,
"curly": false,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"max-union-size": false,
"no-big-function": false,
"no-bitwise": false,
"no-duplicate-string": false,
"no-implicit-dependencies": false,
"no-identical-functions": false,
"no-internal-module": true,
"no-namespace": false,
"no-null-keyword": true,
"no-reference": false,
"no-submodule-imports": false,
"no-trailing-whitespace": true,
"no-var-keyword": true,
"object-literal-key-quotes": [
true,
"consistent-as-needed"
],
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"ordered-imports": [
true,
{
"import-sources-order": "case-insensitive-legacy",
"named-imports-order": "lowercase-last"
}
],
"prefer-const": true,
"prefer-for-of": false,
"quotemark": [
true,
"double",
"avoid-escape"
],
"semicolon": [
true,
"never"
],
"trailing-comma": [
true,
{
"multiline": {
"objects": "never",
"arrays": "never",
"functions": "never",
"typeLiterals": "never"
},
"esSpecCompliant": true
}
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type"
]
}
}

View File

@ -43,7 +43,7 @@ import AssetsManifestPlugin from "webpack-assets-manifest"
*
* @param args - Command-line arguments
*
* @return Webpack configuration
* @returns Webpack configuration
*/
function config(args: Configuration): Configuration {
const assets = {}
@ -188,7 +188,7 @@ function config(args: Configuration): Configuration {
* @param env - Webpack environment arguments
* @param args - Command-line arguments
*
* @return Webpack configurations
* @returns Webpack configurations
*/
export default (_env: never, args: Configuration): Configuration[] => {
const hash = args.mode === "production" ? ".[chunkhash].min" : ""