mirror of
https://github.com/samsonjs/mit-license.git
synced 2026-03-25 09:25:49 +00:00
Refactor
Signed-off-by: Richie Bendall <richiebendall@gmail.com>
This commit is contained in:
parent
325cd76ca4
commit
bd71a57b7a
10 changed files with 223 additions and 178 deletions
|
|
@ -11,10 +11,10 @@ const getUrlParts = url => {
|
|||
return url.slice(1).split('/')
|
||||
}
|
||||
|
||||
module.exports = (request, response, next) => {
|
||||
const urlParts = getUrlParts(request.url)
|
||||
const loadOptions = url => {
|
||||
const urlParts = getUrlParts(url)
|
||||
|
||||
response.locals.options = {
|
||||
const options = {
|
||||
format: 'html',
|
||||
startYear: null,
|
||||
endYear: currentYear
|
||||
|
|
@ -23,21 +23,23 @@ module.exports = (request, response, next) => {
|
|||
for (const urlPart of urlParts) {
|
||||
if (yearRegex.test(urlPart)) {
|
||||
if (urlPart.startsWith('@')) {
|
||||
response.locals.options.pinnedYear = Number.parseInt(urlPart.slice(1))
|
||||
options.pinnedYear = Number.parseInt(urlPart.slice(1), 10)
|
||||
} else {
|
||||
response.locals.options.startYear = Number.parseInt(urlPart)
|
||||
options.startYear = Number.parseInt(urlPart, 10)
|
||||
}
|
||||
} else if (yearRangeRegex.test(urlPart)) {
|
||||
const [startYear, endYear] = urlPart.match(yearRangeRegex).slice(1)
|
||||
|
||||
response.locals.options.startYear = Number.parseInt(startYear)
|
||||
response.locals.options.endYear = Number.parseInt(endYear)
|
||||
options.startYear = Number.parseInt(startYear, 10)
|
||||
options.endYear = Number.parseInt(endYear, 10)
|
||||
} else if (urlPart.startsWith('license')) {
|
||||
response.locals.options.format = urlPart.split('.')[1].trim()
|
||||
options.format = urlPart.split('.')[1].trim()
|
||||
} else if (urlPart.startsWith('+')) {
|
||||
response.locals.options.license = urlPart.slice(1).toUpperCase()
|
||||
options.license = urlPart.slice(1).toUpperCase()
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
return options
|
||||
}
|
||||
|
||||
export default loadOptions
|
||||
26
lib/load-user.js
Normal file
26
lib/load-user.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import {fileURLToPath} from 'node:url'
|
||||
import path, {dirname} from 'node:path'
|
||||
import loadJsonFile from 'load-json-file'
|
||||
|
||||
const directoryName = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const loadUser = async hostname => {
|
||||
const [id] = hostname.split('.')
|
||||
|
||||
const user = {
|
||||
copyright: '<copyright holders>' // Fallback
|
||||
}
|
||||
|
||||
try {
|
||||
return {
|
||||
...user,
|
||||
...await loadJsonFile(path.join(directoryName, '..', 'users', `${id}.json`))
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default loadUser
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
const path = require('path')
|
||||
const loadJsonFile = require('load-json-file')
|
||||
|
||||
module.exports = async (request, response, next) => {
|
||||
const id = request.hostname.split('.')[0]
|
||||
|
||||
if (request.method.toUpperCase() !== 'GET') {
|
||||
return next()
|
||||
}
|
||||
|
||||
// Otherwise load up the user json file
|
||||
response.locals.user = {
|
||||
copyright: '<copyright holders>'
|
||||
}
|
||||
|
||||
try {
|
||||
response.locals.user = {
|
||||
...response.locals.user,
|
||||
...await loadJsonFile(path.join(__dirname, '..', 'users', `${id}.json`))
|
||||
}
|
||||
} catch ({ code, message }) {
|
||||
if (code !== 'ENOENT') {
|
||||
response
|
||||
.code(500)
|
||||
.send(
|
||||
`An internal error occurred - open an issue on https://github.com/remy/mit-license with the following information: ${message}`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
35
package.json
35
package.json
|
|
@ -2,6 +2,7 @@
|
|||
"name": "mit-licence",
|
||||
"description": "Hosted MIT License with details controlled through this repo",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "2.0.0",
|
||||
"main": "server.js",
|
||||
"repository": {
|
||||
|
|
@ -17,42 +18,45 @@
|
|||
"dev": "nodemon .",
|
||||
"serve": "node server.js",
|
||||
"test": "node test.js",
|
||||
"lint": "standard"
|
||||
"lint": "xo"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/remy/mit-license/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^18.0.6",
|
||||
"@sindresorhus/is": "^3.1.2",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@sindresorhus/is": "^4.0.1",
|
||||
"any-size": "^1.2.0",
|
||||
"btoa": "^1.2.1",
|
||||
"cors": "^2.8.5",
|
||||
"create-html-element": "^3.0.0",
|
||||
"ejs": "^3.1.5",
|
||||
"escape-goat": "^3.0.0",
|
||||
"ejs": "^3.1.6",
|
||||
"escape-goat": "^4.0.0",
|
||||
"express": "^4.17.1",
|
||||
"express-minify": "^1.0.0",
|
||||
"gravatar-url": "^3.1.0",
|
||||
"gravatar-url": "^4.0.0",
|
||||
"html-text": "^1.0.1",
|
||||
"load-json-file": "^6.2.0",
|
||||
"path-exists": "^4.0.0",
|
||||
"postcss-middleware": "^1.1.4",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"read-pkg": "^6.0.0",
|
||||
"serve-favicon": "^2.5.0",
|
||||
"temp-dir": "^2.0.0",
|
||||
"write-json-file": "^4.3.0",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.14.3",
|
||||
"@babel/plugin-syntax-top-level-await": "^7.12.13",
|
||||
"css": "^3.0.0",
|
||||
"file-ext": "^1.0.0",
|
||||
"has-flag": "^4.0.0",
|
||||
"has-flag": "^5.0.0",
|
||||
"husky": "^4.3.0",
|
||||
"nodemon": "^2.0.4",
|
||||
"nodemon": "^2.0.7",
|
||||
"path-extra": "^4.3.0",
|
||||
"standard": "^14.3.4"
|
||||
"xo": "^0.40.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"postcss-middleware/vinyl-fs/glob-stream/micromatch/braces": "^3.0.2"
|
||||
|
|
@ -62,5 +66,18 @@
|
|||
"pre-commit": "npm run lint",
|
||||
"pre-push": "npm test"
|
||||
}
|
||||
},
|
||||
"xo": {
|
||||
"space": 2,
|
||||
"semicolon": false,
|
||||
"parser": "@babel/eslint-parser",
|
||||
"parserOptions": {
|
||||
"requireConfigFile": false,
|
||||
"babelOptions": {
|
||||
"plugins": [
|
||||
"@babel/plugin-syntax-top-level-await"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
const path = require('path')
|
||||
const { htmlEscape, htmlUnescape } = require('escape-goat')
|
||||
const stripHtml = require('html-text')
|
||||
const is = require('@sindresorhus/is')
|
||||
const getGravatarUrl = require('gravatar-url')
|
||||
const createHtmlElement = require('create-html-element')
|
||||
const { renderFile } = require('ejs')
|
||||
import {fileURLToPath} from 'node:url'
|
||||
import path, {dirname} from 'node:path'
|
||||
import {htmlEscape, htmlUnescape} from 'escape-goat'
|
||||
import stripHtml from 'html-text'
|
||||
import is from '@sindresorhus/is'
|
||||
import getGravatarUrl from 'gravatar-url'
|
||||
import createHtmlElement from 'create-html-element'
|
||||
import {renderFile} from 'ejs'
|
||||
|
||||
import loadUser from '../lib/load-user.js'
|
||||
import loadOptions from '../lib/load-options.js'
|
||||
|
||||
const directoryName = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const getCopyrightName = (user, isPlainText) => {
|
||||
if (is.string(user)) {
|
||||
|
|
@ -53,9 +59,24 @@ const getGravatarEmail = user => {
|
|||
|
||||
const removeFalsy = array => array.filter(Boolean)
|
||||
|
||||
module.exports = async (_, response) => {
|
||||
const { user, options } = response.locals
|
||||
const isPlainText = options.format !== 'html'
|
||||
const getRoute = async (request, response) => {
|
||||
let user
|
||||
try {
|
||||
user = await loadUser(request.hostname)
|
||||
} catch ({message}) {
|
||||
response
|
||||
.status(500)
|
||||
.send(`An internal error occurred - open an issue on https://github.com/remy/mit-license with the following information: ${message}`)
|
||||
return
|
||||
}
|
||||
|
||||
const options = loadOptions(request.url)
|
||||
const year = options.pinnedYear ?
|
||||
options.pinnedYear :
|
||||
removeFalsy([options.startYear, options.endYear]).join('-')
|
||||
const license = (options.license || user.license || 'MIT').toUpperCase()
|
||||
const format = options.format || user.format || 'html'
|
||||
const isPlainText = format !== 'html'
|
||||
|
||||
let name
|
||||
|
||||
|
|
@ -85,21 +106,15 @@ module.exports = async (_, response) => {
|
|||
})
|
||||
}
|
||||
|
||||
const year = options.pinnedYear
|
||||
? options.pinnedYear
|
||||
: removeFalsy([options.startYear, options.endYear]).join('-')
|
||||
const license = (options.license || user.license || 'MIT').toUpperCase()
|
||||
const format = options.format || user.format || 'html'
|
||||
|
||||
try {
|
||||
const content = await renderFile(path.join(__dirname, '..', 'licenses', `${license}.ejs`), {
|
||||
const content = await renderFile(path.join(directoryName, '..', 'licenses', `${license}.ejs`), {
|
||||
info: `${year} ${name}`,
|
||||
theme: user.theme || 'default',
|
||||
gravatar
|
||||
})
|
||||
|
||||
if (format === 'txt') {
|
||||
const { articleContent } = content.match(/<article>(?<articleContent>.*)<\/article>/ms).groups
|
||||
const {articleContent} = content.match(/<article>(?<articleContent>.*)<\/article>/ms).groups
|
||||
|
||||
response
|
||||
.set('Content-Type', 'text/plain; charset=UTF-8')
|
||||
|
|
@ -111,8 +126,11 @@ module.exports = async (_, response) => {
|
|||
response.send(content)
|
||||
return
|
||||
}
|
||||
response.json({ ...user, ...options })
|
||||
|
||||
response.json({...user, ...options})
|
||||
} catch (error) {
|
||||
response.status(500).send(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default getRoute
|
||||
|
|
|
|||
|
|
@ -1,22 +1,29 @@
|
|||
const path = require('path')
|
||||
const btoa = require('btoa')
|
||||
const { version } = require(path.join(__dirname, '..', 'package.json'))
|
||||
const size = require('any-size')
|
||||
const { Octokit } = require('@octokit/rest')
|
||||
const pathExists = require('path-exists')
|
||||
const writeJsonFile = require('write-json-file')
|
||||
import path, {dirname} from 'node:path'
|
||||
import toBase64 from 'btoa'
|
||||
import {readPackageAsync as readPackage} from 'read-pkg'
|
||||
import size from 'any-size'
|
||||
import {Octokit} from '@octokit/rest'
|
||||
import pathExists from 'path-exists'
|
||||
import writeJsonFile from 'write-json-file'
|
||||
import yn from 'yn'
|
||||
import is from '@sindresorhus/is'
|
||||
|
||||
import {fileURLToPath} from 'node:url'
|
||||
|
||||
import {isDomainId} from './utils.js'
|
||||
|
||||
const directoryName = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const {version} = await readPackage()
|
||||
|
||||
const github = new Octokit({
|
||||
// GitHub personal access token
|
||||
auth: process.env.github_token,
|
||||
// User agent with version from package.json
|
||||
userAgent: `mit-license v${version}`
|
||||
})
|
||||
const yn = require('yn')
|
||||
const is = require('@sindresorhus/is')
|
||||
|
||||
const { isDomainId } = require('./utils')
|
||||
|
||||
function getUserData ({ query, body }) {
|
||||
function getUserData({query, body}) {
|
||||
// If query parameters provided
|
||||
if (size(query) > 0) {
|
||||
return query
|
||||
|
|
@ -31,24 +38,23 @@ function getUserData ({ query, body }) {
|
|||
return body
|
||||
}
|
||||
|
||||
// HTTP POST API
|
||||
module.exports = async (request, response) => {
|
||||
const { hostname } = request
|
||||
const postRoute = async (request, response) => {
|
||||
const {hostname} = request
|
||||
|
||||
// Get different parts of hostname (example: remy.mit-license.org -> ['remy', 'mit-license', 'org'])
|
||||
const params = hostname.split('.')
|
||||
const parameters = hostname.split('.')
|
||||
|
||||
// This includes the copyright, year, etc.
|
||||
const userData = getUserData(request)
|
||||
|
||||
// If there isn't enough part of the hostname
|
||||
if (params.length < 2) {
|
||||
if (parameters.length < 2) {
|
||||
response.status(400).send('Please specify a subdomain in the URL.')
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the name from the URL
|
||||
const [id] = params
|
||||
const [id] = parameters
|
||||
|
||||
if (!isDomainId(id)) {
|
||||
// Return a vague error intentionally
|
||||
|
|
@ -62,7 +68,7 @@ module.exports = async (request, response) => {
|
|||
}
|
||||
|
||||
// Check if the user file exists in the users directory
|
||||
if (await pathExists(path.join(__dirname, '..', 'users', `${id}.json`))) {
|
||||
if (await pathExists(path.join(directoryName, '..', 'users', `${id}.json`))) {
|
||||
response
|
||||
.status(409)
|
||||
.send(
|
||||
|
|
@ -73,7 +79,7 @@ module.exports = async (request, response) => {
|
|||
|
||||
if (userData.gravatar) {
|
||||
// Parse the string version of a boolean or similar
|
||||
userData.gravatar = yn(userData.gravatar, { lenient: true })
|
||||
userData.gravatar = yn(userData.gravatar, {lenient: true})
|
||||
if (is.undefined(userData.gravatar)) {
|
||||
response
|
||||
.status(400)
|
||||
|
|
@ -98,13 +104,13 @@ module.exports = async (request, response) => {
|
|||
repo: 'mit-license',
|
||||
path: `users/${id}.json`,
|
||||
message: `Automated creation of user ${id}.`,
|
||||
content: btoa(JSON.stringify(userData, 0, 2)),
|
||||
content: toBase64(JSON.stringify(userData, 0, 2)),
|
||||
committer: {
|
||||
name: 'MIT License Bot',
|
||||
email: 'remy@leftlogic.com'
|
||||
}
|
||||
}),
|
||||
writeJsonFile(path.join(__dirname, '..', 'users', `${id}.json`), userData, { indent: undefined })
|
||||
writeJsonFile(path.join(directoryName, '..', 'users', `${id}.json`), userData, {indent: undefined})
|
||||
])
|
||||
|
||||
response.status(201).send(`MIT license page created: https://${hostname}`)
|
||||
|
|
@ -116,3 +122,6 @@ module.exports = async (request, response) => {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP POST API
|
||||
export default postRoute
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
exports.isDomainId = value => /^[\w-_]+$/.test(value)
|
||||
export const isDomainId = value => /^[\w-_]+$/.test(value)
|
||||
|
|
|
|||
43
server.js
43
server.js
|
|
@ -5,16 +5,25 @@ IMPORTANT: Set the `github_token` environment variable to a personal access to
|
|||
Server port: The `PORT` environment variable can also be set to control the port the server
|
||||
should be hosted on.
|
||||
*/
|
||||
const express = require('express')
|
||||
const minify = require('express-minify')
|
||||
const favicon = require('serve-favicon')
|
||||
const postcssMiddleware = require('postcss-middleware')
|
||||
const tempDirectory = require('temp-dir')
|
||||
const path = require('path')
|
||||
import path, {dirname} from 'node:path'
|
||||
import express from 'express'
|
||||
import minify from 'express-minify'
|
||||
import favicon from 'serve-favicon'
|
||||
import postcssMiddleware from 'postcss-middleware'
|
||||
import tempDirectory from 'temp-dir'
|
||||
import postcssPresetEnv from 'postcss-preset-env'
|
||||
import cors from 'cors'
|
||||
|
||||
import {fileURLToPath} from 'node:url'
|
||||
|
||||
import postRoute from './routes/post.js'
|
||||
import getRoute from './routes/get.js'
|
||||
|
||||
// Server
|
||||
const PORT = process.env.PORT || 8080
|
||||
|
||||
const directoryName = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
// Prepare application
|
||||
const app = express()
|
||||
app.use(
|
||||
|
|
@ -22,22 +31,22 @@ app.use(
|
|||
cache: tempDirectory
|
||||
})
|
||||
)
|
||||
app.use(favicon(path.join(__dirname, 'favicon.ico')))
|
||||
app.set('views', path.join(__dirname, '/licenses'))
|
||||
app.use(favicon(path.join(directoryName, 'favicon.ico')))
|
||||
app.set('views', path.join(directoryName, '/licenses'))
|
||||
|
||||
// Setup static files
|
||||
app.use('/robots.txt', express.static('robots.txt'))
|
||||
app.use('/favicon.ico', express.static(`${__dirname}/favicon.ico`))
|
||||
app.use('/favicon.ico', express.static(`${directoryName}/favicon.ico`))
|
||||
app.use(
|
||||
'/themes',
|
||||
postcssMiddleware({
|
||||
plugins: [
|
||||
require('postcss-preset-env')({
|
||||
postcssPresetEnv({
|
||||
overrideBrowserslist: '>= 0%'
|
||||
})
|
||||
],
|
||||
src (request) {
|
||||
return path.join(__dirname, 'themes', request.path)
|
||||
src(request) {
|
||||
return path.join(directoryName, 'themes', request.path)
|
||||
}
|
||||
}),
|
||||
express.static('themes')
|
||||
|
|
@ -46,7 +55,7 @@ app.use(
|
|||
// Middleware
|
||||
|
||||
// CORS
|
||||
app.use(require('cors')())
|
||||
app.use(cors())
|
||||
// Parse URL-encoded bodies (as sent by HTML forms)
|
||||
app.use(
|
||||
express.urlencoded({
|
||||
|
|
@ -56,13 +65,9 @@ app.use(
|
|||
// Parse JSON bodies (as sent by API clients)
|
||||
app.use(express.json())
|
||||
|
||||
// Capture the id from the subdomain and options from parts of the url
|
||||
app.use(require('./middleware/load-user'))
|
||||
app.use(require('./middleware/load-options'))
|
||||
|
||||
// HTTP endpoints
|
||||
app.post('/', require('./routes/post'))
|
||||
app.get('/*', require('./routes/get'))
|
||||
app.post('/', postRoute)
|
||||
app.get('/*', getRoute)
|
||||
|
||||
// Start listening for HTTP requests
|
||||
app.listen(PORT, () => {
|
||||
|
|
|
|||
131
test.js
131
test.js
|
|
@ -1,78 +1,79 @@
|
|||
const { promises: fs } = require('fs')
|
||||
const writeJsonFile = require('write-json-file')
|
||||
const CSS = require('css')
|
||||
const { isDomainId } = require('./routes/utils')
|
||||
const hasFlag = require('has-flag')
|
||||
const getExtension = require('file-ext')
|
||||
const path = require('path-extra')
|
||||
const is = require('@sindresorhus/is')
|
||||
import {promises as fs} from 'node:fs'
|
||||
import writeJsonFile from 'write-json-file'
|
||||
import {parse as parseCSS} from 'css'
|
||||
import hasFlag from 'has-flag'
|
||||
import getExtension from 'file-ext'
|
||||
import path from 'path-extra'
|
||||
import is from '@sindresorhus/is'
|
||||
import {isDomainId} from './routes/utils.js'
|
||||
|
||||
async function report (content, fix) {
|
||||
async function report(content, fix) {
|
||||
console.error(content)
|
||||
if (fix && hasFlag('--fix')) await fix()
|
||||
if (fix && hasFlag('--fix')) {
|
||||
await fix()
|
||||
}
|
||||
|
||||
process.exitCode = 1
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const users = await fs.readdir('users')
|
||||
const users = await fs.readdir('users')
|
||||
|
||||
for (const user of users) {
|
||||
if (getExtension(user) !== 'json') {
|
||||
await report(`${user} is not a json file`, async () => {
|
||||
await fs.unlink(user)
|
||||
})
|
||||
}
|
||||
for await (const user of users) {
|
||||
if (getExtension(user) !== 'json') {
|
||||
await report(`${user} is not a json file`, async () => {
|
||||
await fs.unlink(user)
|
||||
})
|
||||
}
|
||||
|
||||
if (!isDomainId(path.base(user))) {
|
||||
await report(`${user} is not a valid domain id.`)
|
||||
}
|
||||
if (!isDomainId(path.base(user))) {
|
||||
await report(`${user} is not a valid domain id.`)
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await fs.readFile(path.join('users', user), 'utf8')
|
||||
|
||||
try {
|
||||
const data = await fs.readFile(path.join('users', user), 'utf8')
|
||||
const parsedData = JSON.parse(data)
|
||||
|
||||
try {
|
||||
const parsedData = JSON.parse(data)
|
||||
|
||||
if (!parsedData.locked && !parsedData.copyright) {
|
||||
report(`Copyright not specified in ${user}`)
|
||||
}
|
||||
|
||||
if (parsedData.version) {
|
||||
await report(`Version tag found in ${user}`, async () => {
|
||||
delete parsedData.version
|
||||
await writeJsonFile(path.join('users', user), parsedData, { indent: 2 })
|
||||
})
|
||||
}
|
||||
|
||||
if (is.string(parsedData.gravatar)) {
|
||||
await report(`Gravatar boolean encoded as string found in ${user}`, async () => {
|
||||
parsedData.gravatar = parsedData.gravatar === 'true'
|
||||
const stringified = `${JSON.stringify(parsedData, 0, 2)}\n`
|
||||
await fs.writeFile(path.join('users', user), stringified)
|
||||
})
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Invalid JSON in ${user} (${message})`)
|
||||
if (!parsedData.locked && !parsedData.copyright) {
|
||||
report(`Copyright not specified in ${user}`)
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Unable to read ${user} (${message})`)
|
||||
|
||||
if (parsedData.version) {
|
||||
await report(`Version tag found in ${user}`, async () => {
|
||||
delete parsedData.version
|
||||
await writeJsonFile(path.join('users', user), parsedData, {indent: 2})
|
||||
})
|
||||
}
|
||||
|
||||
if (is.string(parsedData.gravatar)) {
|
||||
await report(`Gravatar boolean encoded as string found in ${user}`, async () => {
|
||||
parsedData.gravatar = parsedData.gravatar === 'true'
|
||||
const stringified = `${JSON.stringify(parsedData, 0, 2)}\n`
|
||||
await fs.writeFile(path.join('users', user), stringified)
|
||||
})
|
||||
}
|
||||
} catch ({message}) {
|
||||
report(`Invalid JSON in ${user} (${message})`)
|
||||
}
|
||||
} catch ({message}) {
|
||||
report(`Unable to read ${user} (${message})`)
|
||||
}
|
||||
}
|
||||
|
||||
const themes = await fs.readdir('themes')
|
||||
|
||||
for await (const theme of themes) {
|
||||
if (getExtension(theme) === 'css') {
|
||||
try {
|
||||
const cssData = await fs.readFile(path.join('themes', theme), 'utf8')
|
||||
try {
|
||||
parseCSS(cssData)
|
||||
} catch ({message}) {
|
||||
report(`Invalid CSS in ${theme} (${message})`)
|
||||
}
|
||||
} catch ({message}) {
|
||||
report(`Unable to read ${theme} (${message})`)
|
||||
}
|
||||
}
|
||||
|
||||
const themes = await fs.readdir('themes')
|
||||
|
||||
for (const theme of themes) {
|
||||
if (getExtension(theme) === 'css') {
|
||||
try {
|
||||
const cssData = await fs.readFile(path.join('themes', theme), 'utf8')
|
||||
try {
|
||||
CSS.parse(cssData)
|
||||
} catch ({ message }) {
|
||||
report(`Invalid CSS in ${theme} (${message})`)
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Unable to read ${theme} (${message})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
|
|
|||
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue