mirror of
https://github.com/zen-browser/surfer.git
synced 2025-07-08 01:10:03 +02:00
🎨 New, overkill linter
This commit is contained in:
parent
7650c90c3a
commit
d84e0941b5
49 changed files with 670 additions and 470 deletions
11
.eslintrc.js
11
.eslintrc.js
|
@ -3,12 +3,17 @@ module.exports = {
|
|||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:unicorn/recommended'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint'],
|
||||
rules: {},
|
||||
plugins: ['@typescript-eslint', 'unicorn'],
|
||||
rules: {
|
||||
'unicorn/no-process-exit': 0,
|
||||
// We are currently using commonjs. If / when it becomes viable for us to
|
||||
// switch to ESModules, we should consider enabling this rule
|
||||
'unicorn/prefer-module': 0,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||
"@typescript-eslint/parser": "^5.22.0",
|
||||
"eslint": "^8.15.0",
|
||||
"eslint-plugin-unicorn": "^44.0.2",
|
||||
"jest": "^27.4.5",
|
||||
"prettier": "^2.2.1",
|
||||
"ts-jest": "^27.1.2",
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
/* eslint-disable unicorn/no-await-expression-member */
|
||||
|
||||
import { Cmd } from './types'
|
||||
|
||||
export const commands: Cmd[] = [
|
||||
|
@ -132,7 +135,7 @@ export const commands: Cmd[] = [
|
|||
cmd: 'setup-project',
|
||||
description: 'Sets up a gluon project for the first time',
|
||||
requestController: async () =>
|
||||
(await import('./commands/setupProject')).setupProject,
|
||||
(await import('./commands/setup-project')).setupProject,
|
||||
},
|
||||
{
|
||||
cmd: 'status',
|
||||
|
|
|
@ -10,11 +10,11 @@ import { configDispatch } from '../utils'
|
|||
export const bootstrap = async () => {
|
||||
log.info(`Bootstrapping ${config.name}...`)
|
||||
|
||||
const args = ['--application-choice', 'browser']
|
||||
const arguments_ = ['--application-choice', 'browser']
|
||||
|
||||
console.debug(`Passing through to |mach bootstrap|`)
|
||||
await configDispatch('./mach', {
|
||||
args: ['bootstrap', ...args],
|
||||
args: ['bootstrap', ...arguments_],
|
||||
cwd: ENGINE_DIR,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import execa from 'execa'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
||||
import { join, resolve } from 'path'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { bin_name, config } from '..'
|
||||
import { BUILD_TARGETS, CONFIGS_DIR, ENGINE_DIR } from '../constants'
|
||||
import { internalMozconfg } from '../constants/mozconfig'
|
||||
|
@ -28,7 +28,7 @@ const applyConfig = async (os: string) => {
|
|||
// Retrieve changeset
|
||||
const { stdout } = await execa('git', ['rev-parse', 'HEAD'])
|
||||
changeset = stdout.trim()
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.warning(
|
||||
'Gluon expects that you are building your browser with git as your version control'
|
||||
)
|
||||
|
@ -38,7 +38,7 @@ const applyConfig = async (os: string) => {
|
|||
log.warning('Otherwise, you can setup git in this folder by running:')
|
||||
log.warning(' |git init|')
|
||||
|
||||
throw e
|
||||
throw error
|
||||
}
|
||||
|
||||
const templateOptions = {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import execa from 'execa'
|
||||
import { existsSync, statSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, statSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { log } from '../log'
|
||||
import { ENGINE_DIR } from '../constants'
|
||||
|
||||
|
@ -17,7 +17,7 @@ export const discard = async (file: string): Promise<void> => {
|
|||
|
||||
try {
|
||||
await execa('git', ['restore', file], { cwd: ENGINE_DIR })
|
||||
} catch (e) {
|
||||
} catch {
|
||||
log.warning(`The file ${file} was not changed`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { isMatch } from 'picomatch'
|
||||
|
||||
import { config } from '../..'
|
||||
|
@ -10,7 +10,7 @@ import {
|
|||
AddonInfo,
|
||||
configDispatch,
|
||||
delay,
|
||||
ensureDir,
|
||||
ensureDirectory,
|
||||
walkDirectoryTree,
|
||||
windowsPathToUnix,
|
||||
} from '../../utils'
|
||||
|
@ -29,34 +29,36 @@ export async function resolveAddonDownloadUrl(
|
|||
addon: AddonInfo
|
||||
): Promise<string> {
|
||||
switch (addon.platform) {
|
||||
case 'url':
|
||||
case 'url': {
|
||||
return addon.url
|
||||
}
|
||||
|
||||
case 'amo':
|
||||
case 'amo': {
|
||||
try {
|
||||
return (
|
||||
await axios.get(
|
||||
`https://addons.mozilla.org/api/v4/addons/addon/${addon.amoId}/versions/`
|
||||
)
|
||||
).data.results[0].files[0].url
|
||||
} catch (e) {
|
||||
const mozillaData = await axios.get(
|
||||
`https://addons.mozilla.org/api/v4/addons/addon/${addon.amoId}/versions/`
|
||||
)
|
||||
|
||||
return mozillaData.data.results[0].files[0].url
|
||||
} catch (error) {
|
||||
log.warning(
|
||||
'The following error occured whilst fetching amo addon metadata'
|
||||
)
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
case 'github':
|
||||
case 'github': {
|
||||
try {
|
||||
const githubData = await axios.get(
|
||||
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
||||
)
|
||||
|
||||
return (
|
||||
(
|
||||
((
|
||||
await axios.get(
|
||||
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
||||
)
|
||||
).data.assets as {
|
||||
(githubData.data.assets as {
|
||||
url: string
|
||||
browser_download_url: string
|
||||
name: string
|
||||
|
@ -64,14 +66,15 @@ export async function resolveAddonDownloadUrl(
|
|||
).find((asset) => isMatch(asset.name, addon.fileGlob))
|
||||
?.browser_download_url || 'failed'
|
||||
)
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.warning(
|
||||
'The following error occured whilst fetching github metadata'
|
||||
)
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +82,7 @@ export async function downloadAddon(
|
|||
url: string,
|
||||
addon: AddonInfo & { name: string }
|
||||
): Promise<string> {
|
||||
const tempFile = join(MELON_TMP_DIR, addon.name + '.xpi')
|
||||
const temporaryFile = join(MELON_TMP_DIR, addon.name + '.xpi')
|
||||
|
||||
log.info(`Download addon from ${url}`)
|
||||
|
||||
|
@ -91,23 +94,23 @@ export async function downloadAddon(
|
|||
// it
|
||||
} else {
|
||||
const cache = extensionCache.unwrap()
|
||||
if (cache.url == url && existsSync(tempFile)) {
|
||||
if (cache.url == url && existsSync(temporaryFile)) {
|
||||
log.info(`Using cached version of ${addon.name}`)
|
||||
return tempFile
|
||||
return temporaryFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (existsSync(tempFile)) {
|
||||
unlinkSync(tempFile)
|
||||
if (existsSync(temporaryFile)) {
|
||||
unlinkSync(temporaryFile)
|
||||
}
|
||||
|
||||
await downloadFileToLocation(url, tempFile)
|
||||
await downloadFileToLocation(url, temporaryFile)
|
||||
|
||||
// I do not know why, but this delay causes unzip to work reliably
|
||||
await delay(200)
|
||||
|
||||
return tempFile
|
||||
return temporaryFile
|
||||
}
|
||||
|
||||
export async function unpackAddon(
|
||||
|
@ -128,7 +131,7 @@ export async function unpackAddon(
|
|||
// I do not know why, but this delay causes unzip to work reliably
|
||||
await delay(200)
|
||||
|
||||
ensureDir(outPath)
|
||||
ensureDirectory(outPath)
|
||||
|
||||
await configDispatch('unzip', {
|
||||
args: [windowsPathToUnix(path), '-d', windowsPathToUnix(outPath)],
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import execa from 'execa'
|
||||
import { existsSync } from 'fs'
|
||||
import { dirname, resolve } from 'path'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import { bin_name } from '../..'
|
||||
import { BASH_PATH, ENGINE_DIR, MELON_TMP_DIR } from '../../constants'
|
||||
import { log } from '../../log'
|
||||
import { commandExistsSync } from '../../utils/commandExists'
|
||||
import { commandExistsSync } from '../../utils/command-exists'
|
||||
import { downloadFileToLocation } from '../../utils/download'
|
||||
import { ensureDir, windowsPathToUnix } from '../../utils/fs'
|
||||
import { ensureDirectory, windowsPathToUnix } from '../../utils/fs'
|
||||
import { init } from '../init'
|
||||
|
||||
export function shouldSetupFirefoxSource() {
|
||||
|
@ -30,7 +30,7 @@ export async function setupFirefoxSource(version: string) {
|
|||
async function unpackFirefoxSource(name: string): Promise<void> {
|
||||
log.info(`Unpacking Firefox...`)
|
||||
|
||||
ensureDir(ENGINE_DIR)
|
||||
ensureDirectory(ENGINE_DIR)
|
||||
|
||||
let tarExec = 'tar'
|
||||
|
||||
|
@ -56,12 +56,12 @@ async function unpackFirefoxSource(name: string): Promise<void> {
|
|||
tarExec,
|
||||
[
|
||||
'--strip-components=1',
|
||||
process.platform == 'win32' ? '--force-local' : null,
|
||||
process.platform == 'win32' ? '--force-local' : undefined,
|
||||
'-xf',
|
||||
windowsPathToUnix(resolve(MELON_TMP_DIR, name)),
|
||||
'-C',
|
||||
windowsPathToUnix(ENGINE_DIR),
|
||||
].filter((x) => x) as string[],
|
||||
].filter(Boolean) as string[],
|
||||
{
|
||||
// HACK: Use bash shell on windows to get a sane version of tar that works
|
||||
shell: BASH_PATH || false,
|
||||
|
@ -80,7 +80,7 @@ async function downloadFirefoxSource(version: string) {
|
|||
|
||||
log.info(`Locating Firefox release ${version}...`)
|
||||
|
||||
await ensureDir(dirname(fsSaveLocation))
|
||||
await ensureDirectory(dirname(fsSaveLocation))
|
||||
|
||||
if (existsSync(fsSaveLocation)) {
|
||||
log.info('Using cached download')
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync } from 'fs'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { log } from '../log'
|
||||
import { ENGINE_DIR } from '../constants'
|
||||
import { dispatch } from '../utils'
|
||||
|
||||
export const execute = async (cmd: string[]) => {
|
||||
if (existsSync(ENGINE_DIR)) {
|
||||
if (!cmd || cmd.length == 0)
|
||||
if (!cmd || cmd.length === 0)
|
||||
log.error('You need to specify a command to run.')
|
||||
|
||||
const bin = cmd[0]
|
||||
const args = cmd
|
||||
args.shift()
|
||||
const arguments_ = cmd
|
||||
arguments_.shift()
|
||||
|
||||
log.info(
|
||||
`Executing \`${bin}${args.length !== 0 ? ` ` : ``}${args.join(
|
||||
`Executing \`${bin}${arguments_.length > 0 ? ` ` : ``}${arguments_.join(
|
||||
' '
|
||||
)}\` in \`src\`...`
|
||||
)
|
||||
dispatch(bin, args, ENGINE_DIR)
|
||||
dispatch(bin, arguments_, ENGINE_DIR)
|
||||
} else {
|
||||
log.error(`Unable to locate src directory.`)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import execa from 'execa'
|
||||
import { existsSync, writeFileSync } from 'fs'
|
||||
import { basename, resolve } from 'path'
|
||||
import { existsSync, writeFileSync } from 'node:fs'
|
||||
import { basename, resolve } from 'node:path'
|
||||
import { log } from '../log'
|
||||
import { ENGINE_DIR, SRC_DIR } from '../constants'
|
||||
import { delay, ensureDir } from '../utils'
|
||||
import { delay, ensureDirectory } from '../utils'
|
||||
|
||||
export const getPatchName = (file: string): string =>
|
||||
`${basename(file).replace(/\./g, '-')}.patch`
|
||||
|
@ -36,7 +36,7 @@ export const exportFile = async (file: string): Promise<void> => {
|
|||
const name = getPatchName(file)
|
||||
const patchPath = file.replace(/\./g, '-').split('/').slice(0, -1)
|
||||
|
||||
await ensureDir(resolve(SRC_DIR, ...patchPath))
|
||||
await ensureDirectory(resolve(SRC_DIR, ...patchPath))
|
||||
|
||||
if (proc.stdout.length >= 8000) {
|
||||
log.warning('')
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { Command } from 'commander'
|
||||
import { existsSync, readFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { bin_name } from '..'
|
||||
import { log } from '../log'
|
||||
import { config, configDispatch } from '../utils'
|
||||
|
@ -11,9 +11,9 @@ import { config, configDispatch } from '../utils'
|
|||
export const init = async (directory: Command | string): Promise<void> => {
|
||||
const cwd = process.cwd()
|
||||
|
||||
const dir = resolve(cwd as string, directory.toString())
|
||||
const absoluteInitDirectory = resolve(cwd as string, directory.toString())
|
||||
|
||||
if (!existsSync(dir)) {
|
||||
if (!existsSync(absoluteInitDirectory)) {
|
||||
log.error(
|
||||
`Directory "${directory}" not found.\nCheck the directory exists and run |${bin_name} init| again.`
|
||||
)
|
||||
|
@ -36,30 +36,31 @@ export const init = async (directory: Command | string): Promise<void> => {
|
|||
|
||||
version = version.trim().replace(/\\n/g, '')
|
||||
|
||||
// TODO: Use bash on windows, this may significantly improve performance. Still needs testing though
|
||||
// TODO: Use bash on windows, this may significantly improve performance.
|
||||
// Still needs testing though
|
||||
log.info('Initializing git, this may take some time')
|
||||
|
||||
await configDispatch('git', {
|
||||
args: ['init'],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
|
||||
await configDispatch('git', {
|
||||
args: ['init'],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
|
||||
await configDispatch('git', {
|
||||
args: ['checkout', '--orphan', version],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
|
||||
await configDispatch('git', {
|
||||
args: ['add', '-f', '.'],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
|
||||
|
@ -67,13 +68,13 @@ export const init = async (directory: Command | string): Promise<void> => {
|
|||
|
||||
await configDispatch('git', {
|
||||
args: ['commit', '-aqm', `"Firefox ${version}"`],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
|
||||
await configDispatch('git', {
|
||||
args: ['checkout', '-b', config.name.toLowerCase().replace(/\s/g, '_')],
|
||||
cwd: dir,
|
||||
cwd: absoluteInitDirectory,
|
||||
shell: 'unix',
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import { join } from 'path'
|
||||
import { join } from 'node:path'
|
||||
import { isValidLicense } from './license-check'
|
||||
|
||||
describe('isValidLicense', () => {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { readFile, writeFile } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
|
||||
import { SRC_DIR } from '../constants'
|
||||
import { walkDirectory } from '../utils/fs'
|
||||
import { Task, TaskList } from '../utils/taskList'
|
||||
import { Task, TaskList } from '../utils/task-list'
|
||||
|
||||
const ignoredFiles = new RegExp('.*\\.(json|patch|md|jpeg|png|gif|tiff|ico)')
|
||||
const licenseIgnore = new RegExp('(//|#) Ignore license in this file', 'g')
|
||||
|
@ -32,7 +32,7 @@ const fixableFiles = [
|
|||
]
|
||||
|
||||
export async function isValidLicense(path: string): Promise<boolean> {
|
||||
const file = (await readFile(path)).toString()
|
||||
const file = await readFile(path, { encoding: 'utf8' })
|
||||
const contents = file.split('\n')
|
||||
|
||||
// We need to grab the top 5 lines just in case there are newlines in the
|
||||
|
@ -58,7 +58,8 @@ export function createTask(path: string, noFix: boolean): Task {
|
|||
skip: () => ignoredFiles.test(path),
|
||||
name: path.replace(SRC_DIR, ''),
|
||||
task: async () => {
|
||||
const contents = (await readFile(path)).toString().split('\n')
|
||||
const contents = await readFile(path, { encoding: 'utf8' })
|
||||
const contentsSplitNewline = contents.split('\n')
|
||||
const hasLicense = await isValidLicense(path)
|
||||
|
||||
if (hasLicense) {
|
||||
|
@ -73,11 +74,12 @@ export function createTask(path: string, noFix: boolean): Task {
|
|||
)
|
||||
}
|
||||
|
||||
const mpl = (
|
||||
await readFile(join(__dirname, 'license-check.txt'))
|
||||
).toString()
|
||||
const mplHeader = // eslint-disable-next-line unicorn/prefer-module
|
||||
await readFile(join(__dirname, 'license-check.txt'), {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
const { comment, commentOpen, commentClose } = fixable
|
||||
let header = mpl
|
||||
let header = mplHeader
|
||||
.split('\n')
|
||||
.map((ln) => (comment || '') + ln)
|
||||
.join('\n')
|
||||
|
@ -86,7 +88,7 @@ export function createTask(path: string, noFix: boolean): Task {
|
|||
header = commentOpen + header + commentClose
|
||||
}
|
||||
|
||||
await writeFile(path, header + '\n' + contents.join('\n'))
|
||||
await writeFile(path, header + '\n' + contentsSplitNewline.join('\n'))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync } from 'fs'
|
||||
import { copyFile, mkdir, readdir, unlink } from 'fs/promises'
|
||||
import { join, resolve } from 'path'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { copyFile, mkdir, readdir, unlink } from 'node:fs/promises'
|
||||
import { join, resolve } from 'node:path'
|
||||
|
||||
import { bin_name, config } from '..'
|
||||
import { DIST_DIR, ENGINE_DIR, OBJ_DIR } from '../constants'
|
||||
|
@ -37,15 +37,15 @@ export const gluonPackage = async () => {
|
|||
log.error(`Cannot locate the 'mach' binary within ${ENGINE_DIR}`)
|
||||
}
|
||||
|
||||
const args = ['package']
|
||||
const arguments_ = ['package']
|
||||
|
||||
log.info(
|
||||
`Packaging \`${config.binaryName}\` with args ${JSON.stringify(
|
||||
args.slice(1, 0)
|
||||
arguments_.slice(1, 0)
|
||||
)}...`
|
||||
)
|
||||
|
||||
await dispatch(machPath, args, ENGINE_DIR, true)
|
||||
await dispatch(machPath, arguments_, ENGINE_DIR, true)
|
||||
|
||||
log.info('Copying results up')
|
||||
|
||||
|
@ -53,31 +53,41 @@ export const gluonPackage = async () => {
|
|||
if (!existsSync(DIST_DIR)) await mkdir(DIST_DIR, { recursive: true })
|
||||
|
||||
log.debug('Indexing files to copy')
|
||||
const files = (await readdir(join(OBJ_DIR, 'dist'), { withFileTypes: true }))
|
||||
const filesInMozillaDistrobution = await readdir(join(OBJ_DIR, 'dist'), {
|
||||
withFileTypes: true,
|
||||
})
|
||||
const files = filesInMozillaDistrobution
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
|
||||
for (const file of files) {
|
||||
const destFile = join(DIST_DIR, file)
|
||||
const destinationFile = join(DIST_DIR, file)
|
||||
log.debug(`Copying ${file}`)
|
||||
if (existsSync(destFile)) await unlink(destFile)
|
||||
await copyFile(join(OBJ_DIR, 'dist', file), destFile)
|
||||
if (existsSync(destinationFile)) await unlink(destinationFile)
|
||||
await copyFile(join(OBJ_DIR, 'dist', file), destinationFile)
|
||||
}
|
||||
|
||||
// Windows has some special dist files that are available within the dist
|
||||
// directory.
|
||||
if (process.platform == 'win32') {
|
||||
const installerDistDirectory = join(OBJ_DIR, 'dist', 'install', 'sea')
|
||||
const installerDistributionDirectory = join(
|
||||
OBJ_DIR,
|
||||
'dist',
|
||||
'install',
|
||||
'sea'
|
||||
)
|
||||
|
||||
if (!existsSync(installerDistDirectory)) {
|
||||
if (!existsSync(installerDistributionDirectory)) {
|
||||
log.error(
|
||||
`Could not find windows installer files located at '${installerDistDirectory}'`
|
||||
`Could not find windows installer files located at '${installerDistributionDirectory}'`
|
||||
)
|
||||
}
|
||||
|
||||
const windowsInstallerFiles = (
|
||||
await readdir(installerDistDirectory, { withFileTypes: true })
|
||||
const installerDistributionDirectoryContents = await readdir(
|
||||
installerDistributionDirectory,
|
||||
{ withFileTypes: true }
|
||||
)
|
||||
const windowsInstallerFiles = installerDistributionDirectoryContents
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
|
||||
|
@ -96,10 +106,13 @@ export const gluonPackage = async () => {
|
|||
}
|
||||
|
||||
// Actually copy
|
||||
const destFile = join(DIST_DIR, newFileName)
|
||||
const destinationFile = join(DIST_DIR, newFileName)
|
||||
log.debug(`Copying ${file}`)
|
||||
if (existsSync(destFile)) await unlink(destFile)
|
||||
await copyFile(join(installerDistDirectory, file), destFile)
|
||||
if (existsSync(destinationFile)) await unlink(destinationFile)
|
||||
await copyFile(
|
||||
join(installerDistributionDirectory, file),
|
||||
destinationFile
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,18 +150,10 @@ async function createMarFile(version: string, channel: string) {
|
|||
// On macos this should be
|
||||
// <obj dir>/dist/${binaryName}/${brandFullName}.app and on everything else,
|
||||
// the contents of the folder <obj dir>/dist/${binaryName}
|
||||
let binary: string
|
||||
|
||||
if (process.platform == 'darwin') {
|
||||
binary = join(
|
||||
OBJ_DIR,
|
||||
'dist',
|
||||
config.binaryName,
|
||||
`${getCurrentBrandName()}.app`
|
||||
)
|
||||
} else {
|
||||
binary = join(OBJ_DIR, 'dist', config.binaryName)
|
||||
}
|
||||
const binary =
|
||||
process.platform == 'darwin'
|
||||
? join(OBJ_DIR, 'dist', config.binaryName, `${getCurrentBrandName()}.app`)
|
||||
: join(OBJ_DIR, 'dist', config.binaryName)
|
||||
|
||||
const marPath = windowsPathToUnix(join(DIST_DIR, 'output.mar'))
|
||||
await configDispatch('./tools/update-packaging/make_full_update.sh', {
|
||||
|
|
|
@ -10,10 +10,10 @@ import {
|
|||
readFileSync,
|
||||
writeFileSync,
|
||||
copyFileSync,
|
||||
} from 'fs'
|
||||
import { copyFile, readFile, rm, writeFile } from 'fs/promises'
|
||||
} from 'node:fs'
|
||||
import { copyFile, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { every } from 'modern-async'
|
||||
import { dirname, extname, join } from 'path'
|
||||
import { dirname, extname, join } from 'node:path'
|
||||
import sharp from 'sharp'
|
||||
import pngToIco from 'png-to-ico'
|
||||
import asyncIcns from 'async-icns'
|
||||
|
@ -31,7 +31,7 @@ import {
|
|||
walkDirectory,
|
||||
windowsPathToUnix,
|
||||
} from '../../utils'
|
||||
import { templateDir } from '../setupProject'
|
||||
import { templateDirectory } from '../setup-project'
|
||||
import { IMelonPatch } from './command'
|
||||
|
||||
// =============================================================================
|
||||
|
@ -74,7 +74,7 @@ function constructConfig(name: string) {
|
|||
brandingVendor: config.vendor,
|
||||
|
||||
...defaultBrandsConfig,
|
||||
...(config.brands[name] || {}),
|
||||
...config.brands[name],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,15 +111,15 @@ async function setupImages(configPath: string, outputPath: string) {
|
|||
// TODO: Custom MacOS icon support
|
||||
if (process.platform == 'darwin') {
|
||||
log.debug('Generating Mac Icons')
|
||||
const tmp = join(MELON_TMP_DIR, 'macos_icon_info.iconset')
|
||||
const temporary = join(MELON_TMP_DIR, 'macos_icon_info.iconset')
|
||||
|
||||
if (existsSync(tmp)) await rm(tmp, { recursive: true })
|
||||
if (existsSync(temporary)) await rm(temporary, { recursive: true })
|
||||
|
||||
asyncIcns.convert({
|
||||
input: join(configPath, 'logo.png'),
|
||||
output: join(outputPath, 'firefox.icns'),
|
||||
sizes: [16, 32, 64, 128, 256, 512],
|
||||
tmpDirectory: tmp,
|
||||
tmpDirectory: temporary,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -155,22 +155,32 @@ async function setupLocale(
|
|||
brandingVendor: string
|
||||
}
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
||||
;(await walkDirectory(join(templateDir, 'branding.optional')))
|
||||
.map((file) =>
|
||||
windowsPathToUnix(file).replace(
|
||||
windowsPathToUnix(join(templateDir, 'branding.optional') + '/'),
|
||||
''
|
||||
)
|
||||
)
|
||||
.map((file) => [
|
||||
readFileSync(join(templateDir, 'branding.optional', file)).toString(),
|
||||
join(outputPath, file),
|
||||
])
|
||||
.forEach(([contents, path]) => {
|
||||
mkdirSync(dirname(path), { recursive: true })
|
||||
writeFileSync(path, stringTemplate(contents, brandingConfig))
|
||||
for (const file of await walkDirectory(
|
||||
join(templateDirectory, 'branding.optional')
|
||||
)) {
|
||||
const fileContents = await readFile(windowsPathToUnix(file), {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
|
||||
const universalPath =
|
||||
// We want to avoid the pain that windows is going to throw at us with its
|
||||
// weird paths
|
||||
windowsPathToUnix(file)
|
||||
// We want to remove all of the extra folders that surround this from the
|
||||
// template folder
|
||||
.replace(
|
||||
windowsPathToUnix(join(templateDirectory, 'branding.optional') + '/'),
|
||||
''
|
||||
)
|
||||
|
||||
const sourceFolderPath = join(outputPath, universalPath)
|
||||
|
||||
await mkdir(dirname(sourceFolderPath), { recursive: true })
|
||||
await writeFile(
|
||||
sourceFolderPath,
|
||||
stringTemplate(fileContents, brandingConfig)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function copyMozFiles(
|
||||
|
@ -184,7 +194,8 @@ async function copyMozFiles(
|
|||
brandingVendor: string
|
||||
}
|
||||
) {
|
||||
const files = (await walkDirectory(BRANDING_FF)).filter(
|
||||
const firefoxBrandingDirectoryContents = await walkDirectory(BRANDING_FF)
|
||||
const files = firefoxBrandingDirectoryContents.filter(
|
||||
(file) => !existsSync(join(outputPath, file.replace(BRANDING_FF, '')))
|
||||
)
|
||||
|
||||
|
@ -192,7 +203,7 @@ async function copyMozFiles(
|
|||
|
||||
const everythingElse = files.filter((file) => !css.includes(file))
|
||||
|
||||
css
|
||||
for (const [contents, path] of css
|
||||
.map((filePath) => [
|
||||
readFileSync(filePath).toString(),
|
||||
join(outputPath, filePath.replace(BRANDING_FF, '')),
|
||||
|
@ -201,17 +212,16 @@ async function copyMozFiles(
|
|||
contents.replace(CSS_REPLACE_REGEX, 'var(--theme-bg)') +
|
||||
`:root { --theme-bg: ${brandingConfig.backgroundColor} }`,
|
||||
path,
|
||||
])
|
||||
.forEach(([contents, path]) => {
|
||||
mkdirSync(dirname(path), { recursive: true })
|
||||
writeFileSync(path, contents)
|
||||
})
|
||||
])) {
|
||||
mkdirSync(dirname(path), { recursive: true })
|
||||
writeFileSync(path, contents)
|
||||
}
|
||||
|
||||
// Copy everything else from the default firefox branding directory
|
||||
everythingElse.forEach((file) => {
|
||||
for (const file of everythingElse) {
|
||||
mkdirpSync(dirname(join(outputPath, file.replace(BRANDING_FF, ''))))
|
||||
copyFileSync(file, join(outputPath, file.replace(BRANDING_FF, '')))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
|
@ -1,19 +1,19 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { join } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import { join } from 'node:path'
|
||||
import { existsSync } from 'node:fs'
|
||||
import glob from 'tiny-glob'
|
||||
|
||||
import { ENGINE_DIR, SRC_DIR } from '../../constants'
|
||||
import * as gitPatch from './gitPatch'
|
||||
import * as copyPatch from './copyPatches'
|
||||
import * as brandingPatch from './brandingPatch'
|
||||
import * as gitPatch from './git-patch'
|
||||
import * as copyPatch from './copy-patches'
|
||||
import * as brandingPatch from './branding-patch'
|
||||
import { patchCountFile } from '../../middleware/patch-check'
|
||||
import { checkHash } from '../../utils'
|
||||
import { templateDir } from '../setupProject'
|
||||
import { Task, TaskList } from '../../utils/taskList'
|
||||
import { writeFile } from 'fs/promises'
|
||||
import { templateDirectory } from '../setup-project'
|
||||
import { Task, TaskList } from '../../utils/task-list'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
|
||||
export interface IMelonPatch {
|
||||
name: string
|
||||
|
@ -23,7 +23,7 @@ export interface IMelonPatch {
|
|||
function patchMethod<T extends IMelonPatch>(
|
||||
name: string,
|
||||
patches: T[],
|
||||
patchFn: (patch: T, index: number) => Promise<void>
|
||||
patchFunction: (patch: T, index: number) => Promise<void>
|
||||
): Task {
|
||||
return {
|
||||
name: `Apply ${patches.length} ${name} patches`,
|
||||
|
@ -32,7 +32,7 @@ function patchMethod<T extends IMelonPatch>(
|
|||
new TaskList(
|
||||
patches.map((patch, index) => ({
|
||||
name: `Apply ${patch.name}`,
|
||||
task: () => patchFn(patch, index),
|
||||
task: () => patchFunction(patch, index),
|
||||
skip: patch.skip,
|
||||
}))
|
||||
),
|
||||
|
@ -80,12 +80,11 @@ async function importFolders(): Promise<Task> {
|
|||
}
|
||||
|
||||
async function importGitPatch(): Promise<Task> {
|
||||
const patches = (
|
||||
await glob('**/*.patch', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
).map((path) => join(SRC_DIR, path))
|
||||
let patches = await glob('**/*.patch', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
patches = patches.map((path) => join(SRC_DIR, path))
|
||||
|
||||
await writeFile(patchCountFile, patches.length.toString())
|
||||
|
||||
|
@ -97,19 +96,18 @@ async function importGitPatch(): Promise<Task> {
|
|||
}
|
||||
|
||||
async function importInternalPatch(): Promise<Task> {
|
||||
const patches = (
|
||||
await glob('*.patch', {
|
||||
filesOnly: true,
|
||||
cwd: join(templateDir, 'patches.optional'),
|
||||
})
|
||||
).map((path) => ({
|
||||
const patches = await glob('*.patch', {
|
||||
filesOnly: true,
|
||||
cwd: join(templateDirectory, 'patches.optional'),
|
||||
})
|
||||
const structuredPatches = patches.map((path) => ({
|
||||
name: path,
|
||||
path: join(templateDir, 'patches.optional', path),
|
||||
path: join(templateDirectory, 'patches.optional', path),
|
||||
}))
|
||||
|
||||
return patchMethod<gitPatch.IGitPatch>(
|
||||
'gluon',
|
||||
patches,
|
||||
structuredPatches,
|
||||
async (patch) => await gitPatch.apply(patch.path)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync } from 'fs'
|
||||
import { lstatSync, readFileSync } from 'fs'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { lstatSync, readFileSync } from 'node:fs'
|
||||
import { ensureSymlink, remove } from 'fs-extra'
|
||||
import { copyFile } from 'fs/promises'
|
||||
import { dirname, resolve } from 'path'
|
||||
import { copyFile } from 'node:fs/promises'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import glob from 'tiny-glob'
|
||||
|
||||
import { appendToFileSync, mkdirp } from '../../utils'
|
||||
|
@ -70,21 +70,20 @@ export interface ICopyPatch extends IMelonPatch {
|
|||
// Exports
|
||||
|
||||
export async function get(): Promise<ICopyPatch[]> {
|
||||
const files = (
|
||||
await glob('**/*', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
).filter(
|
||||
const allFilesInSource = await glob('**/*', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
const files = allFilesInSource.filter(
|
||||
(f) => !(f.endsWith('.patch') || f.split('/').includes('node_modules'))
|
||||
)
|
||||
|
||||
const manualPatches: ICopyPatch[] = []
|
||||
|
||||
files.map((i) => {
|
||||
const group = i.split('/')[0]
|
||||
files.map((index) => {
|
||||
const group = index.split('/')[0]
|
||||
|
||||
if (!manualPatches.find((m) => m.name == group)) {
|
||||
if (!manualPatches.some((m) => m.name == group)) {
|
||||
manualPatches.push({
|
||||
name: group,
|
||||
src: files.filter((f) => f.split('/')[0] == group),
|
||||
|
@ -95,8 +94,8 @@ export async function get(): Promise<ICopyPatch[]> {
|
|||
return manualPatches
|
||||
}
|
||||
|
||||
export async function apply(src: string[]): Promise<void> {
|
||||
for (const item of src) {
|
||||
export async function apply(source: string[]): Promise<void> {
|
||||
for (const item of source) {
|
||||
await copyManual(item)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import execa from 'execa'
|
||||
import { PATCH_ARGS, ENGINE_DIR } from '../../constants'
|
||||
import { log } from '../../log'
|
||||
import { IMelonPatch } from './command'
|
||||
|
||||
export interface IGitPatch extends IMelonPatch {
|
||||
|
@ -14,11 +16,11 @@ export async function apply(path: string): Promise<void> {
|
|||
await execa('git', ['apply', '-R', ...PATCH_ARGS, path], {
|
||||
cwd: ENGINE_DIR,
|
||||
})
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
// If the patch has already been applied, we want to revert it. Because
|
||||
// there is no good way to check this we are just going to catch and
|
||||
// discard the error
|
||||
null
|
||||
undefined
|
||||
}
|
||||
|
||||
const { stdout, exitCode } = await execa(
|
||||
|
@ -27,5 +29,5 @@ export async function apply(path: string): Promise<void> {
|
|||
{ cwd: ENGINE_DIR }
|
||||
)
|
||||
|
||||
if (exitCode != 0) throw stdout
|
||||
if (exitCode != 0) log.error(stdout)
|
||||
}
|
|
@ -1,27 +1,29 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync, readdirSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, readdirSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { bin_name } from '..'
|
||||
import { ENGINE_DIR } from '../constants'
|
||||
import { log } from '../log'
|
||||
import { config, dispatch } from '../utils'
|
||||
|
||||
export const run = async (chrome?: string) => {
|
||||
const dirs = readdirSync(ENGINE_DIR)
|
||||
const objDirname = dirs.find((dir) => dir.startsWith('obj-'))
|
||||
const directories = readdirSync(ENGINE_DIR)
|
||||
const objectDirname = directories.find((directory) =>
|
||||
directory.startsWith('obj-')
|
||||
)
|
||||
|
||||
if (!objDirname) {
|
||||
if (!objectDirname) {
|
||||
throw new Error(`${config.name} needs to be built before you can do this.`)
|
||||
}
|
||||
|
||||
const objDir = resolve(ENGINE_DIR, objDirname)
|
||||
const objectDirectory = resolve(ENGINE_DIR, objectDirname)
|
||||
|
||||
if (existsSync(objDir)) {
|
||||
if (existsSync(objectDirectory)) {
|
||||
dispatch(
|
||||
'./mach',
|
||||
['run'].concat(chrome ? ['-chrome', chrome] : []),
|
||||
['run', ...(chrome ? ['-chrome', chrome] : [])],
|
||||
ENGINE_DIR,
|
||||
true
|
||||
)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'fs'
|
||||
import { copyFile } from 'fs/promises'
|
||||
import { join, dirname } from 'path'
|
||||
import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'
|
||||
import { copyFile } from 'node:fs/promises'
|
||||
import { join, dirname } from 'node:path'
|
||||
|
||||
import prompts from 'prompts'
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
|||
configPath,
|
||||
delay,
|
||||
getLatestFF,
|
||||
projectDir,
|
||||
projectDirectory,
|
||||
SupportedProducts,
|
||||
walkDirectory,
|
||||
} from '../utils'
|
||||
|
@ -48,7 +48,7 @@ export async function setupProject(): Promise<void> {
|
|||
},
|
||||
{
|
||||
title: 'Firefox developer edition (Not recommended)',
|
||||
value: SupportedProducts.FirefoxDev,
|
||||
value: SupportedProducts.FirefoxDevelopment,
|
||||
},
|
||||
{
|
||||
title: 'Firefox beta (Not recommended)',
|
||||
|
@ -136,10 +136,10 @@ export async function setupProject(): Promise<void> {
|
|||
await copyOptional(['browser/themes'])
|
||||
}
|
||||
|
||||
writeFileSync(configPath, JSON.stringify(config, null, 2))
|
||||
writeFileSync(configPath, JSON.stringify(config, undefined, 2))
|
||||
|
||||
// Append important stuff to gitignore
|
||||
const gitignore = join(projectDir, '.gitignore')
|
||||
const gitignore = join(projectDirectory, '.gitignore')
|
||||
let gitignoreContents = ''
|
||||
|
||||
if (existsSync(gitignore)) {
|
||||
|
@ -149,48 +149,64 @@ export async function setupProject(): Promise<void> {
|
|||
gitignoreContents += '\n.dotbuild/\nengine/\nfirefox-*/\nnode_modules/\n'
|
||||
|
||||
writeFileSync(gitignore, gitignoreContents)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Filesystem templating
|
||||
|
||||
export const templateDir = join(__dirname, '../..', 'template')
|
||||
// eslint-disable-next-line unicorn/prefer-module
|
||||
export const templateDirectory = join(__dirname, '../..', 'template')
|
||||
|
||||
/**
|
||||
* Copy files from the template directory that have .optional in their path,
|
||||
* based on the function parameters
|
||||
*
|
||||
* @param files The files that should be coppied
|
||||
*/
|
||||
async function copyOptional(files: string[]) {
|
||||
await Promise.all(
|
||||
(
|
||||
await walkDirectory(templateDir)
|
||||
const directoryContents = await walkDirectory(templateDirectory)
|
||||
|
||||
for (const file of directoryContents) {
|
||||
if (
|
||||
!file.includes('.optional') &&
|
||||
!files
|
||||
.map((induvidualFile) => file.includes(induvidualFile))
|
||||
.some(Boolean)
|
||||
)
|
||||
.filter((f) => f.includes('.optional'))
|
||||
.filter((f) => files.map((file) => f.includes(file)).some((b) => b))
|
||||
.map(async (file) => {
|
||||
const out = join(projectDir, file.replace(templateDir, '')).replace(
|
||||
'.optional',
|
||||
''
|
||||
)
|
||||
if (!existsSync(out)) {
|
||||
mkdirSync(dirname(out), { recursive: true })
|
||||
await copyFile(file, out)
|
||||
}
|
||||
})
|
||||
)
|
||||
continue
|
||||
|
||||
const outLocation = join(
|
||||
projectDirectory,
|
||||
file.replace(templateDirectory, '')
|
||||
).replace('.optional', '')
|
||||
|
||||
if (!existsSync(outLocation)) {
|
||||
mkdirSync(dirname(outLocation), { recursive: true })
|
||||
await copyFile(file, outLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all non-optional files from the template directory
|
||||
*/
|
||||
async function copyRequired() {
|
||||
await Promise.all(
|
||||
(
|
||||
await walkDirectory(templateDir)
|
||||
const directoryContents = await walkDirectory(templateDirectory)
|
||||
|
||||
for (const file of directoryContents) {
|
||||
if (file.includes('.optional')) continue
|
||||
|
||||
const outLocation = join(
|
||||
projectDirectory,
|
||||
file.replace(templateDirectory, '')
|
||||
)
|
||||
.filter((f) => !f.includes('.optional'))
|
||||
.map(async (file) => {
|
||||
const out = join(projectDir, file.replace(templateDir, ''))
|
||||
if (!existsSync(out)) {
|
||||
mkdirSync(dirname(out), { recursive: true })
|
||||
await copyFile(file, out)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
if (!existsSync(outLocation)) {
|
||||
mkdirSync(dirname(outLocation), { recursive: true })
|
||||
await copyFile(file, outLocation)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync } from 'fs'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { log } from '../log'
|
||||
import { BIN_NAME, ENGINE_DIR } from '../constants'
|
||||
import { dispatch, hasConfig } from '../utils'
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import { stat, writeFile } from 'fs/promises'
|
||||
import { dirname, join } from 'path'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { create } from 'xmlbuilder2'
|
||||
import { DIST_DIR } from '../../constants'
|
||||
import { dynamicConfig, ensureDir, generateHash, getSize } from '../../utils'
|
||||
import {
|
||||
dynamicConfig,
|
||||
ensureDirectory,
|
||||
generateHash,
|
||||
getSize,
|
||||
} from '../../utils'
|
||||
import {
|
||||
downloadAddon,
|
||||
getAddons,
|
||||
|
@ -45,6 +50,6 @@ export async function generateAddonUpdateFiles() {
|
|||
'update.xml'
|
||||
)
|
||||
|
||||
await ensureDir(dirname(path))
|
||||
await ensureDirectory(dirname(path))
|
||||
await writeFile(path, root.end({ prettyPrint: true }))
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { existsSync } from 'fs'
|
||||
import { readFile, writeFile } from 'fs/promises'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { parse } from 'ini'
|
||||
import { isAppleSilicon } from 'is-apple-silicon'
|
||||
import { dirname, join } from 'path'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { create } from 'xmlbuilder2'
|
||||
import { bin_name, config } from '../..'
|
||||
import { DIST_DIR, OBJ_DIR } from '../../constants'
|
||||
|
@ -41,7 +41,8 @@ export async function getPlatformConfig() {
|
|||
if (!existsSync(platformINI))
|
||||
platformINI = join(OBJ_DIR, 'dist', 'bin', 'platform.ini')
|
||||
|
||||
return parse((await readFile(platformINI)).toString())
|
||||
const iniContents = await readFile(platformINI)
|
||||
return parse(iniContents.toString())
|
||||
}
|
||||
|
||||
function getReleaseMarName(releaseInfo: ReleaseInfo): string | undefined {
|
||||
|
@ -52,12 +53,15 @@ function getReleaseMarName(releaseInfo: ReleaseInfo): string | undefined {
|
|||
}
|
||||
|
||||
switch (process.platform) {
|
||||
case 'win32':
|
||||
case 'win32': {
|
||||
return releaseInfo.x86?.windowsMar
|
||||
case 'darwin':
|
||||
}
|
||||
case 'darwin': {
|
||||
return releaseInfo.x86?.macosMar
|
||||
case 'linux':
|
||||
}
|
||||
case 'linux': {
|
||||
return releaseInfo.x86?.linuxMar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +88,7 @@ async function writeUpdateFileToDisk(
|
|||
channel: string,
|
||||
updateObject: {
|
||||
updates: {
|
||||
update: Record<string, any>
|
||||
update: Record<string, string | undefined>
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import execa from 'execa'
|
||||
import { existsSync, mkdirSync, readdirSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, mkdirSync, readdirSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { log } from '../log'
|
||||
|
||||
export const BIN_NAME = 'gluon'
|
||||
|
@ -63,13 +63,13 @@ export const OBJ_DIR = resolve(ENGINE_DIR, `obj-${CONFIG_GUESS}`)
|
|||
|
||||
// TODO: Remove this, it is unused
|
||||
export const FTL_STRING_LINE_REGEX =
|
||||
/(([a-zA-Z0-9-]*|\.[a-z-]*) =(.*|\.)|\[[a-zA-Z0-9]*\].*(\n\s?\s?})?|\*\[[a-zA-Z0-9]*\] .*(\n\s?\s?})?)/gm
|
||||
/(([\dA-Za-z-]*|\.[a-z-]*) =(.*|\.)|\[[\dA-Za-z]*].*(\n\s?\s?})?|\*\[[\dA-Za-z]*] .*(\n\s?\s?})?)/gm
|
||||
|
||||
// =================
|
||||
// Windows constants
|
||||
// =================
|
||||
|
||||
export let BASH_PATH: string | null = null
|
||||
export let BASH_PATH: string | undefined
|
||||
|
||||
// All windows specific code should be located inside of this if statement
|
||||
if (process.platform == 'win32') {
|
||||
|
|
|
@ -3,14 +3,7 @@ import { config } from '..'
|
|||
const otherBuildModes = `# You can change to other build modes by running:
|
||||
# $ gluon set buildMode [dev|debug|release]`
|
||||
|
||||
const platformOptimize =
|
||||
process.platform == 'darwin'
|
||||
? 'ac_add_options --enable-optimize="-O3 -march=nehalem -mtune=haswell -w"'
|
||||
: process.platform == 'linux'
|
||||
? 'ac_add_options --enable-optimize="-O3 -march=haswell -mtune=haswell -w"'
|
||||
: process.platform == 'win32'
|
||||
? 'ac_add_options --enable-optimize="-O2 -Qvec -w -clang:-ftree-vectorize -clang:-msse3 -clang:-mssse3 -clang:-msse4.1 -clang:-mtune=haswell"'
|
||||
: `# Unknown platform ${process.platform}`
|
||||
const platformOptimize = getPlatformOptimiseFlags()
|
||||
|
||||
export const internalMozconfg = (
|
||||
brand: string,
|
||||
|
@ -20,24 +13,27 @@ export const internalMozconfg = (
|
|||
|
||||
// Get the specific build options for the current build mode
|
||||
switch (buildMode) {
|
||||
case 'dev':
|
||||
case 'dev': {
|
||||
buildOptions = `# Development build settings
|
||||
${otherBuildModes}
|
||||
ac_add_options --disable-debug`
|
||||
break
|
||||
case 'debug':
|
||||
}
|
||||
case 'debug': {
|
||||
buildOptions = `# Debug build settings
|
||||
${otherBuildModes}
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --disable-optimize`
|
||||
break
|
||||
}
|
||||
|
||||
case 'release':
|
||||
case 'release': {
|
||||
buildOptions = `# Release build settings
|
||||
ac_add_options --disable-debug
|
||||
ac_add_options --enable-optimize
|
||||
${platformOptimize} # Taken from waterfox`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return `
|
||||
|
@ -61,3 +57,24 @@ export MOZ_APPUPDATE_HOST=${
|
|||
}
|
||||
`
|
||||
}
|
||||
|
||||
function getPlatformOptimiseFlags(): string {
|
||||
let optimiseFlags = `# Unknown platform ${process.platform}`
|
||||
|
||||
switch (process.platform) {
|
||||
case 'linux': {
|
||||
optimiseFlags = `ac_add_options --enable-optimize="-O3 -march=haswell -mtune=haswell -w"`
|
||||
break
|
||||
}
|
||||
case 'darwin': {
|
||||
optimiseFlags = `ac_add_options --enable-optimize="-O3 -march=nehalem -mtune=haswell -w"`
|
||||
break
|
||||
}
|
||||
case 'win32': {
|
||||
optimiseFlags = `ac_add_options --enable-optimize="-O2 -Qvec -w -clang:-ftree-vectorize -clang:-msse3 -clang:-mssse3 -clang:-msse4.1 -clang:-mtune=haswell"`
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return optimiseFlags
|
||||
}
|
||||
|
|
35
src/index.ts
35
src/index.ts
|
@ -4,19 +4,19 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import commander, { Command } from 'commander'
|
||||
import { existsSync, readFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
|
||||
import { errorHandler, config as configInited, versionFormatter } from './utils'
|
||||
import { commands } from './cmds'
|
||||
import { BIN_NAME, ENGINE_DIR } from './constants'
|
||||
import { updateCheck } from './middleware/update-check'
|
||||
import { registerCommand } from './middleware/registerCommand'
|
||||
import { registerCommand } from './middleware/register-command'
|
||||
import { log } from './log'
|
||||
|
||||
// We have to use a dynamic require here, otherwise the typescript compiler
|
||||
// mucks up the directory structure
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, unicorn/prefer-module
|
||||
const { version: gluonVersion } = require('../package.json')
|
||||
|
||||
export const config = configInited
|
||||
|
@ -76,14 +76,13 @@ async function middleware(command: commander.Command) {
|
|||
registerCommand(command.name())
|
||||
}
|
||||
|
||||
commands.forEach((command) => {
|
||||
if (command.flags) {
|
||||
if (
|
||||
command.flags.platforms &&
|
||||
!command.flags.platforms.includes(process.platform)
|
||||
) {
|
||||
return
|
||||
}
|
||||
for (const command of commands) {
|
||||
if (
|
||||
command.flags &&
|
||||
command.flags.platforms &&
|
||||
!command.flags.platforms.includes(process.platform)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
let buildCommand = program
|
||||
|
@ -92,11 +91,11 @@ commands.forEach((command) => {
|
|||
.aliases(command?.aliases || [])
|
||||
|
||||
// Register all of the required options
|
||||
command?.options?.forEach((opt) => {
|
||||
for (const opt of command?.options || []) {
|
||||
buildCommand = buildCommand.option(opt.arg, opt.description)
|
||||
})
|
||||
}
|
||||
|
||||
buildCommand = buildCommand.action(async (...args) => {
|
||||
buildCommand = buildCommand.action(async (...arguments_) => {
|
||||
// Start loading the controller in the background whilst middleware is
|
||||
// executing
|
||||
const controller = command.requestController()
|
||||
|
@ -107,12 +106,12 @@ commands.forEach((command) => {
|
|||
|
||||
// Finish loading the controller and execute it
|
||||
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
||||
;(await controller)(...args)
|
||||
;(await controller)(...arguments_)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
process
|
||||
.on('uncaughtException', errorHandler)
|
||||
.on('unhandledException', (err) => errorHandler(err, true))
|
||||
.on('unhandledException', (error) => errorHandler(error, true))
|
||||
|
||||
program.parse(process.argv)
|
||||
|
|
48
src/log.ts
48
src/log.ts
|
@ -4,6 +4,9 @@
|
|||
import chalk from 'chalk'
|
||||
import prompts from 'prompts'
|
||||
|
||||
const formatToDoubleDigit = (r: number) =>
|
||||
r.toString().length == 1 ? `0${r}` : r
|
||||
|
||||
class Log {
|
||||
private startTime: number
|
||||
|
||||
|
@ -26,15 +29,15 @@ class Log {
|
|||
const mins = Math.floor((elapsedTime / (60 * 1000)) % 60)
|
||||
const hours = Math.floor((elapsedTime / (60 * 60 * 1000)) % 24)
|
||||
|
||||
const format = (r: number) => (r.toString().length == 1 ? `0${r}` : r)
|
||||
|
||||
return `${format(hours)}:${format(mins)}:${format(secs)}`
|
||||
return `${formatToDoubleDigit(hours)}:${formatToDoubleDigit(
|
||||
mins
|
||||
)}:${formatToDoubleDigit(secs)}`
|
||||
}
|
||||
|
||||
set isDebug(val: boolean) {
|
||||
log.debug(`Logger debug mode has been ${val ? 'enabled' : 'disabled'}`)
|
||||
this._isDebug = val
|
||||
log.debug(`Logger debug mode has been ${val ? 'enabled' : 'disabled'}`)
|
||||
set isDebug(value: boolean) {
|
||||
log.debug(`Logger debug mode has been ${value ? 'enabled' : 'disabled'}`)
|
||||
this._isDebug = value
|
||||
log.debug(`Logger debug mode has been ${value ? 'enabled' : 'disabled'}`)
|
||||
}
|
||||
|
||||
get isDebug() {
|
||||
|
@ -46,8 +49,8 @@ class Log {
|
|||
*
|
||||
* @param args The information you want to provide to the user
|
||||
*/
|
||||
debug(...args: unknown[]): void {
|
||||
if (this.isDebug) console.debug(...args)
|
||||
debug(...arguments_: unknown[]): void {
|
||||
if (this.isDebug) console.debug(...arguments_)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,8 +60,8 @@ class Log {
|
|||
*
|
||||
* @param args The information you want to provide to the user
|
||||
*/
|
||||
info(...args: unknown[]): void {
|
||||
console.info(chalk.blueBright.bold(this.getDiff()), ...args)
|
||||
info(...arguments_: unknown[]): void {
|
||||
console.info(chalk.blueBright.bold(this.getDiff()), ...arguments_)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,8 +71,8 @@ class Log {
|
|||
*
|
||||
* @param args The information you want to provide to the user
|
||||
*/
|
||||
warning(...args: unknown[]): void {
|
||||
console.warn(chalk.yellowBright.bold(' WARNING'), ...args)
|
||||
warning(...arguments_: unknown[]): void {
|
||||
console.warn(chalk.yellowBright.bold(' WARNING'), ...arguments_)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,8 +81,8 @@ class Log {
|
|||
*
|
||||
* @param args The information you want to provide to the user
|
||||
*/
|
||||
async hardWarning(...args: unknown[]): Promise<void> {
|
||||
console.info('', chalk.bgRed.bold('WARNING'), ...args)
|
||||
async hardWarning(...arguments_: unknown[]): Promise<void> {
|
||||
console.info('', chalk.bgRed.bold('WARNING'), ...arguments_)
|
||||
|
||||
const { answer } = await prompts({
|
||||
type: 'confirm',
|
||||
|
@ -95,9 +98,12 @@ class Log {
|
|||
*
|
||||
* @param args The information you want to provide to the user
|
||||
*/
|
||||
success(...args: unknown[]): void {
|
||||
success(...arguments_: unknown[]): void {
|
||||
console.log()
|
||||
console.log(`\n${chalk.greenBright.bold('SUCCESS')}`, args.join('\n\t'))
|
||||
console.log(
|
||||
`\n${chalk.greenBright.bold('SUCCESS')}`,
|
||||
arguments_.join('\n\t')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,11 +111,11 @@ class Log {
|
|||
*
|
||||
* @param args The error you want to throw or a type that you want to convert to an error
|
||||
*/
|
||||
error(...args: (Error | unknown)[]): never {
|
||||
throw args[0] instanceof Error
|
||||
? args[0]
|
||||
error(...arguments_: (Error | unknown)[]): never {
|
||||
throw arguments_[0] instanceof Error
|
||||
? arguments_[0]
|
||||
: new Error(
|
||||
...args.map((a) =>
|
||||
...arguments_.map((a) =>
|
||||
typeof a !== 'undefined' ? (a as object).toString() : a
|
||||
)
|
||||
)
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* Responsible for checking if all new patches have been applied
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { log } from '../log'
|
||||
import { MELON_DIR, SRC_DIR } from '../constants'
|
||||
import { walkDirectory } from '../utils'
|
||||
|
@ -14,14 +14,12 @@ import { walkDirectory } from '../utils'
|
|||
export const patchCountFile = resolve(MELON_DIR, 'patchCount')
|
||||
|
||||
export const patchCheck = async (): Promise<void> => {
|
||||
const fileList = (await walkDirectory(resolve(SRC_DIR))).filter((file) =>
|
||||
file.endsWith('.patch')
|
||||
)
|
||||
const directoryCotnents = await walkDirectory(resolve(SRC_DIR))
|
||||
|
||||
const fileList = directoryCotnents.filter((file) => file.endsWith('.patch'))
|
||||
const patchCount = fileList.length
|
||||
|
||||
if (!existsSync(patchCountFile)) {
|
||||
writeFileSync(patchCountFile, '0')
|
||||
}
|
||||
if (!existsSync(patchCountFile)) writeFileSync(patchCountFile, '0')
|
||||
|
||||
const recordedPatchCount = Number(readFileSync(patchCountFile).toString())
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { writeFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { writeFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { MELON_DIR } from '../constants'
|
||||
|
||||
/**
|
|
@ -15,9 +15,9 @@ export const updateCheck = async (): Promise<void> => {
|
|||
log.warning(
|
||||
`Latest version of Firefox (${version}) does not match frozen version (${firefoxVersion}).`
|
||||
)
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.warning(`Failed to check for updates.`)
|
||||
log.askForReport()
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
}
|
||||
}
|
||||
|
|
2
src/types.d.ts
vendored
2
src/types.d.ts
vendored
|
@ -11,7 +11,7 @@ export interface Cmd {
|
|||
* writing, is getting a touch long
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
requestController: () => Promise<(...args: any) => void>
|
||||
requestController: () => Promise<(...arguments_: any) => void>
|
||||
|
||||
options?: CmdOption[]
|
||||
aliases?: string[]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { readFile } from 'fs/promises'
|
||||
import { createHash } from 'crypto'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { readItem, writeItem } from './store'
|
||||
|
||||
/**
|
|
@ -21,9 +21,9 @@
|
|||
// Adapted from the `command-exists` node module
|
||||
// https://github.com/mathisonian/command-exists
|
||||
|
||||
import { execSync } from 'child_process'
|
||||
import { accessSync, constants } from 'fs'
|
||||
import path from 'path'
|
||||
import { execSync } from 'node:child_process'
|
||||
import { accessSync, constants } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
const onWindows = process.platform == 'win32'
|
||||
|
||||
|
@ -31,7 +31,7 @@ const fileNotExistsSync = (commandName: string): boolean => {
|
|||
try {
|
||||
accessSync(commandName, constants.F_OK)
|
||||
return false
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ const localExecutableSync = (commandName: string): boolean => {
|
|||
try {
|
||||
accessSync(commandName, constants.F_OK | constants.X_OK)
|
||||
return true
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ const commandExistsUnixSync = function (
|
|||
'; exit 0; }'
|
||||
)
|
||||
return !!stdout
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ const commandExistsWindowsSync = function (
|
|||
): boolean {
|
||||
// Regex from Julio from: https://stackoverflow.com/questions/51494579/regex-windows-path-validator
|
||||
if (
|
||||
!/^(?!(?:.*\s|.*\.|\W+)$)(?:[a-zA-Z]:)?(?:(?:[^<>:"|?*\n])+(?:\/\/|\/|\\\\|\\)?)+$/m.test(
|
||||
!/^(?!(?:.*\s|.*\.|\W+)$)(?:[A-Za-z]:)?(?:[^\n"*:<>?|]+(?:\/\/|\/|\\\\|\\)?)+$/m.test(
|
||||
commandName
|
||||
)
|
||||
) {
|
||||
|
@ -82,7 +82,7 @@ const commandExistsWindowsSync = function (
|
|||
try {
|
||||
const stdout = execSync('where ' + cleanedCommandName, { stdio: [] })
|
||||
return !!stdout
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ function cleanInput(toBeCleaned: string): string {
|
|||
// Windows has a different cleaning process to Unix, so we should go through
|
||||
// that process first
|
||||
if (onWindows) {
|
||||
const isPathName = /[\\]/.test(toBeCleaned)
|
||||
const isPathName = /\\/.test(toBeCleaned)
|
||||
if (isPathName) {
|
||||
const dirname = '"' + path.dirname(toBeCleaned) + '"'
|
||||
const basename = '"' + path.basename(toBeCleaned) + '"'
|
||||
|
@ -102,7 +102,7 @@ function cleanInput(toBeCleaned: string): string {
|
|||
}
|
||||
|
||||
// Otherwise go through the unix cleaning process
|
||||
if (/[^A-Za-z0-9_\\/:=-]/.test(toBeCleaned)) {
|
||||
if (/[^\w/:=\\-]/.test(toBeCleaned)) {
|
||||
toBeCleaned = "'" + toBeCleaned.replace(/'/g, "'\\''") + "'"
|
||||
toBeCleaned = toBeCleaned
|
||||
.replace(/^(?:'')+/g, '') // unduplicate single-quote at the beginning
|
||||
|
@ -114,9 +114,5 @@ function cleanInput(toBeCleaned: string): string {
|
|||
|
||||
export function commandExistsSync(commandName: string): boolean {
|
||||
const cleanedCommandName = cleanInput(commandName)
|
||||
if (onWindows) {
|
||||
return commandExistsWindowsSync(commandName, cleanedCommandName)
|
||||
} else {
|
||||
return commandExistsUnixSync(commandName, cleanedCommandName)
|
||||
}
|
||||
return onWindows ? commandExistsWindowsSync(commandName, cleanedCommandName) : commandExistsUnixSync(commandName, cleanedCommandName);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||
import {
|
||||
configPath,
|
||||
defaultConfig,
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
* Responsible for loading, parsing and checking the config file for melon
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { BIN_NAME } from '../constants'
|
||||
|
||||
import { log } from '../log'
|
||||
|
||||
export const projectDir = process.cwd()
|
||||
export const configPath = join(projectDir, 'gluon.json')
|
||||
export const projectDirectory = process.cwd()
|
||||
export const configPath = join(projectDirectory, 'gluon.json')
|
||||
|
||||
let hasWarnedAboutConfig = false
|
||||
|
||||
export enum SupportedProducts {
|
||||
Firefox = 'firefox',
|
||||
FirefoxESR = 'firefox-esr',
|
||||
FirefoxDev = 'firefox-dev',
|
||||
FirefoxDevelopment = 'firefox-dev',
|
||||
FirefoxBeta = 'firefox-beta',
|
||||
FirefoxNightly = 'firefox-nightly',
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export enum SupportedProducts {
|
|||
export const validProducts = [
|
||||
SupportedProducts.Firefox,
|
||||
SupportedProducts.FirefoxESR,
|
||||
SupportedProducts.FirefoxDev,
|
||||
SupportedProducts.FirefoxDevelopment,
|
||||
SupportedProducts.FirefoxBeta,
|
||||
SupportedProducts.FirefoxNightly,
|
||||
]
|
||||
|
@ -216,10 +216,10 @@ export function getConfig(): Config {
|
|||
try {
|
||||
// Try to parse the contents of the file. May not be valid JSON
|
||||
fileParsed = JSON.parse(fileContents)
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
// Report the error to the user
|
||||
log.error(`Error parsing ${BIN_NAME} config file located at ${configPath}`)
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ export function getConfig(): Config {
|
|||
}
|
||||
|
||||
export function saveConfig() {
|
||||
writeFileSync(configPath, JSON.stringify(config, null, 2))
|
||||
writeFileSync(configPath, JSON.stringify(config, undefined, 2))
|
||||
}
|
||||
|
||||
export const config = getConfig()
|
||||
|
|
|
@ -36,26 +36,29 @@ export const configDispatch = (
|
|||
if (config?.shell) {
|
||||
switch (config.shell) {
|
||||
// Don't change anything if we are using the default shell
|
||||
case 'default':
|
||||
case 'default': {
|
||||
break
|
||||
}
|
||||
|
||||
case 'unix':
|
||||
case 'unix': {
|
||||
// Bash path provides a unix shell on windows
|
||||
shell = BASH_PATH || false
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
default: {
|
||||
log.error(`dispatch() does not understand the shell '${shell}'`)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handle = (data: string | Error, killOnError?: boolean) => {
|
||||
const d = data.toString()
|
||||
const dataAsString = data.toString()
|
||||
|
||||
d.split('\n').forEach((line: string) => {
|
||||
if (line.length !== 0) logger(removeTimestamp(line))
|
||||
})
|
||||
for (const line of dataAsString.split('\n')) {
|
||||
if (line.length > 0) logger(removeTimestamp(line))
|
||||
}
|
||||
|
||||
if (killOnError) {
|
||||
log.error('Command failed. See error above.')
|
||||
|
@ -67,7 +70,7 @@ export const configDispatch = (
|
|||
cwd: config?.cwd || process.cwd(),
|
||||
shell: shell,
|
||||
env: {
|
||||
...(config?.env || {}),
|
||||
...config?.env,
|
||||
...process.env,
|
||||
},
|
||||
})
|
||||
|
@ -89,13 +92,13 @@ export const configDispatch = (
|
|||
*/
|
||||
export const dispatch = (
|
||||
cmd: string,
|
||||
args?: string[],
|
||||
arguments_?: string[],
|
||||
cwd?: string,
|
||||
killOnError?: boolean,
|
||||
logger = (data: string) => log.info(data)
|
||||
): Promise<boolean> => {
|
||||
return configDispatch(cmd, {
|
||||
args: args,
|
||||
args: arguments_,
|
||||
cwd: cwd,
|
||||
killOnError: killOnError,
|
||||
logger: logger,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { createWriteStream } from 'fs'
|
||||
import { createWriteStream } from 'node:fs'
|
||||
|
||||
import axios from 'axios'
|
||||
import cliProgress from 'cli-progress'
|
||||
import { Duplex } from 'stream'
|
||||
import { Duplex } from 'node:stream'
|
||||
import { log } from '../log'
|
||||
|
||||
export async function downloadFileToLocation(
|
||||
|
@ -44,11 +44,11 @@ export async function downloadFileToLocation(
|
|||
receivedBytes += chunk.length
|
||||
})
|
||||
data.pipe(writer)
|
||||
data.on('error', (err: unknown) => {
|
||||
data.on('error', (error: unknown) => {
|
||||
log.warning(
|
||||
`An error occured whilst downloading ${url}. It might be ignored`
|
||||
)
|
||||
reject(err)
|
||||
reject(error)
|
||||
})
|
||||
|
||||
const progressInterval = setInterval(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as dynamicConfig from './dynamicConfig'
|
||||
import * as dynamicConfig from './dynamic-config'
|
||||
import { readItem, removeItem } from './store'
|
||||
|
||||
describe('set', () => {
|
|
@ -2,12 +2,12 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import chalk from 'chalk'
|
||||
import { readFileSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { MELON_DIR } from '../constants'
|
||||
import { log } from '../log'
|
||||
|
||||
export const errorHandler = (err: Error, isUnhandledRej: boolean): void => {
|
||||
export const errorHandler = (error: Error, isUnhandledRej: boolean): never => {
|
||||
let cc = readFileSync(resolve(MELON_DIR, 'command')).toString()
|
||||
cc = cc.replace(/(\r\n|\n|\r)/gm, '')
|
||||
|
||||
|
@ -21,11 +21,11 @@ export const errorHandler = (err: Error, isUnhandledRej: boolean): void => {
|
|||
console.log(
|
||||
`\n\t`,
|
||||
isUnhandledRej
|
||||
? err.toString().replace(/\n/g, '\n\t ')
|
||||
: err.message.replace(/\n/g, '\n\t ')
|
||||
? error.toString().replace(/\n/g, '\n\t ')
|
||||
: error.message.replace(/\n/g, '\n\t ')
|
||||
)
|
||||
if (err.stack || isUnhandledRej) {
|
||||
const stack: string[] | undefined = err.stack?.split('\n')
|
||||
if (error.stack || isUnhandledRej) {
|
||||
const stack: string[] | undefined = error.stack?.split('\n')
|
||||
|
||||
if (!stack) return
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import {
|
|||
openSync,
|
||||
rmSync,
|
||||
writeSync,
|
||||
} from 'fs'
|
||||
import { mkdir, readdir, stat, symlink } from 'fs/promises'
|
||||
import { join, isAbsolute, dirname, relative } from 'path'
|
||||
} from 'node:fs'
|
||||
import { mkdir, readdir, stat } from 'node:fs/promises'
|
||||
import { join, isAbsolute } from 'node:path'
|
||||
|
||||
import { log } from '../log'
|
||||
|
||||
|
@ -24,19 +24,19 @@ import { log } from '../log'
|
|||
export const windowsPathToUnix = (path: string): string =>
|
||||
process.platform == 'win32' ? path.replace(/\\/g, '/') : path
|
||||
|
||||
export async function walkDirectory(dirName: string): Promise<string[]> {
|
||||
export async function walkDirectory(directory: string): Promise<string[]> {
|
||||
const output = []
|
||||
|
||||
if (!isAbsolute(dirName)) {
|
||||
if (!isAbsolute(directory)) {
|
||||
log.askForReport()
|
||||
log.error('Please provide an absolute input to walkDirectory')
|
||||
}
|
||||
|
||||
try {
|
||||
const directoryContents = await readdir(dirName)
|
||||
const directoryContents = await readdir(directory)
|
||||
|
||||
for (const file of directoryContents) {
|
||||
const fullPath = join(dirName, file)
|
||||
const fullPath = join(directory, file)
|
||||
const fStat = await stat(fullPath)
|
||||
|
||||
if (fStat.isDirectory()) {
|
||||
|
@ -47,9 +47,9 @@ export async function walkDirectory(dirName: string): Promise<string[]> {
|
|||
output.push(fullPath)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.askForReport()
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
}
|
||||
|
||||
return output
|
||||
|
@ -57,21 +57,21 @@ export async function walkDirectory(dirName: string): Promise<string[]> {
|
|||
|
||||
export type TreeType = { [property: string]: string[] | TreeType }
|
||||
|
||||
export async function walkDirectoryTree(dirName: string): Promise<TreeType> {
|
||||
export async function walkDirectoryTree(directory: string): Promise<TreeType> {
|
||||
const output: TreeType = {}
|
||||
|
||||
if (!isAbsolute(dirName)) {
|
||||
if (!isAbsolute(directory)) {
|
||||
log.askForReport()
|
||||
log.error('Please provide an absolute input to walkDirectory')
|
||||
}
|
||||
|
||||
try {
|
||||
const directoryContents = await readdir(dirName)
|
||||
const directoryContents = await readdir(directory)
|
||||
|
||||
const currentOut = []
|
||||
|
||||
for (const file of directoryContents) {
|
||||
const fullPath = join(dirName, file)
|
||||
const fullPath = join(directory, file)
|
||||
const fStat = await stat(fullPath)
|
||||
|
||||
if (fStat.isDirectory()) {
|
||||
|
@ -82,26 +82,26 @@ export async function walkDirectoryTree(dirName: string): Promise<TreeType> {
|
|||
}
|
||||
|
||||
output['.'] = currentOut
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.askForReport()
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
export async function ensureDir(dirName: string): Promise<void> {
|
||||
if (!existsSync(dirName)) {
|
||||
await mkdirp(dirName)
|
||||
export async function ensureDirectory(directory: string): Promise<void> {
|
||||
if (!existsSync(directory)) {
|
||||
await mkdirp(directory)
|
||||
}
|
||||
}
|
||||
|
||||
export function mkdirp(dirName: string): Promise<string | undefined> {
|
||||
return mkdir(dirName, { recursive: true })
|
||||
export function mkdirp(directory: string): Promise<string | undefined> {
|
||||
return mkdir(directory, { recursive: true })
|
||||
}
|
||||
|
||||
export function mkdirpSync(dirName: string): string | undefined {
|
||||
return mkdirSync(dirName, { recursive: true })
|
||||
export function mkdirpSync(directory: string): string | undefined {
|
||||
return mkdirSync(directory, { recursive: true })
|
||||
}
|
||||
|
||||
export function appendToFileSync(fileName: string, content: string): void {
|
||||
|
@ -110,58 +110,6 @@ export function appendToFileSync(fileName: string, content: string): void {
|
|||
closeSync(file)
|
||||
}
|
||||
|
||||
export async function createSymlink(
|
||||
srcPath: string,
|
||||
destPath: string,
|
||||
type?: string
|
||||
): Promise<void> {
|
||||
if (existsSync(destPath)) return
|
||||
|
||||
const { toDest: src } = symlinkPaths(srcPath, destPath)
|
||||
|
||||
const dir = dirname(destPath)
|
||||
const exists = existsSync(dir)
|
||||
if (exists) return await symlink(src, destPath, type)
|
||||
await mkdirp(dir)
|
||||
return await symlink(src, destPath, type)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapted from fs-extra
|
||||
* @param srcPath
|
||||
* @param destPath
|
||||
* @returns
|
||||
*/
|
||||
export function symlinkPaths(
|
||||
srcPath: string,
|
||||
destPath: string
|
||||
): { toCwd: string; toDest: string } {
|
||||
if (isAbsolute(srcPath)) {
|
||||
if (!existsSync(srcPath)) throw new Error('absolute srcpath does not exist')
|
||||
|
||||
return {
|
||||
toCwd: srcPath,
|
||||
toDest: srcPath,
|
||||
}
|
||||
} else {
|
||||
const dstdir = dirname(destPath)
|
||||
const relativeToDst = join(dstdir, srcPath)
|
||||
if (existsSync(relativeToDst))
|
||||
return {
|
||||
toCwd: relativeToDst,
|
||||
toDest: srcPath,
|
||||
}
|
||||
else {
|
||||
if (!existsSync(srcPath))
|
||||
throw new Error('relative srcpath does not exist')
|
||||
return {
|
||||
toCwd: srcPath,
|
||||
toDest: relative(dstdir, srcPath),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function filesExist(files: string[]): boolean {
|
||||
return files.every((file) => existsSync(file))
|
||||
}
|
||||
|
@ -175,5 +123,6 @@ export function ensureEmpty(path: string) {
|
|||
}
|
||||
|
||||
export async function getSize(path: string): Promise<number> {
|
||||
return (await stat(path)).size
|
||||
const fileInfo = await stat(path)
|
||||
return fileInfo.size
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
export * from './commandExists'
|
||||
export * from './changeTracking'
|
||||
export * from './command-exists'
|
||||
export * from './change-tracking'
|
||||
export * from './delay'
|
||||
export * from './dispatch'
|
||||
export * from './error-handler'
|
||||
export * from './version'
|
||||
export * from './config'
|
||||
export * from './stringTemplate'
|
||||
export * from './string-template'
|
||||
export * from './fs'
|
||||
export * from './versionFormatter'
|
||||
export * as dynamicConfig from './dynamicConfig'
|
||||
export * from './version-formatter'
|
||||
export * as dynamicConfig from './dynamic-config'
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { equip, None, OptionEquipped } from 'rustic'
|
||||
|
||||
import { MELON_DIR } from '../constants'
|
||||
|
||||
export const readItem = <T>(key: string): OptionEquipped<T> => {
|
||||
const dir = join(MELON_DIR, `${key}.json`)
|
||||
const fileLocation = join(MELON_DIR, `${key}.json`)
|
||||
|
||||
if (!existsSync(dir)) {
|
||||
if (!existsSync(fileLocation)) {
|
||||
return equip<T>(None)
|
||||
}
|
||||
|
||||
const data = readFileSync(dir).toString()
|
||||
const data = readFileSync(fileLocation).toString()
|
||||
|
||||
return equip(JSON.parse(data))
|
||||
}
|
||||
|
||||
export const writeItem = <T>(key: string, data: T) => {
|
||||
const dir = join(MELON_DIR, `${key}.json`)
|
||||
writeFileSync(dir, JSON.stringify(data, null, 2))
|
||||
const fileLocation = join(MELON_DIR, `${key}.json`)
|
||||
writeFileSync(fileLocation, JSON.stringify(data, undefined, 2))
|
||||
}
|
||||
|
||||
export const removeItem = (key: string) => {
|
||||
|
|
|
@ -8,15 +8,15 @@ export function stringTemplate(
|
|||
template: string,
|
||||
variables: { [key: string]: string | number }
|
||||
): string {
|
||||
let temp = template
|
||||
let temporary = template
|
||||
|
||||
for (const variable in variables) {
|
||||
// Replace only replaces the first instance of a string. We want to
|
||||
// replace all instances
|
||||
while (temp.includes(`\${${variable}}`)) {
|
||||
temp = temp.replace(`\${${variable}}`, variables[variable].toString())
|
||||
while (temporary.includes(`\${${variable}}`)) {
|
||||
temporary = temporary.replace(`\${${variable}}`, variables[variable].toString())
|
||||
}
|
||||
}
|
||||
|
||||
return temp
|
||||
return temporary
|
||||
}
|
|
@ -15,10 +15,10 @@ export interface Task {
|
|||
export class TaskList {
|
||||
tasks: Task[]
|
||||
loggingStyle: LoggingMode = 'normal'
|
||||
loggingIndentation: string = ''
|
||||
loggingIndentation = ''
|
||||
loggingOnError: LoggingErrorMode = 'throw'
|
||||
|
||||
error: Error | null = null
|
||||
error?: Error
|
||||
|
||||
constructor(tasks: Task[]) {
|
||||
this.tasks = tasks
|
||||
|
@ -49,22 +49,27 @@ export class TaskList {
|
|||
const prefixTemplate = `[${type.toUpperCase()}]`
|
||||
|
||||
switch (type) {
|
||||
case 'start':
|
||||
case 'start': {
|
||||
prefix += kleur.bold().gray(prefixTemplate)
|
||||
break
|
||||
case 'finish':
|
||||
}
|
||||
case 'finish': {
|
||||
prefix += kleur.bold().green(prefixTemplate)
|
||||
break
|
||||
case 'fail':
|
||||
}
|
||||
case 'fail': {
|
||||
prefix += kleur.bold().red(prefixTemplate)
|
||||
break
|
||||
case 'skip':
|
||||
}
|
||||
case 'skip': {
|
||||
prefix += kleur.bold().yellow(prefixTemplate)
|
||||
break
|
||||
case 'info':
|
||||
}
|
||||
case 'info': {
|
||||
prefix += ' '
|
||||
prefix += kleur.bold().cyan(prefixTemplate)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`${prefix} ${name}`)
|
||||
|
@ -94,17 +99,17 @@ export class TaskList {
|
|||
|
||||
await result.indent(this.loggingIndentation + ' ').run()
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
if (this.loggingOnError == 'throw') {
|
||||
this.log('fail', task.name)
|
||||
throw e
|
||||
throw error
|
||||
}
|
||||
|
||||
if (this.loggingOnError == 'inline') {
|
||||
this.log('fail', `${task.name}: ${e}`)
|
||||
this.log('fail', `${task.name}: ${error}`)
|
||||
}
|
||||
|
||||
this.error = e as Error
|
||||
this.error = error as Error
|
||||
}
|
||||
|
||||
this.log('finish', task.name)
|
|
@ -7,8 +7,8 @@ export const versionFormatter = (
|
|||
options: ({ name: string; value: string } | null | string)[]
|
||||
): string => {
|
||||
const spacesValue = Math.max(
|
||||
...options.map((arg) =>
|
||||
typeof arg === 'string' ? 0 : arg?.value?.length || 0
|
||||
...options.map((argument) =>
|
||||
typeof argument === 'string' ? 0 : argument?.value?.length || 0
|
||||
)
|
||||
)
|
||||
|
|
@ -8,7 +8,7 @@ import { SupportedProducts } from './config'
|
|||
const firefoxTargets = JSON.parse(`{
|
||||
"${SupportedProducts.Firefox}": "LATEST_FIREFOX_VERSION",
|
||||
"${SupportedProducts.FirefoxBeta}": "LATEST_FIREFOX_DEVEL_VERSION",
|
||||
"${SupportedProducts.FirefoxDev}": "FIREFOX_DEVEDITION",
|
||||
"${SupportedProducts.FirefoxDevelopment}": "FIREFOX_DEVEDITION",
|
||||
"${SupportedProducts.FirefoxESR}": "FIREFOX_ESR",
|
||||
"${SupportedProducts.FirefoxNightly}": "FIREFOX_NIGHTLY"
|
||||
}`)
|
||||
|
@ -22,9 +22,9 @@ export const getLatestFF = async (
|
|||
)
|
||||
|
||||
return data[firefoxTargets[product]]
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
log.warning('Failed to get latest firefox version with error:')
|
||||
log.error(e)
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
|
|
177
yarn.lock
177
yarn.lock
|
@ -127,6 +127,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
|
||||
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.19.1":
|
||||
version "7.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
|
||||
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
|
||||
|
||||
"@babel/helper-validator-option@^7.18.6":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
|
||||
|
@ -1114,6 +1119,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
|
||||
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
|
||||
integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
|
||||
|
||||
"@types/picomatch@^2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003"
|
||||
|
@ -1525,6 +1535,11 @@ buffer@^5.2.0, buffer@^5.5.0:
|
|||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
builtin-modules@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
||||
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
|
@ -1577,11 +1592,23 @@ ci-info@^3.2.0:
|
|||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
|
||||
integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==
|
||||
|
||||
ci-info@^3.4.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f"
|
||||
integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==
|
||||
|
||||
cjs-module-lexer@^1.0.0:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
|
||||
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
||||
|
||||
clean-regexp@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7"
|
||||
integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
cli-progress@^3.9.1:
|
||||
version "3.11.2"
|
||||
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77"
|
||||
|
@ -1863,6 +1890,26 @@ escodegen@^2.0.0:
|
|||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-plugin-unicorn@^44.0.2:
|
||||
version "44.0.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz#6324a001c0a5e2ac00fb51b30db27d14c6c36ab3"
|
||||
integrity sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
ci-info "^3.4.0"
|
||||
clean-regexp "^1.0.0"
|
||||
eslint-utils "^3.0.0"
|
||||
esquery "^1.4.0"
|
||||
indent-string "^4.0.0"
|
||||
is-builtin-module "^3.2.0"
|
||||
lodash "^4.17.21"
|
||||
pluralize "^8.0.0"
|
||||
read-pkg-up "^7.0.1"
|
||||
regexp-tree "^0.1.24"
|
||||
safe-regex "^2.1.1"
|
||||
semver "^7.3.7"
|
||||
strip-indent "^3.0.0"
|
||||
|
||||
eslint-scope@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
|
@ -2271,6 +2318,11 @@ has@^1.0.3:
|
|||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||
|
||||
html-encoding-sniffer@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
|
||||
|
@ -2350,6 +2402,11 @@ imurmurhash@^0.1.4:
|
|||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
|
||||
indent-string@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
|
||||
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
|
@ -2387,6 +2444,13 @@ is-arrayish@^0.3.1:
|
|||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||
|
||||
is-builtin-module@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.0.tgz#bb0310dfe881f144ca83f30100ceb10cf58835e0"
|
||||
integrity sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==
|
||||
dependencies:
|
||||
builtin-modules "^3.3.0"
|
||||
|
||||
is-core-module@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||
|
@ -3071,7 +3135,7 @@ lodash.merge@^4.6.2:
|
|||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash@^4.7.0:
|
||||
lodash@^4.17.21, lodash@^4.7.0:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
@ -3154,6 +3218,11 @@ min-document@^2.19.0:
|
|||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
min-indent@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
|
||||
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
||||
|
||||
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
|
@ -3228,6 +3297,16 @@ node-releases@^2.0.6:
|
|||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
|
||||
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
|
||||
|
||||
normalize-package-data@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
|
||||
dependencies:
|
||||
hosted-git-info "^2.1.4"
|
||||
resolve "^1.10.0"
|
||||
semver "2 || 3 || 4 || 5"
|
||||
validate-npm-package-license "^3.0.1"
|
||||
|
||||
normalize-path@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
|
@ -3342,7 +3421,7 @@ parse-headers@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
|
||||
integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
|
||||
|
||||
parse-json@^5.2.0:
|
||||
parse-json@^5.0.0, parse-json@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
|
||||
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
|
||||
|
@ -3416,6 +3495,11 @@ pkg-dir@^4.2.0:
|
|||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
pluralize@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
|
||||
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
|
||||
|
||||
png-to-ico@^2.1.4:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-2.1.4.tgz#0f14674c79e23bbd4367696b5852693edf28dbee"
|
||||
|
@ -3523,6 +3607,25 @@ react-is@^17.0.1:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
|
||||
read-pkg-up@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
|
||||
integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==
|
||||
dependencies:
|
||||
find-up "^4.1.0"
|
||||
read-pkg "^5.2.0"
|
||||
type-fest "^0.8.1"
|
||||
|
||||
read-pkg@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
|
||||
integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
|
||||
dependencies:
|
||||
"@types/normalize-package-data" "^2.4.0"
|
||||
normalize-package-data "^2.5.0"
|
||||
parse-json "^5.0.0"
|
||||
type-fest "^0.6.0"
|
||||
|
||||
readable-stream@^3.1.1, readable-stream@^3.4.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
|
@ -3537,6 +3640,11 @@ regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4:
|
|||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||
|
||||
regexp-tree@^0.1.24, regexp-tree@~0.1.1:
|
||||
version "0.1.24"
|
||||
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d"
|
||||
integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==
|
||||
|
||||
regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
|
@ -3569,7 +3677,7 @@ resolve.exports@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
|
||||
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
|
||||
|
||||
resolve@^1.20.0:
|
||||
resolve@^1.10.0, resolve@^1.20.0:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||
|
@ -3619,6 +3727,13 @@ safe-buffer@~5.1.1:
|
|||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-regex@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2"
|
||||
integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==
|
||||
dependencies:
|
||||
regexp-tree "~0.1.1"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
|
@ -3636,6 +3751,11 @@ saxes@^5.0.1:
|
|||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
"semver@2 || 3 || 4 || 5":
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7:
|
||||
version "7.3.7"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||
|
@ -3728,6 +3848,32 @@ source-map@^0.7.3:
|
|||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
|
||||
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
|
||||
dependencies:
|
||||
spdx-expression-parse "^3.0.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-exceptions@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
|
||||
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
|
||||
|
||||
spdx-expression-parse@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
|
||||
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
|
||||
dependencies:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-license-ids@^3.0.0:
|
||||
version "3.0.12"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779"
|
||||
integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
@ -3781,6 +3927,13 @@ strip-final-newline@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||
|
||||
strip-indent@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
|
||||
integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
|
||||
dependencies:
|
||||
min-indent "^1.0.0"
|
||||
|
||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
|
@ -3991,6 +4144,16 @@ type-fest@^0.21.3:
|
|||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
type-fest@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
|
||||
integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
|
||||
|
||||
type-fest@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
typedarray-to-buffer@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||
|
@ -4054,6 +4217,14 @@ v8-to-istanbul@^8.1.0:
|
|||
convert-source-map "^1.6.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
|
||||
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
|
||||
dependencies:
|
||||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
w3c-hr-time@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue