Merge pull request #29 from JohnXLivingston/typescript

Typescript
This commit is contained in:
John Livingston 2021-04-07 18:32:43 +02:00 committed by GitHub
commit 5d8102c64d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 950 additions and 108 deletions

View File

@ -1,23 +1,9 @@
{ {
"root": true, "root": true,
"env": { "env": {},
"browser": true, "extends": [],
"es6": true
},
"extends": [
"standard"
],
"globals": {}, "globals": {},
"plugins": [], "plugins": [],
"ignorePatterns": ["node_modules/", "dist/", "webpack.config.js"], "ignorePatterns": ["node_modules/", "dist/", "webpack.config.js"],
"rules": { "rules": {}
"max-len": [
"error",
{
"code": 120,
"comments": 120
}
],
"no-unused-vars": [2, {"argsIgnorePattern": "^_"}]
}
} }

View File

@ -1,5 +1,9 @@
# Changelog # Changelog
## ???
* Code is now in Typescript
## v1.0.8 ## v1.0.8
* Fix: typo that can prevent settings chat-only-locals to work * Fix: typo that can prevent settings chat-only-locals to work

40
client/.eslintrc.json Normal file
View File

@ -0,0 +1,40 @@
{
"root": true,
"env": {
"browser": true,
"es6": true
},
"extends": [
"standard-with-typescript"
],
"globals": {},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"project": [
"./client/tsconfig.json"
]
},
"plugins": [
"@typescript-eslint"
],
"ignorePatterns": [],
"rules": {
"@typescript-eslint/no-unused-vars": [2, {"argsIgnorePattern": "^_"}],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/return-await": [2, "in-try-catch"], // FIXME: correct?
"@typescript-eslint/no-invalid-void-type": "off",
"@typescript-eslint/triple-slash-reference": "off",
"max-len": [
"error",
{
"code": 120,
"comments": 120
}
],
"no-unused-vars": "off"
}
}

View File

@ -1,7 +1,7 @@
'use strict' 'use strict'
function register ({ registerHook, _peertubeHelpers }) { function register ({ registerHook }: RegisterOptions): void {
registerHook({ registerHook({
target: 'action:router.navigation-end', target: 'action:router.navigation-end',
handler: () => { handler: () => {

11
client/peertube.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
interface RegisterOptions {
registerHook: any
peertubeHelpers: any
}
interface Video {
isLive: boolean
isLocal: boolean
originInstanceUrl: string
uuid: string
}

20
client/tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"module": "es6",
"target": "es5",
"allowJs": true,
"sourceMap": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"alwaysStrict": true, // should already be true because of strict:true
"noImplicitAny": true, // should already be true because of strict:true
"noImplicitThis": true, // should already be true because of strict:true
"noImplicitReturns": true,
"strictBindCallApply": true, // should already be true because of strict:true
"noUnusedLocals": true,
"outDir": "../dist/client",
"paths": {}
},
"include": ["./**/*"],
"exclude": []
}

View File

@ -1,18 +1,20 @@
'use strict' 'use strict'
function register ({ registerHook, peertubeHelpers }) { interface VideoCache {[key: string]: Video}
function register ({ registerHook, peertubeHelpers }: RegisterOptions): void {
const logger = { const logger = {
log: (s) => console.log('[peertube-plugin-livechat] ' + s), log: (s: string) => console.log('[peertube-plugin-livechat] ' + s),
info: (s) => console.info('[peertube-plugin-livechat] ' + s), info: (s: string) => console.info('[peertube-plugin-livechat] ' + s),
error: (s) => console.error('[peertube-plugin-livechat] ' + s), error: (s: string) => console.error('[peertube-plugin-livechat] ' + s),
warn: (s) => console.warn('[peertube-plugin-livechat] ' + s) warn: (s: string) => console.warn('[peertube-plugin-livechat] ' + s)
} }
const videoCache = {} const videoCache: VideoCache = {}
let lastUUID = null let lastUUID: string | null = null
let settings = {} let settings: any = {}
function parseUUIDs (s) { function parseUUIDs (s: string): string[] {
if (!s) { if (!s) {
return [] return []
} }
@ -25,7 +27,7 @@ function register ({ registerHook, peertubeHelpers }) {
return a.filter(line => line !== '') return a.filter(line => line !== '')
} }
function getBaseRoute () { function getBaseRoute (): string {
// FIXME: should be provided by PeertubeHelpers (does not exists for now) // FIXME: should be provided by PeertubeHelpers (does not exists for now)
// We are guessing the route with the correct plugin version with this trick: // We are guessing the route with the correct plugin version with this trick:
const staticBase = peertubeHelpers.getBaseStaticRoute() const staticBase = peertubeHelpers.getBaseStaticRoute()
@ -33,7 +35,7 @@ function register ({ registerHook, peertubeHelpers }) {
return staticBase.replace(/\/static.*$/, '/router') return staticBase.replace(/\/static.*$/, '/router')
} }
function getIframeUri (uuid) { function getIframeUri (uuid: string): string | null {
if (!settings) { if (!settings) {
logger.error('Settings are not initialized, too soon to compute the iframeUri') logger.error('Settings are not initialized, too soon to compute the iframeUri')
return null return null
@ -52,7 +54,7 @@ function register ({ registerHook, peertubeHelpers }) {
// we need to pass the complete url. // we need to pass the complete url.
const video = videoCache[uuid] const video = videoCache[uuid]
if (video) { if (video) {
const url = video.originInstanceUrl + '/videos/watch/' + uuid const url: string = video.originInstanceUrl + '/videos/watch/' + uuid
iframeUri = getBaseRoute() + '/webchat?url=' + encodeURIComponent(url) iframeUri = getBaseRoute() + '/webchat?url=' + encodeURIComponent(url)
} }
} }
@ -63,7 +65,13 @@ function register ({ registerHook, peertubeHelpers }) {
return iframeUri return iframeUri
} }
function displayButton (buttonContainer, name, label, callback, icon) { function displayButton (
buttonContainer: HTMLElement,
name: string,
label: string,
callback: () => void | boolean,
icon: string | null
): void {
const button = document.createElement('button') const button = document.createElement('button')
button.classList.add( button.classList.add(
'peertube-plugin-livechat-button', 'peertube-plugin-livechat-button',
@ -71,7 +79,8 @@ function register ({ registerHook, peertubeHelpers }) {
) )
button.onclick = callback button.onclick = callback
if (icon) { if (icon) {
const iconUrl = peertubeHelpers.getBaseStaticRoute() + '/images/' + icon // FIXME: remove «as string» when peertube types will be available
const iconUrl = (peertubeHelpers.getBaseStaticRoute() as string) + '/images/' + icon
const iconEl = document.createElement('span') const iconEl = document.createElement('span')
iconEl.classList.add('peertube-plugin-livechat-button-icon') iconEl.classList.add('peertube-plugin-livechat-button-icon')
iconEl.setAttribute('style', iconEl.setAttribute('style',
@ -85,9 +94,10 @@ function register ({ registerHook, peertubeHelpers }) {
buttonContainer.append(button) buttonContainer.append(button)
} }
function insertChatDom (container, peertubeHelpers, uuid, showOpenBlank) { async function insertChatDom (container: HTMLElement, uuid: string, showOpenBlank: boolean): Promise<void> {
logger.log('Adding livechat in the DOM...') logger.log('Adding livechat in the DOM...')
const p = new Promise((resolve, reject) => { const p = new Promise<void>((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Promise.all([ Promise.all([
peertubeHelpers.translate('Open chat'), peertubeHelpers.translate('Open chat'),
peertubeHelpers.translate('Open chat in a new window'), peertubeHelpers.translate('Open chat in a new window'),
@ -121,51 +131,46 @@ function register ({ registerHook, peertubeHelpers }) {
return p return p
} }
function openChat () { function openChat (): void | boolean {
const p = new Promise((resolve, reject) => { const uuid = lastUUID
const uuid = lastUUID if (!uuid) {
if (!uuid) { logger.log('No current uuid.')
logger.log('No current uuid.') return false
return reject(new Error('No current uuid.')) }
}
logger.info('Trying to load the chat for video ' + uuid + '.') logger.info('Trying to load the chat for video ' + uuid + '.')
const iframeUri = getIframeUri(uuid) const iframeUri = getIframeUri(uuid)
if (!iframeUri) { if (!iframeUri) {
logger.error('Incorrect iframe uri') logger.error('Incorrect iframe uri')
return reject(new Error('Incorrect iframe uri')) return false
} }
const additionalStyles = settings['chat-style'] || '' const additionalStyles = settings['chat-style'] || ''
logger.info('Opening the chat...') logger.info('Opening the chat...')
const container = document.getElementById('peertube-plugin-livechat-container') const container = document.getElementById('peertube-plugin-livechat-container')
if (!container) { if (!container) {
logger.error('Cant found the livechat container.') logger.error('Cant found the livechat container.')
return reject(new Error('Cant found the livechat container')) return false
} }
if (container.querySelector('iframe')) { if (container.querySelector('iframe')) {
logger.error('Seems that there is already an iframe in the container.') logger.error('Seems that there is already an iframe in the container.')
return reject(new Error('Seems that there is already an iframe in the container.')) return false
} }
// Creating the iframe... // Creating the iframe...
const iframe = document.createElement('iframe') const iframe = document.createElement('iframe')
iframe.setAttribute('src', iframeUri) iframe.setAttribute('src', iframeUri)
iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms') iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms')
iframe.setAttribute('frameborder', '0') iframe.setAttribute('frameborder', '0')
if (additionalStyles) { if (additionalStyles) {
iframe.setAttribute('style', additionalStyles) iframe.setAttribute('style', additionalStyles)
} }
container.append(iframe) container.append(iframe)
container.setAttribute('peertube-plugin-livechat-state', 'open') container.setAttribute('peertube-plugin-livechat-state', 'open')
resolve()
})
return p
} }
function closeChat () { function closeChat (): void {
const container = document.getElementById('peertube-plugin-livechat-container') const container = document.getElementById('peertube-plugin-livechat-container')
if (!container) { if (!container) {
logger.error('Cant close livechat, container not found.') logger.error('Cant close livechat, container not found.')
@ -177,7 +182,7 @@ function register ({ registerHook, peertubeHelpers }) {
container.setAttribute('peertube-plugin-livechat-state', 'closed') container.setAttribute('peertube-plugin-livechat-state', 'closed')
} }
function initChat () { function initChat (): void {
const videoWrapper = document.querySelector('#video-wrapper') const videoWrapper = document.querySelector('#video-wrapper')
if (!videoWrapper) { if (!videoWrapper) {
logger.error('The required div is not present in the DOM.') logger.error('The required div is not present in the DOM.')
@ -193,7 +198,7 @@ function register ({ registerHook, peertubeHelpers }) {
container.setAttribute('peertube-plugin-livechat-state', 'initializing') container.setAttribute('peertube-plugin-livechat-state', 'initializing')
videoWrapper.append(container) videoWrapper.append(container)
peertubeHelpers.getSettings().then(s => { peertubeHelpers.getSettings().then((s: any) => {
settings = s settings = s
const liveOn = !!settings['chat-all-lives'] const liveOn = !!settings['chat-all-lives']
const nonLiveOn = !!settings['chat-all-non-lives'] const nonLiveOn = !!settings['chat-all-non-lives']
@ -205,6 +210,10 @@ function register ({ registerHook, peertubeHelpers }) {
logger.log('Checking if this video should have a chat...') logger.log('Checking if this video should have a chat...')
const uuid = lastUUID const uuid = lastUUID
if (!uuid) {
logger.error('There is no lastUUID.')
return
}
const video = videoCache[uuid] const video = videoCache[uuid]
if (!video) { if (!video) {
logger.error('Can\'t find the video ' + uuid + ' in the videoCache') logger.error('Can\'t find the video ' + uuid + ' in the videoCache')
@ -215,7 +224,7 @@ function register ({ registerHook, peertubeHelpers }) {
return return
} }
if (uuids.indexOf(uuid) >= 0) { if (uuids.includes(uuid)) {
logger.log('This video is in the list for chats.') logger.log('This video is in the list for chats.')
} else if (video.isLive && liveOn) { } else if (video.isLive && liveOn) {
logger.log('This video is live and we want all lives.') logger.log('This video is live and we want all lives.')
@ -226,10 +235,11 @@ function register ({ registerHook, peertubeHelpers }) {
return return
} }
insertChatDom(container, peertubeHelpers, uuid, !!settings['chat-open-blank']).then(() => { // eslint-disable-next-line @typescript-eslint/no-floating-promises
insertChatDom(container as HTMLElement, uuid, !!settings['chat-open-blank']).then(() => {
if (settings['chat-auto-display']) { if (settings['chat-auto-display']) {
openChat() openChat()
} else { } else if (container) {
container.setAttribute('peertube-plugin-livechat-state', 'closed') container.setAttribute('peertube-plugin-livechat-state', 'closed')
} }
}) })
@ -238,7 +248,7 @@ function register ({ registerHook, peertubeHelpers }) {
registerHook({ registerHook({
target: 'filter:api.video-watch.video.get.result', target: 'filter:api.video-watch.video.get.result',
handler: (video) => { handler: (video: Video) => {
// For now, hooks for action:video-watch... did not receive the video object // For now, hooks for action:video-watch... did not receive the video object
// So we store video objects in videoCache // So we store video objects in videoCache
videoCache[video.uuid] = video videoCache[video.uuid] = video

23
conversejs/.eslintrc.json Normal file
View File

@ -0,0 +1,23 @@
{
"root": true,
"env": {
"browser": true,
"es6": true
},
"extends": [
"standard"
],
"globals": {},
"plugins": [],
"ignorePatterns": [],
"rules": {
"max-len": [
"error",
{
"code": 120,
"comments": 120
}
],
"no-unused-vars": [2, {"argsIgnorePattern": "^_"}]
}
}

662
package-lock.json generated
View File

@ -83,6 +83,32 @@
} }
} }
}, },
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
"integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
"integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
"dev": true
},
"@nodelib/fs.walk": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
"integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
"dev": true,
"requires": {
"@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0"
}
},
"@purtuga/esm-webpack-plugin": { "@purtuga/esm-webpack-plugin": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/@purtuga/esm-webpack-plugin/-/esm-webpack-plugin-1.1.1.tgz", "resolved": "https://registry.npmjs.org/@purtuga/esm-webpack-plugin/-/esm-webpack-plugin-1.1.1.tgz",
@ -98,12 +124,311 @@
"integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==",
"dev": true "dev": true
}, },
"@tsconfig/node12": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.7.tgz",
"integrity": "sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A==",
"dev": true
},
"@types/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/connect": {
"version": "3.4.34",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
"integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/express": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz",
"integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==",
"dev": true,
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz",
"integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"@types/json-schema": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
"dev": true
},
"@types/json5": { "@types/json5": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true "dev": true
}, },
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true
},
"@types/node": {
"version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
"dev": true
},
"@types/qs": {
"version": "6.9.6",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
"integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==",
"dev": true
},
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
"dev": true
},
"@types/serve-static": {
"version": "1.13.9",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
"integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
"dev": true,
"requires": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"@typescript-eslint/eslint-plugin": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.21.0.tgz",
"integrity": "sha512-FPUyCPKZbVGexmbCFI3EQHzCZdy2/5f+jv6k2EDljGdXSRc0cKvbndd2nHZkSLqCNOPk0jB6lGzwIkglXcYVsQ==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "4.21.0",
"@typescript-eslint/scope-manager": "4.21.0",
"debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1",
"lodash": "^4.17.15",
"regexpp": "^3.0.0",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"@typescript-eslint/experimental-utils": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.21.0.tgz",
"integrity": "sha512-cEbgosW/tUFvKmkg3cU7LBoZhvUs+ZPVM9alb25XvR0dal4qHL3SiUqHNrzoWSxaXA9gsifrYrS1xdDV6w/gIA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/scope-manager": "4.21.0",
"@typescript-eslint/types": "4.21.0",
"@typescript-eslint/typescript-estree": "4.21.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
},
"dependencies": {
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
}
},
"esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"requires": {
"estraverse": "^5.2.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
}
}
},
"@typescript-eslint/parser": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.21.0.tgz",
"integrity": "sha512-eyNf7QmE5O/l1smaQgN0Lj2M/1jOuNg2NrBm1dqqQN0sVngTLyw8tdCbih96ixlhbF1oINoN8fDCyEH9SjLeIA==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "4.21.0",
"@typescript-eslint/types": "4.21.0",
"@typescript-eslint/typescript-estree": "4.21.0",
"debug": "^4.1.1"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"@typescript-eslint/scope-manager": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.21.0.tgz",
"integrity": "sha512-kfOjF0w1Ix7+a5T1knOw00f7uAP9Gx44+OEsNQi0PvvTPLYeXJlsCJ4tYnDj5PQEYfpcgOH5yBlw7K+UEI9Agw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.21.0",
"@typescript-eslint/visitor-keys": "4.21.0"
}
},
"@typescript-eslint/types": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.21.0.tgz",
"integrity": "sha512-+OQaupjGVVc8iXbt6M1oZMwyKQNehAfLYJJ3SdvnofK2qcjfor9pEM62rVjBknhowTkh+2HF+/KdRAc/wGBN2w==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.21.0.tgz",
"integrity": "sha512-ZD3M7yLaVGVYLw4nkkoGKumb7Rog7QID9YOWobFDMQKNl+vPxqVIW/uDk+MDeGc+OHcoG2nJ2HphwiPNajKw3w==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.21.0",
"@typescript-eslint/visitor-keys": "4.21.0",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"@typescript-eslint/visitor-keys": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.21.0.tgz",
"integrity": "sha512-dH22dROWGi5Z6p+Igc8bLVLmwy7vEe8r+8c+raPQU0LxgogPUrRAtRGtvBWmlr9waTu3n+QLt/qrS/hWzk1x5w==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.21.0",
"eslint-visitor-keys": "^2.0.0"
}
},
"@webassemblyjs/ast": { "@webassemblyjs/ast": {
"version": "1.8.5", "version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@ -406,6 +731,12 @@
"is-string": "^1.0.5" "is-string": "^1.0.5"
} }
}, },
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true
},
"array-unique": { "array-unique": {
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@ -1256,6 +1587,23 @@
"randombytes": "^2.0.0" "randombytes": "^2.0.0"
} }
}, },
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
"requires": {
"path-type": "^4.0.0"
},
"dependencies": {
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
}
}
},
"doctrine": { "doctrine": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@ -1683,6 +2031,16 @@
"integrity": "sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==", "integrity": "sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==",
"dev": true "dev": true
}, },
"eslint-config-standard-with-typescript": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-20.0.0.tgz",
"integrity": "sha512-IoySf3r0a2+P3Z6GMjv8p1HuOQ6GWQbMpdt9G8uEbkGpnNWAGBXpgaiutbZHbaQAvG5pkVtYepCfHUxYbVDLCA==",
"dev": true,
"requires": {
"@typescript-eslint/parser": "^4.0.0",
"eslint-config-standard": "^16.0.0"
}
},
"eslint-import-resolver-node": { "eslint-import-resolver-node": {
"version": "0.3.4", "version": "0.3.4",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
@ -1834,6 +2192,12 @@
"integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==",
"dev": true "dev": true
}, },
"eslint-plugin-standard": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz",
"integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==",
"dev": true
},
"eslint-scope": { "eslint-scope": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
@ -2103,6 +2467,65 @@
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true "dev": true
}, },
"fast-glob": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
"integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.0",
"merge2": "^1.3.0",
"micromatch": "^4.0.2",
"picomatch": "^2.2.1"
},
"dependencies": {
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"dev": true,
"requires": {
"braces": "^3.0.1",
"picomatch": "^2.0.5"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
}
}
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@ -2115,6 +2538,15 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true "dev": true
}, },
"fastq": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
"integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
"dev": true,
"requires": {
"reusify": "^1.0.4"
}
},
"figgy-pudding": { "figgy-pudding": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@ -2383,6 +2815,28 @@
"type-fest": "^0.8.1" "type-fest": "^0.8.1"
} }
}, },
"globby": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz",
"integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==",
"dev": true,
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
},
"dependencies": {
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
"dev": true
}
}
},
"graceful-fs": { "graceful-fs": {
"version": "4.2.3", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
@ -3025,6 +3479,12 @@
"integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
"dev": true "dev": true
}, },
"merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true
},
"micromatch": { "micromatch": {
"version": "3.1.10", "version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@ -3642,8 +4102,7 @@
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true, "dev": true
"optional": true
}, },
"pidtree": { "pidtree": {
"version": "0.3.1", "version": "0.3.1",
@ -3773,6 +4232,12 @@
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
"dev": true "dev": true
}, },
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -3996,6 +4461,12 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"dev": true "dev": true
}, },
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
"rimraf": { "rimraf": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@ -4015,6 +4486,15 @@
"inherits": "^2.0.1" "inherits": "^2.0.1"
} }
}, },
"run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"requires": {
"queue-microtask": "^1.2.2"
}
},
"run-queue": { "run-queue": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
@ -4137,6 +4617,12 @@
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"dev": true "dev": true
}, },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
"slice-ansi": { "slice-ansi": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
@ -4798,6 +5284,163 @@
"repeat-string": "^1.6.1" "repeat-string": "^1.6.1"
} }
}, },
"ts-loader": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz",
"integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==",
"dev": true,
"requires": {
"chalk": "^4.1.0",
"enhanced-resolve": "^4.0.0",
"loader-utils": "^2.0.0",
"micromatch": "^4.0.0",
"semver": "^7.3.4"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"dev": true,
"requires": {
"braces": "^3.0.1",
"picomatch": "^2.0.5"
}
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"tsconfig-paths": { "tsconfig-paths": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
@ -4816,6 +5459,15 @@
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
"dev": true "dev": true
}, },
"tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"tty-browserify": { "tty-browserify": {
"version": "0.0.0", "version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@ -4843,6 +5495,12 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true "dev": true
}, },
"typescript": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
"integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
"dev": true
},
"union-value": { "union-value": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",

View File

@ -6,13 +6,13 @@
"bugs": "https://github.com/JohnXLivingston/peertube-plugin-livechat/issues", "bugs": "https://github.com/JohnXLivingston/peertube-plugin-livechat/issues",
"clientScripts": [ "clientScripts": [
{ {
"script": "dist/videowatch-client-plugin.js", "script": "dist/client/videowatch-client-plugin.js",
"scopes": [ "scopes": [
"video-watch" "video-watch"
] ]
}, },
{ {
"script": "dist/common-client-plugin.js", "script": "dist/client/common-client-plugin.js",
"scopes": [ "scopes": [
"common" "common"
] ]
@ -24,14 +24,23 @@
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"@purtuga/esm-webpack-plugin": "^1.1.1", "@purtuga/esm-webpack-plugin": "^1.1.1",
"@tsconfig/node12": "^1.0.7",
"@types/express": "^4.17.11",
"@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "^4.21.0",
"@typescript-eslint/parser": "^4.21.0",
"converse.js": "^7.0.5", "converse.js": "^7.0.5",
"eslint": "^7.20.0", "eslint": "^7.20.0",
"eslint-config-standard": "^16.0.2", "eslint-config-standard": "^16.0.2",
"eslint-config-standard-with-typescript": "^20.0.0",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1", "eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^5.0.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"svgo": "^2.2.1", "svgo": "^2.2.1",
"ts-loader": "^8.1.0",
"typescript": "^4.2.3",
"webpack": "^4.41.2", "webpack": "^4.41.2",
"webpack-cli": "^3.3.10" "webpack-cli": "^3.3.10"
}, },
@ -43,20 +52,22 @@
"peertube", "peertube",
"plugin" "plugin"
], ],
"library": "./main.js", "library": "./dist/server/main.js",
"scripts": { "scripts": {
"clean": "rm -rf dist/*", "clean": "rm -rf dist/*",
"prepare": "npm run build", "prepare": "npm run build",
"build:converse": "mkdir -p dist/conversejs && cp -r node_modules/converse.js/dist/* dist/conversejs/", "build:converse": "mkdir -p dist/client/conversejs && cp -r node_modules/converse.js/dist/* dist/client/conversejs/",
"build:images": "mkdir -p dist/images && npx svgo -f public/images/ -o dist/images/", "build:images": "mkdir -p dist/client/images && npx svgo -f public/images/ -o dist/client/images/",
"build:webpack": "webpack --mode=production", "build:webpack": "webpack --mode=production",
"build": "npm-run-all -s clean -p build:converse build:images build:webpack", "build:server": "npx tsc --build server/tsconfig.json",
"lint": "npx eslint --ext .js ." "build:serverconverse": "mkdir -p dist/server/conversejs && cp conversejs/index.html dist/server/conversejs/",
"build": "npm-run-all -s clean -p build:converse build:images build:webpack build:server build:serverconverse",
"lint": "npx eslint --ext .js --ext .ts ."
}, },
"staticDirs": { "staticDirs": {
"static": "dist/static", "static": "dist/client/static",
"conversejs": "dist/conversejs/", "conversejs": "dist/client/conversejs/",
"images": "dist/images/" "images": "dist/client/images/"
}, },
"translations": { "translations": {
"fr-FR": "./languages/fr.json" "fr-FR": "./languages/fr.json"

40
server/.eslintrc.json Normal file
View File

@ -0,0 +1,40 @@
{
"root": true,
"env": {
"browser": false,
"es6": true
},
"extends": [
"standard-with-typescript"
],
"globals": {},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"project": [
"./server/tsconfig.json"
]
},
"plugins": [
"@typescript-eslint"
],
"ignorePatterns": [],
"rules": {
"@typescript-eslint/no-unused-vars": [2, {"argsIgnorePattern": "^_"}],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/return-await": [2, "in-try-catch"], // FIXME: correct?
"@typescript-eslint/no-invalid-void-type": "off",
"@typescript-eslint/triple-slash-reference": "off",
"max-len": [
"error",
{
"code": 120,
"comments": 120
}
],
"no-unused-vars": "off"
}
}

View File

@ -1,17 +1,26 @@
import type { NextFunction, Request, Response } from 'express'
const path = require('path') const path = require('path')
const fs = require('fs').promises const fs = require('fs').promises
interface RegisterServerOptions {
registerHook: any
registerSetting: any
settingsManager: any
storageManager: any
videoCategoryManager: any
videoLicenceManager: any
videoLanguageManager: any
getRouter: any
peertubeHelpers: any
}
async function register ({ async function register ({
_registerHook,
registerSetting, registerSetting,
settingsManager, settingsManager,
_storageManager,
_videoCategoryManager,
_videoLicenceManager,
_videoLanguageManager,
getRouter, getRouter,
peertubeHelpers peertubeHelpers
}) { }: RegisterServerOptions): Promise<any> {
registerSetting({ registerSetting({
name: 'chat-auto-display', name: 'chat-auto-display',
label: 'Automatically open the chat', label: 'Automatically open the chat',
@ -142,8 +151,8 @@ async function register ({
const converseJSIndex = await fs.readFile(path.resolve(__dirname, './conversejs/index.html')) const converseJSIndex = await fs.readFile(path.resolve(__dirname, './conversejs/index.html'))
const router = getRouter() const router = getRouter()
router.get('/ping', (req, res) => res.json({ message: 'pong' })) router.get('/ping', (req: Request, res: Response) => res.json({ message: 'pong' }))
router.get('/webchat', async (req, res, next) => { router.get('/webchat', async (req: Request, res: Response, next: NextFunction) => {
try { try {
const settings = await settingsManager.getSettings([ const settings = await settingsManager.getSettings([
'chat-use-builtin', 'chat-room', 'chat-server', 'chat-use-builtin', 'chat-room', 'chat-server',
@ -168,7 +177,7 @@ async function register ({
// be /webchat/:videoId // be /webchat/:videoId
// const id = req.param('videoId') // const id = req.param('videoId')
// const video = await peertubeHelpers.videos.loadByIdOrUUID(id) // const video = await peertubeHelpers.videos.loadByIdOrUUID(id)
let url = req.query.url let url: string = req.query.url as string || ''
if (!url) { if (!url) {
throw new Error('Missing url parameter)') throw new Error('Missing url parameter)')
} }
@ -183,7 +192,7 @@ async function register ({
throw new Error('Video not found') throw new Error('Video not found')
} }
let page = '' + converseJSIndex let page = '' + (converseJSIndex as string)
// FIXME: Peertube should provide the static folder path. For now: // FIXME: Peertube should provide the static folder path. For now:
const staticRelative = '../static' const staticRelative = '../static'
page = page.replace(/{{BASE_STATIC_URL}}/g, staticRelative) page = page.replace(/{{BASE_STATIC_URL}}/g, staticRelative)
@ -202,7 +211,7 @@ async function register ({
}) })
} }
async function unregister () { async function unregister (): Promise<any> {
} }
module.exports = { module.exports = {

22
server/tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"extends": "@tsconfig/node12/tsconfig.json",
"compilerOptions": {
"moduleResolution": "node", // Tell tsc to look in node_modules for modules
"strict": true, // That implies alwaysStrict, noImplicitAny, noImplicitThis
"alwaysStrict": true, // should already be true because of strict:true
"noImplicitAny": true, // should already be true because of strict:true
"noImplicitThis": true, // should already be true because of strict:true
"noImplicitReturns": true,
"strictBindCallApply": true, // should already be true because of strict:true
"noUnusedLocals": true,
"removeComments": true,
"sourceMap": true,
"outDir": "../dist/server",
"paths": {},
},
"include": ["./**/*"],
"exclude": []
}

View File

@ -3,15 +3,23 @@ const path = require("path")
const EsmWebpackPlugin = require("@purtuga/esm-webpack-plugin") const EsmWebpackPlugin = require("@purtuga/esm-webpack-plugin")
const clientFiles = [ const clientFiles = [
'common-client-plugin.js', 'common-client-plugin',
'videowatch-client-plugin.js' 'videowatch-client-plugin'
] ]
let config = clientFiles.map(f => ({ let config = clientFiles.map(f => ({
entry: "./client/" + f, entry: "./client/" + f + ".ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader'
}
]
},
output: { output: {
path: path.resolve(__dirname, "./dist"), path: path.resolve(__dirname, "./dist/client"),
filename: "./" + f, filename: "./" + f + ".js",
library: "script", library: "script",
libraryTarget: "var" libraryTarget: "var"
}, },
@ -21,7 +29,7 @@ let config = clientFiles.map(f => ({
config.push({ config.push({
entry: "./conversejs/builtin.js", entry: "./conversejs/builtin.js",
output: { output: {
path: path.resolve(__dirname, "./dist/static"), path: path.resolve(__dirname, "./dist/client/static"),
filename: "./builtin.js" filename: "./builtin.js"
} }
}) })