mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
* [monorepo] lint .mts/.cts files
ESLint's `files` globs listed `{js,jsx,mjs,cjs,ts,tsx}` but never the
module-scoped TypeScript extensions, so every `.mts` file in the repo was
silently skipped with "File ignored because no matching configuration was
supplied" -- 21 files today, all in services/web, and more as backend code
migrates to TypeScript (`.mts` is the extension runtime-loaded backend TS
has to use, since services/web has no `"type": "module"`).
Each extension list now carries the c/m variants of the languages it
already allowed, canonicalised to one of:
{js,cjs,mjs} JS only
{js,cjs,mjs,jsx} JS + JSX
{js,cjs,mjs,ts,cts,mts} JS + TS, no JSX
{ts,cts,mts,tsx} TS only
{js,cjs,mjs,jsx,ts,cts,mts,tsx} everything
No list gains a language it did not already have, and none gains JSX
where it was previously excluded, so backend globs keep excluding
jsx/tsx and TS-only rule blocks keep excluding JS.
Both the extension declaration and the plugin/parser block in
services/web/eslint.config.mjs are widened together: widening only the
rule blocks makes `@overleaf/*` rules match files the plugin
registration does not, which fails with "could not find plugin
@overleaf".
The root global-ignores shim (`services/**/*.{mjs,cjs,ts,tsx}` and
friends) is deliberately left alone -- it replicates ESLint v8's file
walker so pre-existing debt in never-linted files stays off the build.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Fix eslint errors
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
GitOrigin-RevId: 084d0d054db9db6b5e3dd26de56d14358ab5edf7
200 lines
7.5 KiB
JavaScript
200 lines
7.5 KiB
JavaScript
/* eslint-disable no-console */
|
|
|
|
import fs from 'node:fs/promises'
|
|
import { createWriteStream } from 'node:fs'
|
|
import { basename, join } from 'node:path'
|
|
import { tmpdir } from 'node:os'
|
|
import { execSync } from 'node:child_process'
|
|
import yauzl from 'yauzl'
|
|
|
|
// brew install woff2
|
|
|
|
const families = [
|
|
{
|
|
folder: 'dm-mono',
|
|
url: 'https://github.com/googlefonts/dm-mono',
|
|
fonts: [
|
|
'https://github.com/googlefonts/dm-mono/raw/refs/heads/main/exports/DMMono-Italic.ttf',
|
|
'https://github.com/googlefonts/dm-mono/raw/refs/heads/main/exports/DMMono-Medium.ttf',
|
|
'https://github.com/googlefonts/dm-mono/raw/refs/heads/main/exports/DMMono-MediumItalic.ttf',
|
|
'https://github.com/googlefonts/dm-mono/raw/refs/heads/main/exports/DMMono-Regular.ttf',
|
|
],
|
|
},
|
|
{
|
|
folder: 'inter',
|
|
url: 'https://github.com/rsms/inter/releases/tag/v4.1',
|
|
archive:
|
|
'https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip',
|
|
fonts: ['web/Inter-Regular.woff2', 'web/Inter-SemiBold.woff2'],
|
|
license:
|
|
'https://raw.githubusercontent.com/rsms/inter/refs/heads/master/LICENSE.txt',
|
|
},
|
|
{
|
|
folder: 'lato',
|
|
url: 'https://www.latofonts.com/',
|
|
archive: 'https://www.latofonts.com/files/Lato2OFLWeb.zip',
|
|
fonts: [
|
|
'Lato2OFLWeb/LatoLatin/fonts/LatoLatin-Bold.woff2',
|
|
'Lato2OFLWeb/LatoLatin/fonts/LatoLatin-BoldItalic.woff2',
|
|
'Lato2OFLWeb/LatoLatin/fonts/LatoLatin-Italic.woff2',
|
|
'Lato2OFLWeb/LatoLatin/fonts/LatoLatin-Regular.woff2',
|
|
],
|
|
},
|
|
{
|
|
folder: 'merriweather',
|
|
url: 'https://github.com/SorkinType/Merriweather',
|
|
fonts: [
|
|
'https://github.com/SorkinType/Merriweather/raw/refs/heads/master/fonts/webfonts/Merriweather-Bold.woff2',
|
|
'https://github.com/SorkinType/Merriweather/raw/refs/heads/master/fonts/webfonts/Merriweather-BoldItalic.woff2',
|
|
'https://github.com/SorkinType/Merriweather/raw/refs/heads/master/fonts/webfonts/Merriweather-Italic.woff2',
|
|
'https://github.com/SorkinType/Merriweather/raw/refs/heads/master/fonts/webfonts/Merriweather-Regular.woff2',
|
|
],
|
|
license:
|
|
'https://github.com/SorkinType/Merriweather/raw/refs/heads/master/OFL.txt',
|
|
},
|
|
{
|
|
folder: 'noto-sans',
|
|
url: 'https://notofonts.github.io/#latin-greek-cyrillic',
|
|
fonts: [
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-Italic.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-Medium.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-MediumItalic.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-Regular.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-SemiBold.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSans/full/ttf/NotoSans-SemiBoldItalic.ttf',
|
|
],
|
|
license:
|
|
'https://raw.githubusercontent.com/notofonts/latin-greek-cyrillic/refs/heads/main/OFL.txt',
|
|
},
|
|
{
|
|
folder: 'noto-serif',
|
|
url: 'https://notofonts.github.io/#latin-greek-cyrillic',
|
|
fonts: [
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSerif/unhinted/slim-variable-ttf/NotoSerif%5Bwght%5D.ttf',
|
|
'https://github.com/notofonts/notofonts.github.io/raw/refs/heads/main/fonts/NotoSerif/unhinted/slim-variable-ttf/NotoSerif-Italic%5Bwght%5D.ttf',
|
|
],
|
|
license:
|
|
'https://raw.githubusercontent.com/notofonts/latin-greek-cyrillic/refs/heads/main/OFL.txt',
|
|
},
|
|
{
|
|
folder: 'open-dyslexic-mono',
|
|
url: 'https://github.com/antijingoist/opendyslexic',
|
|
fonts: [
|
|
'https://github.com/antijingoist/open-dyslexic/blob/master/otf/OpenDyslexicMono-Regular.otf',
|
|
],
|
|
license: 'https://github.com/antijingoist/opendyslexic/blob/master/OFL.txt',
|
|
},
|
|
{
|
|
folder: 'open-sans',
|
|
url: 'https://github.com/googlefonts/opensans',
|
|
fonts: [
|
|
'https://github.com/googlefonts/opensans/raw/refs/heads/main/fonts/ttf/OpenSans-Bold.ttf',
|
|
'https://github.com/googlefonts/opensans/raw/refs/heads/main/fonts/ttf/OpenSans-Light.ttf',
|
|
'https://github.com/googlefonts/opensans/raw/refs/heads/main/fonts/ttf/OpenSans-Regular.ttf',
|
|
'https://github.com/googlefonts/opensans/raw/refs/heads/main/fonts/ttf/OpenSans-SemiBold.ttf',
|
|
],
|
|
license:
|
|
'https://raw.githubusercontent.com/googlefonts/opensans/refs/heads/main/OFL.txt',
|
|
},
|
|
{
|
|
folder: 'source-code-pro',
|
|
url: 'https://github.com/adobe-fonts/source-code-pro',
|
|
fonts: [
|
|
'https://github.com/adobe-fonts/source-code-pro/raw/refs/heads/release/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2',
|
|
],
|
|
license:
|
|
'https://raw.githubusercontent.com/adobe-fonts/source-code-pro/refs/heads/release/LICENSE.md',
|
|
},
|
|
{
|
|
folder: 'STIXTwoMath',
|
|
url: 'https://github.com/stipub/stixfonts',
|
|
fonts: [
|
|
'https://github.com/stipub/stixfonts/raw/refs/heads/master/fonts/static_otf_woff2/STIXTwoMath-Regular.woff2',
|
|
],
|
|
license:
|
|
'https://raw.githubusercontent.com/stipub/stixfonts/refs/heads/master/OFL.txt',
|
|
},
|
|
]
|
|
|
|
const fetchFile = async (url, path) => {
|
|
console.log(`${url}\n${path}`)
|
|
const response = await fetch(url)
|
|
if (!response.ok) {
|
|
throw new Error(response.statusText)
|
|
}
|
|
await fs.writeFile(path, response.body)
|
|
}
|
|
|
|
for (const family of families) {
|
|
if (!family.folder) {
|
|
throw new Error('Missing family information')
|
|
}
|
|
|
|
await fs.mkdir(family.folder, { recursive: true })
|
|
|
|
const fonts = new Set(family.fonts)
|
|
|
|
if (family.archive) {
|
|
const dir = await fs.mkdtemp(join(tmpdir(), 'fonts-'))
|
|
const filename = decodeURIComponent(basename(family.archive))
|
|
const path = `${dir}/${filename}`
|
|
await fetchFile(family.archive, path)
|
|
|
|
await new Promise((resolve, reject) => {
|
|
yauzl.open(path, { lazyEntries: true }, (err, zipfile) => {
|
|
if (err) {
|
|
reject(err)
|
|
} else {
|
|
zipfile.on('entry', entry => {
|
|
if (fonts.has(entry.fileName)) {
|
|
console.log(entry.fileName)
|
|
zipfile.openReadStream(entry, (err, readStream) => {
|
|
if (err) {
|
|
reject(err)
|
|
} else {
|
|
const path = `${family.folder}/${basename(entry.fileName)}`
|
|
const output = createWriteStream(path)
|
|
readStream.on('end', async () => {
|
|
output.close()
|
|
if (path.endsWith('.ttf')) {
|
|
execSync(`woff2_compress "${path}"`)
|
|
await fs.unlink(path)
|
|
}
|
|
zipfile.readEntry()
|
|
})
|
|
readStream.pipe(output)
|
|
}
|
|
})
|
|
} else {
|
|
zipfile.readEntry()
|
|
}
|
|
})
|
|
zipfile.on('error', reject)
|
|
zipfile.on('end', resolve)
|
|
zipfile.readEntry()
|
|
}
|
|
})
|
|
})
|
|
|
|
await fs.unlink(path)
|
|
} else {
|
|
for (const url of fonts) {
|
|
const filename = decodeURIComponent(basename(url))
|
|
const path = `${family.folder}/${filename}`
|
|
await fetchFile(url, path)
|
|
|
|
if (path.endsWith('.ttf')) {
|
|
execSync(`woff2_compress "${path}"`)
|
|
await fs.unlink(path)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (family.license) {
|
|
const url = family.license
|
|
const filename = decodeURIComponent(basename(url))
|
|
const path = `${family.folder}/${filename}`
|
|
await fetchFile(url, path)
|
|
}
|
|
}
|