mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
Integrate Eslint and TypeScript into build & linting process (#142)
This commit is contained in:
parent
0487a82db6
commit
77e689e29a
23 changed files with 2002 additions and 133 deletions
28
.github/workflows/elixir.yml
vendored
28
.github/workflows/elixir.yml
vendored
|
@ -8,7 +8,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- name: Cache mix deps
|
||||||
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
_build
|
_build
|
||||||
|
@ -25,3 +26,28 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
docker-compose run app mix sobelow --config
|
docker-compose run app mix sobelow --config
|
||||||
docker-compose run app mix deps.audit
|
docker-compose run app mix deps.audit
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: Cache node_modules
|
||||||
|
id: cache-node-modules
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ./assets/node_modules
|
||||||
|
key: node_modules-${{ hashFiles('./assets/package-lock.json') }}
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||||
|
run: npm ci --ignore-scripts
|
||||||
|
working-directory: ./assets
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npm run lint
|
||||||
|
working-directory: ./assets
|
||||||
|
|
2
assets/.eslintignore
Normal file
2
assets/.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
js/vendor/*
|
||||||
|
webpack.config.js
|
|
@ -2,16 +2,24 @@ env:
|
||||||
browser: true
|
browser: true
|
||||||
es6: true
|
es6: true
|
||||||
|
|
||||||
|
parser: '@typescript-eslint/parser'
|
||||||
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
ecmaVersion: 6
|
ecmaVersion: 6
|
||||||
sourceType: module
|
sourceType: module
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- '@typescript-eslint'
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
ga: false
|
ga: false
|
||||||
md5: false
|
md5: false
|
||||||
Sortable: false
|
Sortable: false
|
||||||
ActionCable: false
|
ActionCable: false
|
||||||
|
|
||||||
|
extends:
|
||||||
|
- 'plugin:@typescript-eslint/recommended'
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
accessor-pairs: 2
|
accessor-pairs: 2
|
||||||
array-bracket-spacing: 0
|
array-bracket-spacing: 0
|
||||||
|
@ -83,7 +91,6 @@ rules:
|
||||||
no-console: 0
|
no-console: 0
|
||||||
no-const-assign: 2
|
no-const-assign: 2
|
||||||
no-constant-condition: 2
|
no-constant-condition: 2
|
||||||
no-continue: 2
|
|
||||||
no-control-regex: 2
|
no-control-regex: 2
|
||||||
no-debugger: 2
|
no-debugger: 2
|
||||||
no-delete-var: 2
|
no-delete-var: 2
|
||||||
|
@ -245,3 +252,10 @@ rules:
|
||||||
wrap-regex: 0
|
wrap-regex: 0
|
||||||
yield-star-spacing: 2
|
yield-star-spacing: 2
|
||||||
yoda: [2, 'never']
|
yoda: [2, 'never']
|
||||||
|
|
||||||
|
# Disable rules which are impossible to satisfy (types require .ts extension)
|
||||||
|
overrides:
|
||||||
|
- files:
|
||||||
|
- '*.js'
|
||||||
|
rules:
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 0
|
|
@ -1,2 +0,0 @@
|
||||||
vendor/*
|
|
||||||
match_query.js
|
|
|
@ -81,7 +81,8 @@ function initializeFilters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function unmarshal(data) {
|
function unmarshal(data) {
|
||||||
try { return JSON.parse(data); } catch (_) { return data; }
|
try { return JSON.parse(data); }
|
||||||
|
catch (_) { return data; }
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadBooruData() {
|
function loadBooruData() {
|
||||||
|
|
|
@ -31,14 +31,16 @@ const actions = {
|
||||||
|
|
||||||
disable(data) { selectorCb(data.base, data.value, el => el.disabled = true); },
|
disable(data) { selectorCb(data.base, data.value, el => el.disabled = true); },
|
||||||
|
|
||||||
copy(data) { document.querySelector(data.value).select();
|
copy(data) {
|
||||||
document.execCommand('copy'); },
|
document.querySelector(data.value).select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
},
|
||||||
|
|
||||||
inputvalue(data) { document.querySelector(data.value).value = data.el.dataset.setValue; },
|
inputvalue(data) { document.querySelector(data.value).value = data.el.dataset.setValue; },
|
||||||
|
|
||||||
selectvalue(data) { document.querySelector(data.value).value = data.el.querySelector(':checked').dataset.setValue; },
|
selectvalue(data) { document.querySelector(data.value).value = data.el.querySelector(':checked').dataset.setValue; },
|
||||||
|
|
||||||
checkall(data) { $$(`${data.value} input[type=checkbox]`).forEach(c => { c.checked = !c.checked; }) },
|
checkall(data) { $$(`${data.value} input[type=checkbox]`).forEach(c => { c.checked = !c.checked; }); },
|
||||||
|
|
||||||
focus(data) { document.querySelector(data.value).focus(); },
|
focus(data) { document.querySelector(data.value).focus(); },
|
||||||
|
|
||||||
|
@ -50,8 +52,8 @@ const actions = {
|
||||||
|
|
||||||
tab(data) {
|
tab(data) {
|
||||||
const block = data.el.parentNode.parentNode,
|
const block = data.el.parentNode.parentNode,
|
||||||
newTab = $(`.block__tab[data-tab="${data.value}"]`),
|
newTab = $(`.block__tab[data-tab="${data.value}"]`),
|
||||||
loadTab = data.el.dataset.loadTab;
|
loadTab = data.el.dataset.loadTab;
|
||||||
|
|
||||||
// Switch tab
|
// Switch tab
|
||||||
const selectedTab = block.querySelector('.selected');
|
const selectedTab = block.querySelector('.selected');
|
||||||
|
@ -100,8 +102,8 @@ function matchAttributes(event) {
|
||||||
for (const action in actions) {
|
for (const action in actions) {
|
||||||
|
|
||||||
const attr = `data-${event.type}-${action.toLowerCase()}`,
|
const attr = `data-${event.type}-${action.toLowerCase()}`,
|
||||||
el = event.target && event.target.closest(`[${attr}]`),
|
el = event.target && event.target.closest(`[${attr}]`),
|
||||||
value = el && el.getAttribute(attr);
|
value = el && el.getAttribute(attr);
|
||||||
|
|
||||||
if (el) {
|
if (el) {
|
||||||
// Return true if you don't want to preventDefault
|
// Return true if you don't want to preventDefault
|
||||||
|
|
|
@ -30,10 +30,12 @@ function commentPosted(response) {
|
||||||
|
|
||||||
if (requestOk) {
|
if (requestOk) {
|
||||||
response.text().then(text => {
|
response.text().then(text => {
|
||||||
if (text.includes('<div class="flash flash--warning">'))
|
if (text.includes('<div class="flash flash--warning">')) {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
displayComments(container, text);
|
displayComments(container, text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -47,9 +47,8 @@ function selectVersion(imageWidth, imageHeight, imageSize, imageMime) {
|
||||||
if (imageMime === 'video/webm' || imageSize <= 26214400) {
|
if (imageMime === 'video/webm' || imageSize <= 26214400) {
|
||||||
return 'full';
|
return 'full';
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return 'large';
|
return 'large';
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,9 +6,9 @@ import { fetchJson } from './utils/requests';
|
||||||
import { $ } from './utils/dom';
|
import { $ } from './utils/dom';
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
vote(imageId) { return `/images/${imageId}/vote` },
|
vote(imageId) { return `/images/${imageId}/vote`; },
|
||||||
fave(imageId) { return `/images/${imageId}/fave` },
|
fave(imageId) { return `/images/${imageId}/fave`; },
|
||||||
hide(imageId) { return `/images/${imageId}/hide` },
|
hide(imageId) { return `/images/${imageId}/hide`; },
|
||||||
};
|
};
|
||||||
|
|
||||||
const spoilerDownvoteMsg =
|
const spoilerDownvoteMsg =
|
||||||
|
@ -34,16 +34,16 @@ function modifyCache(callback) {
|
||||||
cacheEl.value = JSON.stringify(callback(JSON.parse(cacheEl.value)));
|
cacheEl.value = JSON.stringify(callback(JSON.parse(cacheEl.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function cacheStatus(image_id, interaction_type, value) {
|
function cacheStatus(imageId, interactionType, value) {
|
||||||
modifyCache(cache => {
|
modifyCache(cache => {
|
||||||
cache[`${image_id}${interaction_type}`] = { image_id, interaction_type, value };
|
cache[`${imageId}${interactionType}`] = { imageId, interactionType, value };
|
||||||
return cache;
|
return cache;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function uncacheStatus(image_id, interaction_type) {
|
function uncacheStatus(imageId, interactionType) {
|
||||||
modifyCache(cache => {
|
modifyCache(cache => {
|
||||||
delete cache[`${image_id}${interaction_type}`];
|
delete cache[`${imageId}${interactionType}`];
|
||||||
return cache;
|
return cache;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ function wrapSelection(textarea, options) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
newText = prefix + newText + suffix
|
newText = prefix + newText + suffix;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
newText,
|
newText,
|
||||||
|
@ -188,7 +188,7 @@ function wrapLines(textarea, options, eachLine = true) {
|
||||||
: text.split(/\n/g).map(line => prefix + line.trim() + suffix).join('\n');
|
: text.split(/\n/g).map(line => prefix + line.trim() + suffix).join('\n');
|
||||||
|
|
||||||
// Force a space at the end of lines with only blockquote markers
|
// Force a space at the end of lines with only blockquote markers
|
||||||
newText = newText.replace(/^((?:>\s+)*)>$/gm, '$1> ')
|
newText = newText.replace(/^((?:>\s+)*)>$/gm, '$1> ');
|
||||||
|
|
||||||
return { newText, caretOffset: emptyText ? prefix.length : newText.length };
|
return { newText, caretOffset: emptyText ? prefix.length : newText.length };
|
||||||
}, eachLine);
|
}, eachLine);
|
||||||
|
|
|
@ -5,18 +5,18 @@
|
||||||
|
|
||||||
const tokenList = [
|
const tokenList = [
|
||||||
['fuzz', /^~(?:\d+(\.\d+)?|\.\d+)/],
|
['fuzz', /^~(?:\d+(\.\d+)?|\.\d+)/],
|
||||||
['boost', /^\^[\-\+]?\d+(\.\d+)?/],
|
['boost', /^\^[-+]?\d+(\.\d+)?/],
|
||||||
['quoted_lit', /^\s*"(?:(?:[^"]|\\")+)"/],
|
['quoted_lit', /^\s*"(?:[^"]|\\")+"/],
|
||||||
['lparen', /^\s*\(\s*/],
|
['lparen', /^\s*\(\s*/],
|
||||||
['rparen', /^\s*\)\s*/],
|
['rparen', /^\s*\)\s*/],
|
||||||
['and_op', /^\s*(?:\&\&|AND)\s+/],
|
['and_op', /^\s*(?:&&|AND)\s+/],
|
||||||
['and_op', /^\s*,\s*/],
|
['and_op', /^\s*,\s*/],
|
||||||
['or_op', /^\s*(?:\|\||OR)\s+/],
|
['or_op', /^\s*(?:\|\||OR)\s+/],
|
||||||
['not_op', /^\s*NOT(?:\s+|(?=\())/],
|
['not_op', /^\s*NOT(?:\s+|(?=\())/],
|
||||||
['not_op', /^\s*[\!\-]\s*/],
|
['not_op', /^\s*[!-]\s*/],
|
||||||
['space', /^\s+/],
|
['space', /^\s+/],
|
||||||
['word', /^(?:[^\s,\(\)\^~]|\\[\s,\(\)\^~])+/],
|
['word', /^(?:[^\s,()^~]|\\[\s,()^~])+/],
|
||||||
['word', /^(?:[^\s,\(\)]|\\[\s,\(\)])+/]
|
['word', /^(?:[^\s,()]|\\[\s,()])+/]
|
||||||
],
|
],
|
||||||
numberFields = ['id', 'width', 'height', 'aspect_ratio',
|
numberFields = ['id', 'width', 'height', 'aspect_ratio',
|
||||||
'comment_count', 'score', 'upvotes', 'downvotes',
|
'comment_count', 'score', 'upvotes', 'downvotes',
|
||||||
|
@ -35,6 +35,7 @@ const tokenList = [
|
||||||
id: 'data-image-id',
|
id: 'data-image-id',
|
||||||
width: 'data-width',
|
width: 'data-width',
|
||||||
height: 'data-height',
|
height: 'data-height',
|
||||||
|
/* eslint-disable camelcase */
|
||||||
aspect_ratio: 'data-aspect-ratio',
|
aspect_ratio: 'data-aspect-ratio',
|
||||||
comment_count: 'data-comment-count',
|
comment_count: 'data-comment-count',
|
||||||
tag_count: 'data-tag-count',
|
tag_count: 'data-tag-count',
|
||||||
|
@ -43,10 +44,11 @@ const tokenList = [
|
||||||
sha512_hash: 'data-sha512',
|
sha512_hash: 'data-sha512',
|
||||||
orig_sha512_hash: 'data-orig-sha512',
|
orig_sha512_hash: 'data-orig-sha512',
|
||||||
created_at: 'data-created-at'
|
created_at: 'data-created-at'
|
||||||
|
/* eslint-enable camelcase */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function SearchTerm(termStr, options) {
|
function SearchTerm(termStr) {
|
||||||
this.term = termStr.trim();
|
this.term = termStr.trim();
|
||||||
this.parsed = false;
|
this.parsed = false;
|
||||||
}
|
}
|
||||||
|
@ -57,8 +59,6 @@ SearchTerm.prototype.append = function(substr) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.parseRangeField = function(field) {
|
SearchTerm.prototype.parseRangeField = function(field) {
|
||||||
let qual;
|
|
||||||
|
|
||||||
if (numberFields.indexOf(field) !== -1) {
|
if (numberFields.indexOf(field) !== -1) {
|
||||||
return [field, 'eq', 'number'];
|
return [field, 'eq', 'number'];
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ SearchTerm.prototype.parseRangeField = function(field) {
|
||||||
return [field, 'eq', 'date'];
|
return [field, 'eq', 'date'];
|
||||||
}
|
}
|
||||||
|
|
||||||
qual = /^(\w+)\.([lg]te?|eq)$/.exec(field);
|
const qual = /^(\w+)\.([lg]te?|eq)$/.exec(field);
|
||||||
|
|
||||||
if (qual) {
|
if (qual) {
|
||||||
if (numberFields.indexOf(qual[1]) !== -1) {
|
if (numberFields.indexOf(qual[1]) !== -1) {
|
||||||
|
@ -116,28 +116,29 @@ SearchTerm.prototype.parseRelativeDate = function(dateVal, qual) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw `Cannot parse date string: ${dateVal}`;
|
throw new Error(`Cannot parse date string: ${dateVal}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.parseAbsoluteDate = function(dateVal, qual) {
|
SearchTerm.prototype.parseAbsoluteDate = function(dateVal, qual) {
|
||||||
let parseRes = [
|
const parseRes = [
|
||||||
/^(\d{4})/,
|
/^(\d{4})/,
|
||||||
/^\-(\d{2})/,
|
/^-(\d{2})/,
|
||||||
/^\-(\d{2})/,
|
/^-(\d{2})/,
|
||||||
/^(?:\s+|T|t)(\d{2})/,
|
/^(?:\s+|T|t)(\d{2})/,
|
||||||
/^:(\d{2})/,
|
/^:(\d{2})/,
|
||||||
/^:(\d{2})/
|
/^:(\d{2})/
|
||||||
],
|
],
|
||||||
timeZoneOffset = [0, 0],
|
timeZoneOffset = [0, 0],
|
||||||
timeData = [0, 0, 1, 0, 0, 0],
|
timeData = [0, 0, 1, 0, 0, 0],
|
||||||
bottomDate = null,
|
origDateVal = dateVal;
|
||||||
topDate = null,
|
let topDate = null,
|
||||||
i,
|
i,
|
||||||
match,
|
match,
|
||||||
origDateVal = dateVal;
|
bottomDate = null,
|
||||||
|
localDateVal = origDateVal;
|
||||||
|
|
||||||
match = /([\+\-])(\d{2}):(\d{2})$/.exec(dateVal);
|
match = /([+-])(\d{2}):(\d{2})$/.exec(localDateVal);
|
||||||
if (match) {
|
if (match) {
|
||||||
timeZoneOffset[0] = parseInt(match[2], 10);
|
timeZoneOffset[0] = parseInt(match[2], 10);
|
||||||
timeZoneOffset[1] = parseInt(match[3], 10);
|
timeZoneOffset[1] = parseInt(match[3], 10);
|
||||||
|
@ -145,18 +146,18 @@ SearchTerm.prototype.parseAbsoluteDate = function(dateVal, qual) {
|
||||||
timeZoneOffset[0] *= -1;
|
timeZoneOffset[0] *= -1;
|
||||||
timeZoneOffset[1] *= -1;
|
timeZoneOffset[1] *= -1;
|
||||||
}
|
}
|
||||||
dateVal = dateVal.substr(0, dateVal.length - 6);
|
localDateVal = localDateVal.substr(0, localDateVal.length - 6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dateVal = dateVal.replace(/[Zz]$/, '');
|
localDateVal = localDateVal.replace(/[Zz]$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < parseRes.length; i += 1) {
|
for (i = 0; i < parseRes.length; i += 1) {
|
||||||
if (dateVal.length === 0) {
|
if (localDateVal.length === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
match = parseRes[i].exec(dateVal);
|
match = parseRes[i].exec(localDateVal);
|
||||||
if (match) {
|
if (match) {
|
||||||
if (i === 1) {
|
if (i === 1) {
|
||||||
timeData[i] = parseInt(match[1], 10) - 1;
|
timeData[i] = parseInt(match[1], 10) - 1;
|
||||||
|
@ -164,17 +165,17 @@ SearchTerm.prototype.parseAbsoluteDate = function(dateVal, qual) {
|
||||||
else {
|
else {
|
||||||
timeData[i] = parseInt(match[1], 10);
|
timeData[i] = parseInt(match[1], 10);
|
||||||
}
|
}
|
||||||
dateVal = dateVal.substr(
|
localDateVal = localDateVal.substr(
|
||||||
match[0].length, dateVal.length - match[0].length
|
match[0].length, localDateVal.length - match[0].length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw `Cannot parse date string: ${origDateVal}`;
|
throw new Error(`Cannot parse date string: ${origDateVal}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateVal.length > 0) {
|
if (localDateVal.length > 0) {
|
||||||
throw `Cannot parse date string: ${origDateVal}`;
|
throw new Error(`Cannot parse date string: ${origDateVal}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the user-specified time zone offset. The JS Date constructor
|
// Apply the user-specified time zone offset. The JS Date constructor
|
||||||
|
@ -210,9 +211,8 @@ SearchTerm.prototype.parseDate = function(dateVal, qual) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.parse = function(substr) {
|
SearchTerm.prototype.parse = function() {
|
||||||
let matchArr,
|
let rangeParsing,
|
||||||
rangeParsing,
|
|
||||||
candidateTermSpace,
|
candidateTermSpace,
|
||||||
termCandidate;
|
termCandidate;
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ SearchTerm.prototype.parse = function(substr) {
|
||||||
this.termSpace = 'tags';
|
this.termSpace = 'tags';
|
||||||
this.termType = 'literal';
|
this.termType = 'literal';
|
||||||
|
|
||||||
matchArr = this.term.split(':');
|
const matchArr = this.term.split(':');
|
||||||
|
|
||||||
if (matchArr.length > 1) {
|
if (matchArr.length > 1) {
|
||||||
candidateTermSpace = matchArr[0];
|
candidateTermSpace = matchArr[0];
|
||||||
|
@ -258,7 +258,7 @@ SearchTerm.prototype.parse = function(substr) {
|
||||||
this.term = termCandidate;
|
this.term = termCandidate;
|
||||||
this.termSpace = candidateTermSpace;
|
this.termSpace = candidateTermSpace;
|
||||||
}
|
}
|
||||||
else if (candidateTermSpace == 'my') {
|
else if (candidateTermSpace === 'my') {
|
||||||
this.termType = 'my';
|
this.termType = 'my';
|
||||||
this.termSpace = termCandidate;
|
this.termSpace = termCandidate;
|
||||||
}
|
}
|
||||||
|
@ -285,9 +285,9 @@ SearchTerm.prototype.parse = function(substr) {
|
||||||
|
|
||||||
SearchTerm.prototype._normalizeTerm = function() {
|
SearchTerm.prototype._normalizeTerm = function() {
|
||||||
if (!this.wildcardable) {
|
if (!this.wildcardable) {
|
||||||
return this.term.replace('\"', '"');
|
return this.term.replace('"', '"');
|
||||||
}
|
}
|
||||||
return this.term.replace(/\\([^\*\?])/g, '$1');
|
return this.term.replace(/\\([^*?])/g, '$1');
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.fuzzyMatch = function(targetStr) {
|
SearchTerm.prototype.fuzzyMatch = function(targetStr) {
|
||||||
|
@ -309,16 +309,16 @@ SearchTerm.prototype.fuzzyMatch = function(targetStr) {
|
||||||
targetDistance = this.fuzz;
|
targetDistance = this.fuzz;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetStr = targetStr.toLowerCase();
|
const targetStrLower = targetStr.toLowerCase();
|
||||||
|
|
||||||
for (i = 0; i <= targetStr.length; i += 1) {
|
for (i = 0; i <= targetStrLower.length; i += 1) {
|
||||||
v1.push(i);
|
v1.push(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < this.term.length; i += 1) {
|
for (i = 0; i < this.term.length; i += 1) {
|
||||||
v2[0] = i;
|
v2[0] = i;
|
||||||
for (j = 0; j < targetStr.length; j += 1) {
|
for (j = 0; j < targetStrLower.length; j += 1) {
|
||||||
const cost = this.term[i] === targetStr[j] ? 0 : 1;
|
const cost = this.term[i] === targetStrLower[j] ? 0 : 1;
|
||||||
v2[j + 1] = Math.min(
|
v2[j + 1] = Math.min(
|
||||||
// Deletion.
|
// Deletion.
|
||||||
v1[j + 1] + 1,
|
v1[j + 1] + 1,
|
||||||
|
@ -327,8 +327,8 @@ SearchTerm.prototype.fuzzyMatch = function(targetStr) {
|
||||||
// Substitution or No Change.
|
// Substitution or No Change.
|
||||||
v1[j] + cost
|
v1[j] + cost
|
||||||
);
|
);
|
||||||
if (i > 1 && j > 1 && this.term[i] === targetStr[j - 1] &&
|
if (i > 1 && j > 1 && this.term[i] === targetStrLower[j - 1] &&
|
||||||
targetStr[i - 1] === targetStr[j]) {
|
targetStrLower[i - 1] === targetStrLower[j]) {
|
||||||
v2[j + 1] = Math.min(v2[j], v0[j - 1] + cost);
|
v2[j + 1] = Math.min(v2[j], v0[j - 1] + cost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ SearchTerm.prototype.fuzzyMatch = function(targetStr) {
|
||||||
v2 = temp;
|
v2 = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v1[targetStr.length] <= targetDistance;
|
return v1[targetStrLower.length] <= targetDistance;
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.exactMatch = function(targetStr) {
|
SearchTerm.prototype.exactMatch = function(targetStr) {
|
||||||
|
@ -354,10 +354,8 @@ SearchTerm.prototype.interactionMatch = function(imageID, type, interaction, int
|
||||||
let ret = false;
|
let ret = false;
|
||||||
|
|
||||||
interactions.forEach(v => {
|
interactions.forEach(v => {
|
||||||
if (v.image_id == imageID && v.interaction_type == type && (interaction == null || v.value == interaction)) {
|
if (v.image_id === imageID && v.interaction_type === type && (interaction === null || v.value === interaction)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -365,8 +363,9 @@ SearchTerm.prototype.interactionMatch = function(imageID, type, interaction, int
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchTerm.prototype.match = function(target) {
|
SearchTerm.prototype.match = function(target) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-this-alias,consistent-this
|
||||||
|
const ohffs = this;
|
||||||
let ret = false,
|
let ret = false,
|
||||||
ohffs = this,
|
|
||||||
compFunc,
|
compFunc,
|
||||||
numbuh,
|
numbuh,
|
||||||
date;
|
date;
|
||||||
|
@ -427,9 +426,9 @@ SearchTerm.prototype.match = function(target) {
|
||||||
}
|
}
|
||||||
else if (this.termType === 'date') {
|
else if (this.termType === 'date') {
|
||||||
// Date matching.
|
// Date matching.
|
||||||
date = (new Date(
|
date = new Date(
|
||||||
target.getAttribute(termSpaceToImageField[this.termSpace])
|
target.getAttribute(termSpaceToImageField[this.termSpace])
|
||||||
)).getTime();
|
).getTime();
|
||||||
|
|
||||||
switch (this.compare) {
|
switch (this.compare) {
|
||||||
// The open-left, closed-right date range specified by the
|
// The open-left, closed-right date range specified by the
|
||||||
|
@ -481,23 +480,25 @@ SearchTerm.prototype.match = function(target) {
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateLexArray(searchStr, options) {
|
function generateLexArray(searchStr) {
|
||||||
let opQueue = [],
|
const opQueue = [],
|
||||||
searchTerm = null,
|
groupNegate = [],
|
||||||
|
tokenStack = [];
|
||||||
|
let searchTerm = null,
|
||||||
boost = null,
|
boost = null,
|
||||||
fuzz = null,
|
fuzz = null,
|
||||||
lparenCtr = 0,
|
lparenCtr = 0,
|
||||||
negate = false,
|
negate = false,
|
||||||
groupNegate = [],
|
boostFuzzStr = '',
|
||||||
tokenStack = [],
|
localSearchStr = searchStr;
|
||||||
boostFuzzStr = '';
|
|
||||||
|
|
||||||
while (searchStr.length > 0) {
|
while (localSearchStr.length > 0) {
|
||||||
|
// eslint-disable-next-line no-loop-func
|
||||||
tokenList.every(tokenArr => {
|
tokenList.every(tokenArr => {
|
||||||
let tokenName = tokenArr[0],
|
const tokenName = tokenArr[0],
|
||||||
tokenRE = tokenArr[1],
|
tokenRE = tokenArr[1];
|
||||||
match = tokenRE.exec(searchStr),
|
let match = tokenRE.exec(localSearchStr),
|
||||||
balanced, op;
|
op;
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
match = match[0];
|
match = match[0];
|
||||||
|
@ -560,15 +561,18 @@ function generateLexArray(searchStr, options) {
|
||||||
break;
|
break;
|
||||||
case 'rparen':
|
case 'rparen':
|
||||||
if (lparenCtr > 0) {
|
if (lparenCtr > 0) {
|
||||||
searchTerm.append(match);
|
if (searchTerm) {
|
||||||
|
searchTerm.append(match);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
searchTerm = new SearchTerm(match);
|
||||||
|
}
|
||||||
lparenCtr -= 1;
|
lparenCtr -= 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
balanced = false;
|
|
||||||
while (opQueue.length) {
|
while (opQueue.length) {
|
||||||
op = opQueue.shift();
|
op = opQueue.shift();
|
||||||
if (op === 'lparen') {
|
if (op === 'lparen') {
|
||||||
balanced = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tokenStack.push(op);
|
tokenStack.push(op);
|
||||||
|
@ -587,7 +591,7 @@ function generateLexArray(searchStr, options) {
|
||||||
boostFuzzStr += match;
|
boostFuzzStr += match;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
searchTerm = new SearchTerm(match, options);
|
searchTerm = new SearchTerm(match);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'boost':
|
case 'boost':
|
||||||
|
@ -596,7 +600,7 @@ function generateLexArray(searchStr, options) {
|
||||||
boostFuzzStr += match;
|
boostFuzzStr += match;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
searchTerm = new SearchTerm(match, options);
|
searchTerm = new SearchTerm(match);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'quoted_lit':
|
case 'quoted_lit':
|
||||||
|
@ -604,7 +608,7 @@ function generateLexArray(searchStr, options) {
|
||||||
searchTerm.append(match);
|
searchTerm.append(match);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
searchTerm = new SearchTerm(match, options);
|
searchTerm = new SearchTerm(match);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'word':
|
case 'word':
|
||||||
|
@ -617,7 +621,7 @@ function generateLexArray(searchStr, options) {
|
||||||
searchTerm.append(match);
|
searchTerm.append(match);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
searchTerm = new SearchTerm(match, options);
|
searchTerm = new SearchTerm(match);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -628,8 +632,8 @@ function generateLexArray(searchStr, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate string and restart the token tests.
|
// Truncate string and restart the token tests.
|
||||||
searchStr = searchStr.substr(
|
localSearchStr = localSearchStr.substr(
|
||||||
match.length, searchStr.length - match.length
|
match.length, localSearchStr.length - match.length
|
||||||
);
|
);
|
||||||
|
|
||||||
// Break since we have found a match.
|
// Break since we have found a match.
|
||||||
|
@ -652,7 +656,7 @@ function generateLexArray(searchStr, options) {
|
||||||
|
|
||||||
if (opQueue.indexOf('rparen') !== -1 ||
|
if (opQueue.indexOf('rparen') !== -1 ||
|
||||||
opQueue.indexOf('lparen') !== -1) {
|
opQueue.indexOf('lparen') !== -1) {
|
||||||
throw 'Mismatched parentheses.';
|
throw new Error('Mismatched parentheses.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory-efficient concatenation of remaining operators queue to the
|
// Memory-efficient concatenation of remaining operators queue to the
|
||||||
|
@ -663,8 +667,8 @@ function generateLexArray(searchStr, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTokens(lexicalArray) {
|
function parseTokens(lexicalArray) {
|
||||||
let operandStack = [],
|
const operandStack = [];
|
||||||
negate, op1, op2, parsed;
|
let negate, op1, op2;
|
||||||
lexicalArray.forEach((token, i) => {
|
lexicalArray.forEach((token, i) => {
|
||||||
if (token !== 'not_op') {
|
if (token !== 'not_op') {
|
||||||
negate = lexicalArray[i + 1] === 'not_op';
|
negate = lexicalArray[i + 1] === 'not_op';
|
||||||
|
@ -674,7 +678,7 @@ function parseTokens(lexicalArray) {
|
||||||
op1 = operandStack.pop();
|
op1 = operandStack.pop();
|
||||||
|
|
||||||
if (typeof op1 === 'undefined' || typeof op2 === 'undefined') {
|
if (typeof op1 === 'undefined' || typeof op2 === 'undefined') {
|
||||||
throw 'Missing operand.';
|
throw new Error('Missing operand.');
|
||||||
}
|
}
|
||||||
|
|
||||||
operandStack.push(new SearchAST(token, negate, op1, op2));
|
operandStack.push(new SearchAST(token, negate, op1, op2));
|
||||||
|
@ -691,7 +695,7 @@ function parseTokens(lexicalArray) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (operandStack.length > 1) {
|
if (operandStack.length > 1) {
|
||||||
throw 'Missing operator.';
|
throw new Error('Missing operator.');
|
||||||
}
|
}
|
||||||
|
|
||||||
op1 = operandStack.pop();
|
op1 = operandStack.pop();
|
||||||
|
@ -707,8 +711,8 @@ function parseTokens(lexicalArray) {
|
||||||
return op1;
|
return op1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSearch(searchStr, options) {
|
function parseSearch(searchStr) {
|
||||||
return parseTokens(generateLexArray(searchStr, options));
|
return parseTokens(generateLexArray(searchStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isTerminal(operand) {
|
function isTerminal(operand) {
|
||||||
|
@ -724,25 +728,27 @@ function SearchAST(op, negate, leftOperand, rightOperand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function combineOperands(ast1, ast2, parentAST) {
|
function combineOperands(ast1, ast2, parentAST) {
|
||||||
|
let localAst1;
|
||||||
if (parentAST.op === 'and_op') {
|
if (parentAST.op === 'and_op') {
|
||||||
ast1 = ast1 && ast2;
|
localAst1 = ast1 && ast2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ast1 = ast1 || ast2;
|
localAst1 = ast1 || ast2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentAST.negate) {
|
if (parentAST.negate) {
|
||||||
return !ast1;
|
return !localAst1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast1;
|
return localAst1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluation of the AST in regard to a target image
|
// Evaluation of the AST in regard to a target image
|
||||||
SearchAST.prototype.hitsImage = function(image) {
|
SearchAST.prototype.hitsImage = function(image) {
|
||||||
let treeStack = [],
|
const treeStack = [];
|
||||||
// Left side node.
|
// Left side node.
|
||||||
ast1 = this,
|
// eslint-disable-next-line @typescript-eslint/no-this-alias,consistent-this
|
||||||
|
let ast1 = this,
|
||||||
// Right side node.
|
// Right side node.
|
||||||
ast2,
|
ast2,
|
||||||
// Parent node of the current subtree.
|
// Parent node of the current subtree.
|
||||||
|
@ -834,9 +840,9 @@ SearchAST.prototype.hitsImage = function(image) {
|
||||||
SearchAST.prototype.dumpTree = function() {
|
SearchAST.prototype.dumpTree = function() {
|
||||||
// Dumps to string a simple diagram of the syntax tree structure
|
// Dumps to string a simple diagram of the syntax tree structure
|
||||||
// (starting with this object as the root) for debugging purposes.
|
// (starting with this object as the root) for debugging purposes.
|
||||||
let retStrArr = [],
|
const retStrArr = [],
|
||||||
treeQueue = [['', this]],
|
treeQueue = [['', this]];
|
||||||
treeArr,
|
let treeArr,
|
||||||
prefix,
|
prefix,
|
||||||
tree;
|
tree;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { delegate } from './utils/events';
|
||||||
import store from './utils/store';
|
import store from './utils/store';
|
||||||
|
|
||||||
const NOTIFICATION_INTERVAL = 600000,
|
const NOTIFICATION_INTERVAL = 600000,
|
||||||
NOTIFICATION_EXPIRES = 300000;
|
NOTIFICATION_EXPIRES = 300000;
|
||||||
|
|
||||||
function makeRequest(verb) {
|
function makeRequest(verb) {
|
||||||
return fetchJson(verb, '/notifications/unread').then(handleError);
|
return fetchJson(verb, '/notifications/unread').then(handleError);
|
||||||
|
@ -17,7 +17,7 @@ function makeRequest(verb) {
|
||||||
function bindSubscriptionLinks() {
|
function bindSubscriptionLinks() {
|
||||||
delegate(document, 'fetchcomplete', {
|
delegate(document, 'fetchcomplete', {
|
||||||
'.js-subscription-link': event => {
|
'.js-subscription-link': event => {
|
||||||
const target = $("#js-subscription-target");
|
const target = $('#js-subscription-target');
|
||||||
event.detail.text().then(text => {
|
event.detail.text().then(text => {
|
||||||
target.outerHTML = text;
|
target.outerHTML = text;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { $, $$, clearEl, removeEl, insertBefore } from './utils/dom';
|
import { $, $$, removeEl} from './utils/dom';
|
||||||
import { delegate, leftClick } from './utils/events';
|
import { delegate, leftClick } from './utils/events';
|
||||||
|
|
||||||
function pollOptionRemover(_event, target) {
|
function pollOptionRemover(_event, target) {
|
||||||
|
@ -28,7 +28,7 @@ function pollOptionCreator() {
|
||||||
const newHtml = prevFieldCopy.outerHTML.replace(/(\d+)/g, `${existingOptionCount}`);
|
const newHtml = prevFieldCopy.outerHTML.replace(/(\d+)/g, `${existingOptionCount}`);
|
||||||
|
|
||||||
// Insert copy before the button
|
// Insert copy before the button
|
||||||
addPollOptionButton.insertAdjacentHTML("beforebegin", newHtml);
|
addPollOptionButton.insertAdjacentHTML('beforebegin', newHtml);
|
||||||
existingOptionCount++;
|
existingOptionCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,11 @@ function setupPreviews() {
|
||||||
|
|
||||||
const getCacheKey = () => {
|
const getCacheKey = () => {
|
||||||
return (previewAnon && previewAnon.checked ? 'anon;' : '') + textarea.value;
|
return (previewAnon && previewAnon.checked ? 'anon;' : '') + textarea.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
const previewedTextAttribute = 'data-previewed-text';
|
const previewedTextAttribute = 'data-previewed-text';
|
||||||
const updatePreview = () => {
|
const updatePreview = () => {
|
||||||
const cachedValue = getCacheKey()
|
const cachedValue = getCacheKey();
|
||||||
if (previewContent.getAttribute(previewedTextAttribute) === cachedValue) return;
|
if (previewContent.getAttribute(previewedTextAttribute) === cachedValue) return;
|
||||||
previewContent.setAttribute(previewedTextAttribute, cachedValue);
|
previewContent.setAttribute(previewedTextAttribute, cachedValue);
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ const keyCodes = {
|
||||||
82() { click('.js-rand'); }, // R - go to random image
|
82() { click('.js-rand'); }, // R - go to random image
|
||||||
83() { click('.js-source-link'); }, // S - go to image source
|
83() { click('.js-source-link'); }, // S - go to image source
|
||||||
76() { click('.js-tag-sauce-toggle'); }, // L - edit tags
|
76() { click('.js-tag-sauce-toggle'); }, // L - edit tags
|
||||||
79() { openFullView() }, // O - open original
|
79() { openFullView(); }, // O - open original
|
||||||
86() { openFullViewNewTab() }, // V - open original in a new tab
|
86() { openFullViewNewTab(); }, // V - open original in a new tab
|
||||||
70() { // F - favourite image
|
70() { // F - favourite image
|
||||||
getHover() ? click(`a.interaction--fave[data-image-id="${getHover()}"]`)
|
getHover() ? click(`a.interaction--fave[data-image-id="${getHover()}"]`)
|
||||||
: click('.block__header a.interaction--fave');
|
: click('.block__header a.interaction--fave');
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import { $$ } from './utils/dom';
|
import { $$ } from './utils/dom';
|
||||||
|
|
||||||
function hideStaffTools() {
|
function hideStaffTools() {
|
||||||
if (window.booru.hideStaffTools == "true") {
|
if (window.booru.hideStaffTools === 'true') {
|
||||||
$$('.js-staff-action').forEach(el => {
|
$$('.js-staff-action').forEach(el => {
|
||||||
el.classList.add('hidden');
|
el.classList.add('hidden');
|
||||||
});
|
});
|
||||||
|
|
|
@ -102,7 +102,7 @@ function setupTagsInput(tagBlock) {
|
||||||
if (name.length === 0 || tags.indexOf(name) !== -1) return;
|
if (name.length === 0 || tags.indexOf(name) !== -1) return;
|
||||||
|
|
||||||
// Remove instead if the tag name starts with a minus
|
// Remove instead if the tag name starts with a minus
|
||||||
if (name[0] === "-") {
|
if (name[0] === '-') {
|
||||||
name = name.slice(1); // eslint-disable-line no-param-reassign
|
name = name.slice(1); // eslint-disable-line no-param-reassign
|
||||||
const tagLink = $(`[data-tag-name="${escapeCss(name)}"]`, container);
|
const tagLink = $(`[data-tag-name="${escapeCss(name)}"]`, container);
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,11 @@ function formRemote(event, target) {
|
||||||
headers: headers(),
|
headers: headers(),
|
||||||
body: new FormData(target)
|
body: new FormData(target)
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (response && response.status == 300) {
|
if (response && response.status === 300) {
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fire(target, 'fetchcomplete', response)
|
fire(target, 'fetchcomplete', response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ function setupImageUpload() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch on "enter" in url field
|
// Fetch on "enter" in url field
|
||||||
remoteUrl.addEventListener("keydown", function(event) {
|
remoteUrl.addEventListener('keydown', event => {
|
||||||
if (event.keyCode === 13) { // Hit enter
|
if (event.keyCode === 13) { // Hit enter
|
||||||
fetchButton.click();
|
fetchButton.click();
|
||||||
}
|
}
|
||||||
|
|
1792
assets/package-lock.json
generated
1792
assets/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,21 +1,28 @@
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"deploy": "cross-env NODE_ENV=production webpack",
|
"deploy": "cross-env NODE_ENV=production webpack",
|
||||||
|
"lint": "eslint . --ext .js,.ts",
|
||||||
"watch": "webpack --watch"
|
"watch": "webpack --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"brunch": "^3.0.0",
|
"brunch": "^3.0.0",
|
||||||
"copycat-brunch": "^1.1.1",
|
"copycat-brunch": "^1.1.1",
|
||||||
"postcss": "^8.3.7"
|
"postcss": "^8.3.7",
|
||||||
|
"tslib": "^2.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.32.0",
|
||||||
|
"@typescript-eslint/parser": "^4.32.0",
|
||||||
"acorn": "^7.4.1",
|
"acorn": "^7.4.1",
|
||||||
"autoprefixer": "^10.3.5",
|
"autoprefixer": "^10.3.5",
|
||||||
"copy-webpack-plugin": "^6.4.1",
|
"copy-webpack-plugin": "^6.4.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^5.2.7",
|
"css-loader": "^5.2.7",
|
||||||
"css-minimizer-webpack-plugin": "^2.0.0",
|
"css-minimizer-webpack-plugin": "^2.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-webpack-plugin": "^3.0.1",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"ignore-emit-webpack-plugin": "^2.0.6",
|
"ignore-emit-webpack-plugin": "^2.0.6",
|
||||||
"mini-css-extract-plugin": "^2.3.0",
|
"mini-css-extract-plugin": "^2.3.0",
|
||||||
|
@ -33,6 +40,7 @@
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
"style-loader": "^1.3.0",
|
"style-loader": "^1.3.0",
|
||||||
"terser-webpack-plugin": "^3.1.0",
|
"terser-webpack-plugin": "^3.1.0",
|
||||||
|
"typescript": "^4.4",
|
||||||
"webpack": "^5.53.0",
|
"webpack": "^5.53.0",
|
||||||
"webpack-cli": "^4.8.0",
|
"webpack-cli": "^4.8.0",
|
||||||
"webpack-rollup-loader": "^0.8.0"
|
"webpack-rollup-loader": "^0.8.0"
|
||||||
|
|
9
assets/tsconfig.json
Normal file
9
assets/tsconfig.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"baseUrl": "./js",
|
||||||
|
"target": "ES2018",
|
||||||
|
"allowJs": true,
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,12 +5,14 @@ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||||
const CopyPlugin = require('copy-webpack-plugin');
|
const CopyPlugin = require('copy-webpack-plugin');
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin');
|
const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin');
|
||||||
|
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||||
|
|
||||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
const includePaths = require('rollup-plugin-includepaths')();
|
const includePaths = require('rollup-plugin-includepaths')();
|
||||||
const multiEntry = require('rollup-plugin-multi-entry')();
|
const multiEntry = require('rollup-plugin-multi-entry')();
|
||||||
const buble = require('rollup-plugin-buble')({ transforms: { dangerousForOf: true } });
|
const buble = require('rollup-plugin-buble')({ transforms: { dangerousForOf: true } });
|
||||||
|
const typescript = require('@rollup/plugin-typescript')();
|
||||||
|
|
||||||
let plugins = [
|
let plugins = [
|
||||||
new IgnoreEmitPlugin(/css\/.*(?<!css)$/),
|
new IgnoreEmitPlugin(/css\/.*(?<!css)$/),
|
||||||
|
@ -24,7 +26,16 @@ let plugins = [
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
if (!isDevelopment){
|
if (isDevelopment) {
|
||||||
|
plugins = plugins.concat([
|
||||||
|
new ESLintPlugin({
|
||||||
|
extensions: ['js', 'ts'],
|
||||||
|
failOnError: true,
|
||||||
|
failOnWarning: isDevelopment
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
plugins = plugins.concat([
|
plugins = plugins.concat([
|
||||||
new TerserPlugin({
|
new TerserPlugin({
|
||||||
cache: true,
|
cache: true,
|
||||||
|
@ -90,6 +101,7 @@ module.exports = {
|
||||||
buble,
|
buble,
|
||||||
includePaths,
|
includePaths,
|
||||||
multiEntry,
|
multiEntry,
|
||||||
|
typescript,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue