mirror of
https://github.com/zen-browser/surfer.git
synced 2025-07-08 01:10:03 +02:00
Merge reduce-packages
Assorted clean up
This commit is contained in:
commit
6b65704fdd
51 changed files with 924 additions and 833 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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
"main": "index.js",
|
||||
"reveal": true,
|
||||
"bin": {
|
||||
"melon": "./dist/index.js",
|
||||
"gluon": "./dist/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -46,18 +45,17 @@
|
|||
"commander": "^6.2.1",
|
||||
"execa": "^5.1.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"glob": "^7.1.7",
|
||||
"ini": "^3.0.0",
|
||||
"is-apple-silicon": "trickypr/is-apple-silicon",
|
||||
"listr": "^0.14.3",
|
||||
"kleur": "^4.1.5",
|
||||
"modern-async": "^1.1.2",
|
||||
"picomatch": "^2.3.1",
|
||||
"png-to-ico": "^2.1.4",
|
||||
"prompts": "^2.4.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rustic": "^1.2.1",
|
||||
"semver": "^7.3.7",
|
||||
"sharp": "^0.30.7",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"xmlbuilder2": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -75,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[] = [
|
||||
|
@ -115,7 +118,7 @@ export const commands: Cmd[] = [
|
|||
aliases: ['pack'],
|
||||
description: 'Package the browser for distribution.',
|
||||
requestController: async () =>
|
||||
(await import('./commands/package')).melonPackage,
|
||||
(await import('./commands/package')).gluonPackage,
|
||||
},
|
||||
{
|
||||
cmd: 'reset',
|
||||
|
|
|
@ -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'
|
||||
|
@ -33,7 +33,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'
|
||||
)
|
||||
|
@ -43,15 +43,15 @@ 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 = {
|
||||
name: config.name,
|
||||
vendor: config.name,
|
||||
appId: config.appId,
|
||||
brandingDir: existsSync(join(ENGINE_DIR, 'branding', 'melon'))
|
||||
? 'branding/melon'
|
||||
brandingDir: existsSync(join(ENGINE_DIR, 'branding', 'gluon'))
|
||||
? 'branding/gluon'
|
||||
: 'branding/unofficial',
|
||||
binName: config.binaryName,
|
||||
changeset,
|
||||
|
|
|
@ -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,31 +29,52 @@ export async function resolveAddonDownloadUrl(
|
|||
addon: AddonInfo
|
||||
): Promise<string> {
|
||||
switch (addon.platform) {
|
||||
case 'url':
|
||||
case 'url': {
|
||||
return addon.url
|
||||
}
|
||||
|
||||
case 'amo':
|
||||
return (
|
||||
await axios.get(
|
||||
case 'amo': {
|
||||
try {
|
||||
const mozillaData = await axios.get(
|
||||
`https://addons.mozilla.org/api/v4/addons/addon/${addon.amoId}/versions/`
|
||||
)
|
||||
).data.results[0].files[0].url
|
||||
|
||||
case 'github':
|
||||
return (
|
||||
(
|
||||
((
|
||||
await axios.get(
|
||||
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
||||
)
|
||||
).data.assets as {
|
||||
url: string
|
||||
browser_download_url: string
|
||||
name: string
|
||||
}[]) || []
|
||||
).find((asset) => isMatch(asset.name, addon.fileGlob))
|
||||
?.browser_download_url || 'failed'
|
||||
)
|
||||
return mozillaData.data.results[0].files[0].url
|
||||
} catch (error) {
|
||||
log.warning(
|
||||
'The following error occured whilst fetching amo addon metadata'
|
||||
)
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
case 'github': {
|
||||
try {
|
||||
const githubData = await axios.get(
|
||||
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
||||
)
|
||||
|
||||
return (
|
||||
(
|
||||
(githubData.data.assets as {
|
||||
url: string
|
||||
browser_download_url: string
|
||||
name: string
|
||||
}[]) || []
|
||||
).find((asset) => isMatch(asset.name, addon.fileGlob))
|
||||
?.browser_download_url || 'failed'
|
||||
)
|
||||
} catch (error) {
|
||||
log.warning(
|
||||
'The following error occured whilst fetching github metadata'
|
||||
)
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,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}`)
|
||||
|
||||
|
@ -73,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(
|
||||
|
@ -110,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 Listr, { ListrTask } from 'listr'
|
||||
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/task-list'
|
||||
|
||||
const ignoredFiles = new RegExp('.*\\.(json|patch|md|jpeg|png|gif|tiff|ico)')
|
||||
const licenseIgnore = new RegExp('(//|#) Ignore license in this file', 'g')
|
||||
|
@ -25,14 +25,14 @@ const fixableFiles = [
|
|||
commentClose: '\n -->',
|
||||
},
|
||||
{
|
||||
regex: new RegExp('.*\\.py|moz\\.build'),
|
||||
regex: new RegExp('.*\\.py|moz\\.build|jar\\.mn'),
|
||||
comment: '# ',
|
||||
commentClose: '\n',
|
||||
},
|
||||
]
|
||||
|
||||
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
|
||||
|
@ -53,57 +53,54 @@ export async function isValidLicense(path: string): Promise<boolean> {
|
|||
return hasLicense
|
||||
}
|
||||
|
||||
export function listrCheckFile(
|
||||
path: string,
|
||||
noFix: boolean
|
||||
): ListrTask<unknown> {
|
||||
export function createTask(path: string, noFix: boolean): Task {
|
||||
return {
|
||||
skip: () => ignoredFiles.test(path),
|
||||
title: path.replace(SRC_DIR, ''),
|
||||
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) {
|
||||
const fixable = fixableFiles.find(({ regex }) => regex.test(path))
|
||||
|
||||
if (!fixable || noFix) {
|
||||
throw new Error(
|
||||
`${path} does not have a license. Please add the source code header`
|
||||
)
|
||||
} else {
|
||||
const mpl = (
|
||||
await readFile(join(__dirname, 'license-check.txt'))
|
||||
).toString()
|
||||
const { comment, commentOpen, commentClose } = fixable
|
||||
let header = mpl
|
||||
.split('\n')
|
||||
.map((ln) => (comment || '') + ln)
|
||||
.join('\n')
|
||||
|
||||
if (commentOpen) {
|
||||
header = commentOpen + header + commentClose
|
||||
}
|
||||
|
||||
await writeFile(path, header + '\n' + contents.join('\n'))
|
||||
}
|
||||
if (hasLicense) {
|
||||
return
|
||||
}
|
||||
|
||||
const fixable = fixableFiles.find(({ regex }) => regex.test(path))
|
||||
|
||||
if (!fixable || noFix) {
|
||||
throw new Error(
|
||||
`${path} does not have a license. Please add the source code header`
|
||||
)
|
||||
}
|
||||
|
||||
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 = mplHeader
|
||||
.split('\n')
|
||||
.map((ln) => (comment || '') + ln)
|
||||
.join('\n')
|
||||
|
||||
if (commentOpen) {
|
||||
header = commentOpen + header + commentClose
|
||||
}
|
||||
|
||||
await writeFile(path, header + '\n' + contentsSplitNewline.join('\n'))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
interface Options {
|
||||
noFix: boolean
|
||||
fix: boolean
|
||||
}
|
||||
|
||||
export const licenseCheck = async (options: Options): Promise<void> => {
|
||||
const files = await walkDirectory(SRC_DIR)
|
||||
|
||||
await new Listr(
|
||||
files.map((file) => listrCheckFile(file, options.noFix)),
|
||||
{
|
||||
concurrent: true,
|
||||
exitOnError: false,
|
||||
}
|
||||
).run()
|
||||
await new TaskList(files.map((file) => createTask(file, !options.fix)))
|
||||
.onError('inline')
|
||||
.run()
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
@ -18,7 +18,7 @@ import { generateBrowserUpdateFiles } from './updates/browser'
|
|||
|
||||
const machPath = resolve(ENGINE_DIR, 'mach')
|
||||
|
||||
export const melonPackage = async () => {
|
||||
export const gluonPackage = async () => {
|
||||
const brandingKey = dynamicConfig.get('brand') as string
|
||||
const brandingDetails = config.brands[brandingKey]
|
||||
|
||||
|
@ -37,15 +37,15 @@ export const melonPackage = 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 melonPackage = 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 melonPackage = 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 '../setup-project'
|
||||
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,48 +1,45 @@
|
|||
// 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 { sync } from 'glob'
|
||||
import Listr from 'listr'
|
||||
import { ENGINE_DIR, SRC_DIR } from '../../constants'
|
||||
import { join } from 'node:path'
|
||||
import { existsSync } from 'node:fs'
|
||||
import glob from 'tiny-glob'
|
||||
|
||||
import * as gitPatch from './gitPatch'
|
||||
import * as copyPatch from './copyPatches'
|
||||
import * as brandingPatch from './brandingPatch'
|
||||
import { join } from 'path'
|
||||
import { existsSync, writeFileSync } from 'fs'
|
||||
import { ENGINE_DIR, SRC_DIR } from '../../constants'
|
||||
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 { log } from '../../log'
|
||||
import { templateDir } from '../setup-project'
|
||||
|
||||
type ListrTaskGroup = Listr.ListrTask<unknown>
|
||||
import { templateDirectory } from '../setup-project'
|
||||
import { Task, TaskList } from '../../utils/task-list'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
|
||||
export interface IMelonPatch {
|
||||
name: string
|
||||
skip?: (
|
||||
ctx: unknown
|
||||
) => string | boolean | void | Promise<string | boolean | undefined>
|
||||
skip?: () => boolean | Promise<boolean>
|
||||
}
|
||||
|
||||
function patchMethod<T extends IMelonPatch>(
|
||||
name: string,
|
||||
patches: T[],
|
||||
patchFn: (patch: T, index: number) => Promise<void>
|
||||
): ListrTaskGroup {
|
||||
patchFunction: (patch: T, index: number) => Promise<void>
|
||||
): Task {
|
||||
return {
|
||||
title: `Apply ${patches.length} ${name} patches`,
|
||||
name: `Apply ${patches.length} ${name} patches`,
|
||||
long: true,
|
||||
task: () =>
|
||||
new Listr(
|
||||
new TaskList(
|
||||
patches.map((patch, index) => ({
|
||||
title: `Apply ${patch.name}`,
|
||||
task: () => patchFn(patch, index),
|
||||
name: `Apply ${patch.name}`,
|
||||
task: () => patchFunction(patch, index),
|
||||
skip: patch.skip,
|
||||
}))
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
function importMelonPatches(): ListrTaskGroup {
|
||||
function importMelonPatches(): Task {
|
||||
return patchMethod(
|
||||
'branding',
|
||||
[
|
||||
|
@ -63,10 +60,10 @@ function importMelonPatches(): ListrTaskGroup {
|
|||
(await macosInstallerCheck) &&
|
||||
existsSync(join(ENGINE_DIR, 'browser/branding', name))
|
||||
) {
|
||||
return `${name} has already been applied`
|
||||
return true
|
||||
}
|
||||
|
||||
return
|
||||
return false
|
||||
},
|
||||
})) as brandingPatch.IBrandingPatch[]),
|
||||
],
|
||||
|
@ -74,20 +71,22 @@ function importMelonPatches(): ListrTaskGroup {
|
|||
)
|
||||
}
|
||||
|
||||
function importFolders(): ListrTaskGroup {
|
||||
async function importFolders(): Promise<Task> {
|
||||
return patchMethod(
|
||||
'folder',
|
||||
copyPatch.get(),
|
||||
await copyPatch.get(),
|
||||
async (patch) => await copyPatch.apply(patch.src)
|
||||
)
|
||||
}
|
||||
|
||||
function importGitPatch(): ListrTaskGroup {
|
||||
const patches = sync('**/*.patch', { nodir: true, cwd: SRC_DIR }).map(
|
||||
(path) => join(SRC_DIR, path)
|
||||
)
|
||||
async function importGitPatch(): Promise<Task> {
|
||||
let patches = await glob('**/*.patch', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
})
|
||||
patches = patches.map((path) => join(SRC_DIR, path))
|
||||
|
||||
writeFileSync(patchCountFile, patches.length.toString())
|
||||
await writeFile(patchCountFile, patches.length.toString())
|
||||
|
||||
return patchMethod<gitPatch.IGitPatch>(
|
||||
'git',
|
||||
|
@ -96,32 +95,28 @@ function importGitPatch(): ListrTaskGroup {
|
|||
)
|
||||
}
|
||||
|
||||
function importInternalPatch(): ListrTaskGroup {
|
||||
const patches = sync('*.patch', {
|
||||
nodir: true,
|
||||
cwd: join(templateDir, 'patches.optional'),
|
||||
}).map((path) => ({
|
||||
async function importInternalPatch(): Promise<Task> {
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
||||
export async function applyPatches(): Promise<void> {
|
||||
await new Listr(
|
||||
[
|
||||
importInternalPatch(),
|
||||
importMelonPatches(),
|
||||
importFolders(),
|
||||
importGitPatch(),
|
||||
],
|
||||
{
|
||||
renderer: log.isDebug ? 'verbose' : 'default',
|
||||
}
|
||||
).run()
|
||||
await new TaskList([
|
||||
await importInternalPatch(),
|
||||
importMelonPatches(),
|
||||
await importFolders(),
|
||||
await importGitPatch(),
|
||||
]).run()
|
||||
}
|
||||
|
|
|
@ -1,13 +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 { sync } from 'glob'
|
||||
import { existsSync } from 'fs'
|
||||
import { lstatSync, readFileSync } from 'fs'
|
||||
import { ensureSymlink } from 'fs-extra'
|
||||
import { copyFile } from 'fs/promises'
|
||||
import { dirname, resolve } from 'path'
|
||||
import rimraf from 'rimraf'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { lstatSync, readFileSync } from 'node:fs'
|
||||
import { ensureSymlink, remove } from 'fs-extra'
|
||||
import { copyFile } from 'node:fs/promises'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import glob from 'tiny-glob'
|
||||
|
||||
import { appendToFileSync, mkdirp } from '../../utils'
|
||||
import { config } from '../..'
|
||||
|
@ -26,7 +25,7 @@ export const copyManual = async (name: string): Promise<void> => {
|
|||
existsSync(resolve(ENGINE_DIR, ...getChunked(name))) &&
|
||||
!lstatSync(resolve(ENGINE_DIR, ...getChunked(name))).isSymbolicLink()
|
||||
) {
|
||||
rimraf.sync(resolve(ENGINE_DIR, ...getChunked(name)))
|
||||
await remove(resolve(ENGINE_DIR, ...getChunked(name)))
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -70,20 +69,21 @@ export interface ICopyPatch extends IMelonPatch {
|
|||
// =============================================================================
|
||||
// Exports
|
||||
|
||||
export function get(): ICopyPatch[] {
|
||||
const files = sync('**/*', {
|
||||
nodir: true,
|
||||
export async function get(): Promise<ICopyPatch[]> {
|
||||
const allFilesInSource = await glob('**/*', {
|
||||
filesOnly: true,
|
||||
cwd: SRC_DIR,
|
||||
}).filter(
|
||||
})
|
||||
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),
|
||||
|
@ -94,8 +94,8 @@ export function get(): 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'
|
||||
import { bin_name } from '..'
|
||||
|
@ -14,7 +14,7 @@ import {
|
|||
configPath,
|
||||
delay,
|
||||
getLatestFF,
|
||||
projectDir,
|
||||
projectDirectory,
|
||||
SupportedProducts,
|
||||
walkDirectory,
|
||||
} from '../utils'
|
||||
|
@ -50,19 +50,13 @@ export async function setupProject(): Promise<void> {
|
|||
{
|
||||
title: 'Firefox extended support (older)',
|
||||
description:
|
||||
'The oldest supported extended support release. Maximum security and stability, but will lose support sooner than the newer extended support release.',
|
||||
'The extended support version of Firefox. Will receive security updates for a longer period of time and less frequent, bigger, feature updates',
|
||||
value: SupportedProducts.FirefoxESR,
|
||||
},
|
||||
{
|
||||
title: 'Firefox extended support (newer)',
|
||||
description:
|
||||
'The latest extended support release. Releases around once every 8 stable cycles. Receives regular small security patches and bug fixes.',
|
||||
value: SupportedProducts.FirefoxESRNext,
|
||||
},
|
||||
{
|
||||
title: 'Firefox developer edition (Not recommended)',
|
||||
description: 'Tracks firefox beta, with a few config tweaks',
|
||||
value: SupportedProducts.FirefoxDev,
|
||||
value: SupportedProducts.FirefoxDevelopment,
|
||||
},
|
||||
{
|
||||
title: 'Firefox beta (Not recommended)',
|
||||
|
@ -153,10 +147,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)) {
|
||||
|
@ -174,48 +168,64 @@ export async function setupProject(): Promise<void> {
|
|||
`You can start downloading the Firefox source code by running |${bin_name} download|`,
|
||||
'Or you can follow the getting started guide at https://docs.gluon.dev/getting-started/overview/'
|
||||
)
|
||||
} catch (e) {
|
||||
log.error(e)
|
||||
} catch (error) {
|
||||
log.error(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,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 { existsSync } from 'node:fs'
|
||||
import { log } from '../log'
|
||||
import { ENGINE_DIR } from '../constants'
|
||||
import { BIN_NAME, ENGINE_DIR } from '../constants'
|
||||
import { dispatch, hasConfig } from '../utils'
|
||||
|
||||
export const status = async (): Promise<void> => {
|
||||
|
@ -12,7 +12,7 @@ export const status = async (): Promise<void> => {
|
|||
|
||||
if (!configExists && !engineExists) {
|
||||
log.info(
|
||||
"Melon doesn't appear to be setup for this project. You can set it up by running |melon setup-project|"
|
||||
`Gluon doesn't appear to be setup for this project. You can set it up by running |${BIN_NAME} setup-project|`
|
||||
)
|
||||
|
||||
return
|
||||
|
@ -25,7 +25,7 @@ export const status = async (): Promise<void> => {
|
|||
return
|
||||
} else {
|
||||
log.info(
|
||||
"It appears that melon has been configured, but you haven't run |melon download|"
|
||||
`It appears that ${BIN_NAME} has been configured, but you haven't run |${BIN_NAME} download|`
|
||||
)
|
||||
|
||||
return
|
||||
|
|
|
@ -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',
|
||||
FirefoxESRNext = 'firefox-esr-next',
|
||||
FirefoxDev = 'firefox-dev',
|
||||
FirefoxDevelopment = 'firefox-dev',
|
||||
FirefoxBeta = 'firefox-beta',
|
||||
FirefoxNightly = 'firefox-nightly',
|
||||
}
|
||||
|
@ -27,8 +27,7 @@ export enum SupportedProducts {
|
|||
export const validProducts = [
|
||||
SupportedProducts.Firefox,
|
||||
SupportedProducts.FirefoxESR,
|
||||
SupportedProducts.FirefoxESRNext,
|
||||
SupportedProducts.FirefoxDev,
|
||||
SupportedProducts.FirefoxDevelopment,
|
||||
SupportedProducts.FirefoxBeta,
|
||||
SupportedProducts.FirefoxNightly,
|
||||
]
|
||||
|
@ -214,10 +213,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 melon config file located at ${configPath}`)
|
||||
log.error(e)
|
||||
log.error(`Error parsing ${BIN_NAME} config file located at ${configPath}`)
|
||||
log.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
@ -293,7 +292,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,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 { 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(
|
||||
url: string,
|
||||
|
@ -43,7 +44,12 @@ export async function downloadFileToLocation(
|
|||
receivedBytes += chunk.length
|
||||
})
|
||||
data.pipe(writer)
|
||||
data.on('error', (err: unknown) => reject(err))
|
||||
data.on('error', (error: unknown) => {
|
||||
log.warning(
|
||||
`An error occured whilst downloading ${url}. It might be ignored`
|
||||
)
|
||||
reject(error)
|
||||
})
|
||||
|
||||
const progressInterval = setInterval(
|
||||
() => progressBar.update(receivedBytes),
|
||||
|
|
|
@ -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,13 +21,13 @@ 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
|
||||
if (!stack) process.exit(1)
|
||||
|
||||
stack.shift()
|
||||
stack.shift()
|
||||
|
|
|
@ -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
|
||||
}
|
122
src/utils/task-list.ts
Normal file
122
src/utils/task-list.ts
Normal file
|
@ -0,0 +1,122 @@
|
|||
import kleur from 'kleur'
|
||||
|
||||
export type LoggingMode = 'silent' | 'normal'
|
||||
export type LoggingErrorMode = 'inline' | 'throw'
|
||||
|
||||
export interface Task {
|
||||
name: string
|
||||
skip?: () => boolean | Promise<boolean>
|
||||
long?: boolean
|
||||
task: (
|
||||
log: (message: string) => void
|
||||
) => void | Promise<void> | TaskList | Promise<TaskList>
|
||||
}
|
||||
|
||||
export class TaskList {
|
||||
tasks: Task[]
|
||||
loggingStyle: LoggingMode = 'normal'
|
||||
loggingIndentation = ''
|
||||
loggingOnError: LoggingErrorMode = 'throw'
|
||||
|
||||
error?: Error
|
||||
|
||||
constructor(tasks: Task[]) {
|
||||
this.tasks = tasks
|
||||
}
|
||||
|
||||
style(style: LoggingMode) {
|
||||
this.loggingStyle = style
|
||||
return this
|
||||
}
|
||||
|
||||
indent(indentation: string) {
|
||||
this.loggingIndentation = indentation
|
||||
return this
|
||||
}
|
||||
|
||||
onError(mode: LoggingErrorMode) {
|
||||
this.loggingOnError = mode
|
||||
return this
|
||||
}
|
||||
|
||||
private log(
|
||||
type: 'start' | 'finish' | 'fail' | 'skip' | 'info',
|
||||
name: string
|
||||
) {
|
||||
if (this.loggingStyle == 'silent') return
|
||||
|
||||
let prefix = this.loggingIndentation
|
||||
const prefixTemplate = `[${type.toUpperCase()}]`
|
||||
|
||||
switch (type) {
|
||||
case 'start': {
|
||||
prefix += kleur.bold().gray(prefixTemplate)
|
||||
break
|
||||
}
|
||||
case 'finish': {
|
||||
prefix += kleur.bold().green(prefixTemplate)
|
||||
break
|
||||
}
|
||||
case 'fail': {
|
||||
prefix += kleur.bold().red(prefixTemplate)
|
||||
break
|
||||
}
|
||||
case 'skip': {
|
||||
prefix += kleur.bold().yellow(prefixTemplate)
|
||||
break
|
||||
}
|
||||
case 'info': {
|
||||
prefix += ' '
|
||||
prefix += kleur.bold().cyan(prefixTemplate)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`${prefix} ${name}`)
|
||||
}
|
||||
|
||||
async run() {
|
||||
for (const task of this.tasks) {
|
||||
if (task.skip && (await task.skip())) {
|
||||
this.log('skip', task.name)
|
||||
continue
|
||||
}
|
||||
|
||||
if (task.long) {
|
||||
this.log('start', task.name)
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await task.task((message: string) =>
|
||||
this.log('info', message)
|
||||
)
|
||||
|
||||
if (result instanceof TaskList) {
|
||||
// We want to provide a start point if none exists already
|
||||
if (!task.long) {
|
||||
this.log('start', task.name)
|
||||
}
|
||||
|
||||
await result.indent(this.loggingIndentation + ' ').run()
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.loggingOnError == 'throw') {
|
||||
this.log('fail', task.name)
|
||||
throw error
|
||||
}
|
||||
|
||||
if (this.loggingOnError == 'inline') {
|
||||
this.log('fail', `${task.name}: ${error}`)
|
||||
}
|
||||
|
||||
this.error = error as Error
|
||||
}
|
||||
|
||||
this.log('finish', task.name)
|
||||
}
|
||||
|
||||
if (this.error) {
|
||||
throw this.error
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
15
src/utils/version.test.ts
Normal file
15
src/utils/version.test.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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 { validProducts } from './config'
|
||||
import { getLatestFF } from './version'
|
||||
|
||||
const firefoxVersions = validProducts
|
||||
|
||||
describe('getLatestFF', () => {
|
||||
for (const firefoxVersion of firefoxVersions) {
|
||||
it(`returns the latest ${firefoxVersion} version`, async () =>
|
||||
expect(await getLatestFF(firefoxVersion)).toBeTruthy())
|
||||
}
|
||||
})
|
|
@ -2,23 +2,30 @@
|
|||
// 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 axios from 'axios'
|
||||
import { log } from '../log'
|
||||
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.FirefoxESRNext}": "FIREFOX_ESR_NEXT",
|
||||
"${SupportedProducts.FirefoxNightly}": "FIREFOX_NIGHTLY"
|
||||
}`)
|
||||
|
||||
export const getLatestFF = async (
|
||||
product: SupportedProducts = SupportedProducts.Firefox
|
||||
): Promise<string> => {
|
||||
const { data } = await axios.get(
|
||||
'https://product-details.mozilla.org/1.0/firefox_versions.json'
|
||||
)
|
||||
try {
|
||||
const { data } = await axios.get(
|
||||
'https://product-details.mozilla.org/1.0/firefox_versions.json'
|
||||
)
|
||||
|
||||
return data[firefoxTargets[product]]
|
||||
return data[firefoxTargets[product]]
|
||||
} catch (error) {
|
||||
log.warning('Failed to get latest firefox version with error:')
|
||||
log.error(error)
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# Melon build tool
|
498
yarn.lock
498
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"
|
||||
|
@ -963,13 +968,6 @@
|
|||
"@resvg/resvg-js-win32-ia32-msvc" "1.4.0"
|
||||
"@resvg/resvg-js-win32-x64-msvc" "1.4.0"
|
||||
|
||||
"@samverschueren/stream-to-observable@^0.3.0":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz#a21117b19ee9be70c379ec1877537ef2e1c63301"
|
||||
integrity sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==
|
||||
dependencies:
|
||||
any-observable "^0.3.0"
|
||||
|
||||
"@sinonjs/commons@^1.7.0":
|
||||
version "1.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
|
||||
|
@ -1102,9 +1100,9 @@
|
|||
integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
|
||||
|
||||
"@types/node@*":
|
||||
version "18.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.1.tgz#828e4785ccca13f44e2fb6852ae0ef11e3e20ba5"
|
||||
integrity sha512-z+2vB6yDt1fNwKOeGbckpmirO+VBDuQqecXkgeIqDlaOtmKn6hPR/viQ8cxCfqLU4fTlvM3+YjM367TukWdxpg==
|
||||
version "18.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.2.tgz#ffc5f0f099d27887c8d9067b54e55090fcd54126"
|
||||
integrity sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==
|
||||
|
||||
"@types/node@16.9.1":
|
||||
version "16.9.1"
|
||||
|
@ -1121,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"
|
||||
|
@ -1305,11 +1308,6 @@ ajv@^6.10.0, ajv@^6.12.4:
|
|||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-escapes@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
|
||||
integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
|
||||
|
||||
ansi-escapes@^4.2.1:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
||||
|
@ -1317,26 +1315,11 @@ ansi-escapes@^4.2.1:
|
|||
dependencies:
|
||||
type-fest "^0.21.3"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
|
||||
|
||||
ansi-regex@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
|
||||
integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
|
@ -1361,11 +1344,6 @@ any-base@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe"
|
||||
integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==
|
||||
|
||||
any-observable@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
|
||||
integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==
|
||||
|
||||
anymatch@^3.0.3:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
|
@ -1557,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"
|
||||
|
@ -1573,22 +1556,11 @@ camelcase@^6.2.0:
|
|||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
caniuse-lite@^1.0.30001370:
|
||||
version "1.0.30001370"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001370.tgz#0a30d4f20d38b9e108cc5ae7cc62df9fe66cd5ba"
|
||||
integrity sha512-3PDmaP56wz/qz7G508xzjx8C+MC2qEm4SYhSEzC9IBROo+dGXFWRuaXkWti0A9tuI00g+toiriVqxtWMgl350g==
|
||||
version "1.0.30001373"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be"
|
||||
integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==
|
||||
|
||||
chalk@^1.0.0, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.4.1:
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
|
@ -1620,17 +1592,22 @@ 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==
|
||||
|
||||
cli-cursor@^2.0.0, cli-cursor@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
|
||||
integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==
|
||||
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:
|
||||
restore-cursor "^2.0.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
cli-progress@^3.9.1:
|
||||
version "3.11.2"
|
||||
|
@ -1639,14 +1616,6 @@ cli-progress@^3.9.1:
|
|||
dependencies:
|
||||
string-width "^4.2.3"
|
||||
|
||||
cli-truncate@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
|
||||
integrity sha512-f4r4yJnbT++qUPI9NR4XLDLq41gQ+uqnPItWG0F5ZkehuNiTTa3EY0S4AqTSUOeJ7/zU41oWPQSNkW5BqPL9bg==
|
||||
dependencies:
|
||||
slice-ansi "0.0.4"
|
||||
string-width "^1.0.1"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
|
@ -1661,11 +1630,6 @@ co@^4.6.0:
|
|||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
|
||||
|
||||
code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
|
||||
|
||||
collect-v8-coverage@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
|
||||
|
@ -1780,11 +1744,6 @@ data-urls@^2.0.0:
|
|||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
date-fns@^1.27.2:
|
||||
version "1.30.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
|
||||
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
|
@ -1871,14 +1830,9 @@ domexception@^2.0.1:
|
|||
webidl-conversions "^5.0.0"
|
||||
|
||||
electron-to-chromium@^1.4.202:
|
||||
version "1.4.202"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.202.tgz#0c2ed733f42b02ec49a955c5badfcc65888c390b"
|
||||
integrity sha512-JYsK2ex9lmQD27kj19fhXYxzFJ/phLAkLKHv49A5UY6kMRV2xED3qMMLg/voW/+0AR6wMiI+VxlmK9NDtdxlPA==
|
||||
|
||||
elegant-spinner@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
|
||||
integrity sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==
|
||||
version "1.4.206"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4"
|
||||
integrity sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==
|
||||
|
||||
emittery@^0.8.1:
|
||||
version "0.8.1"
|
||||
|
@ -1909,7 +1863,7 @@ escalade@^3.1.1:
|
|||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
|
||||
|
@ -1936,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"
|
||||
|
@ -2133,21 +2107,6 @@ fb-watchman@^2.0.0:
|
|||
dependencies:
|
||||
bser "2.1.1"
|
||||
|
||||
figures@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
|
||||
integrity sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
figures@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
||||
integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
file-entry-cache@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
|
||||
|
@ -2283,7 +2242,7 @@ glob-parent@^6.0.1:
|
|||
dependencies:
|
||||
is-glob "^4.0.3"
|
||||
|
||||
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7:
|
||||
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
||||
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
|
||||
|
@ -2315,6 +2274,11 @@ globals@^13.15.0:
|
|||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globalyzer@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465"
|
||||
integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==
|
||||
|
||||
globby@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
|
||||
|
@ -2327,18 +2291,16 @@ globby@^11.1.0:
|
|||
merge2 "^1.4.1"
|
||||
slash "^3.0.0"
|
||||
|
||||
globrex@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9:
|
||||
version "4.2.10"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
|
@ -2356,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"
|
||||
|
@ -2435,10 +2402,10 @@ imurmurhash@^0.1.4:
|
|||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
|
||||
indent-string@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
|
||||
integrity sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==
|
||||
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"
|
||||
|
@ -2477,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"
|
||||
|
@ -2489,18 +2463,6 @@ is-extglob@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-fullwidth-code-point@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
||||
integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
|
@ -2528,28 +2490,11 @@ is-number@^7.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
is-observable@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e"
|
||||
integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==
|
||||
dependencies:
|
||||
symbol-observable "^1.1.0"
|
||||
|
||||
is-potential-custom-element-name@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
|
||||
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
|
||||
|
||||
is-promise@^2.1.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
|
||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
|
||||
|
||||
is-stream@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
|
||||
|
@ -3128,6 +3073,11 @@ kleur@^3.0.3:
|
|||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||
|
||||
kleur@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
|
||||
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
|
||||
|
||||
leven@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
||||
|
@ -3154,50 +3104,6 @@ lines-and-columns@^1.1.6:
|
|||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||
|
||||
listr-silent-renderer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
|
||||
integrity sha512-L26cIFm7/oZeSNVhWB6faeorXhMg4HNlb/dS/7jHhr708jxlXrtrBWo4YUxZQkc6dGoxEAe6J/D3juTRBUzjtA==
|
||||
|
||||
listr-update-renderer@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2"
|
||||
integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
cli-truncate "^0.2.1"
|
||||
elegant-spinner "^1.0.1"
|
||||
figures "^1.7.0"
|
||||
indent-string "^3.0.0"
|
||||
log-symbols "^1.0.2"
|
||||
log-update "^2.3.0"
|
||||
strip-ansi "^3.0.1"
|
||||
|
||||
listr-verbose-renderer@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db"
|
||||
integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==
|
||||
dependencies:
|
||||
chalk "^2.4.1"
|
||||
cli-cursor "^2.1.0"
|
||||
date-fns "^1.27.2"
|
||||
figures "^2.0.0"
|
||||
|
||||
listr@^0.14.3:
|
||||
version "0.14.3"
|
||||
resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586"
|
||||
integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==
|
||||
dependencies:
|
||||
"@samverschueren/stream-to-observable" "^0.3.0"
|
||||
is-observable "^1.1.0"
|
||||
is-promise "^2.1.0"
|
||||
is-stream "^1.1.0"
|
||||
listr-silent-renderer "^1.1.1"
|
||||
listr-update-renderer "^0.5.0"
|
||||
listr-verbose-renderer "^0.5.0"
|
||||
p-map "^2.0.0"
|
||||
rxjs "^6.3.3"
|
||||
|
||||
load-bmfont@^1.3.1, load-bmfont@^1.4.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9"
|
||||
|
@ -3229,27 +3135,11 @@ 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==
|
||||
|
||||
log-symbols@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
|
||||
integrity sha512-mmPrW0Fh2fxOzdBbFv4g1m6pR72haFLPJ2G5SJEELf1y+iaQrDG6cWCPjy54RHYbZAt7X+ls690Kw62AdWXBzQ==
|
||||
dependencies:
|
||||
chalk "^1.0.0"
|
||||
|
||||
log-update@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
|
||||
integrity sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg==
|
||||
dependencies:
|
||||
ansi-escapes "^3.0.0"
|
||||
cli-cursor "^2.0.0"
|
||||
wrap-ansi "^3.0.1"
|
||||
|
||||
lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
|
@ -3311,11 +3201,6 @@ mime@^1.3.4:
|
|||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
||||
|
||||
mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
|
@ -3333,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"
|
||||
|
@ -3407,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"
|
||||
|
@ -3419,21 +3319,11 @@ npm-run-path@^4.0.1:
|
|||
dependencies:
|
||||
path-key "^3.0.0"
|
||||
|
||||
number-is-nan@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
|
||||
|
||||
nwsapi@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c"
|
||||
integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==
|
||||
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
|
||||
|
||||
omggif@^1.0.10, omggif@^1.0.9:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19"
|
||||
|
@ -3446,13 +3336,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
|||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
onetime@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
|
||||
integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==
|
||||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
onetime@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
||||
|
@ -3498,11 +3381,6 @@ p-locate@^4.1.0:
|
|||
dependencies:
|
||||
p-limit "^2.2.0"
|
||||
|
||||
p-map@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
|
||||
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
|
||||
|
||||
p-try@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
|
@ -3543,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==
|
||||
|
@ -3617,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"
|
||||
|
@ -3724,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"
|
||||
|
@ -3738,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"
|
||||
|
@ -3770,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==
|
||||
|
@ -3779,14 +3686,6 @@ resolve@^1.20.0:
|
|||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==
|
||||
dependencies:
|
||||
onetime "^2.0.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
reusify@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
|
@ -3811,7 +3710,7 @@ rustic@^1.2.1:
|
|||
resolved "https://registry.yarnpkg.com/rustic/-/rustic-1.2.2.tgz#7b853bccbf0daa6e88d27d7e10aa1909c9bab73f"
|
||||
integrity sha512-aagYrcImcYj3QbaP7nirOw8/q8aULMu0LkKucP9B4WsRbXlXpk195nYAEB+uJzAcgk2pKS+yMzbAJtIoOqwZoQ==
|
||||
|
||||
rxjs@^6.3.3, rxjs@^6.5.1:
|
||||
rxjs@^6.5.1:
|
||||
version "6.6.7"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
|
||||
integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
|
||||
|
@ -3828,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"
|
||||
|
@ -3845,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"
|
||||
|
@ -3919,11 +3830,6 @@ slash@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||
|
||||
slice-ansi@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||
integrity sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==
|
||||
|
||||
source-map-support@^0.5.6:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
|
@ -3942,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"
|
||||
|
@ -3962,23 +3894,6 @@ string-length@^4.0.1:
|
|||
char-regex "^1.0.2"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string-width@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
|
||||
integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
|
||||
dependencies:
|
||||
code-point-at "^1.0.0"
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string-width@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
|
@ -3995,20 +3910,6 @@ string_decoder@^1.1.1:
|
|||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||
integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
|
@ -4026,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"
|
||||
|
@ -4036,11 +3944,6 @@ strip-json-comments@~2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
|
@ -4075,11 +3978,6 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
symbol-observable@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
|
||||
|
||||
symbol-tree@^3.2.4:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
|
@ -4138,6 +4036,14 @@ timm@^1.6.1:
|
|||
resolved "https://registry.yarnpkg.com/timm/-/timm-1.7.1.tgz#96bab60c7d45b5a10a8a4d0f0117c6b7e5aff76f"
|
||||
integrity sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==
|
||||
|
||||
tiny-glob@^0.2.9:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2"
|
||||
integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==
|
||||
dependencies:
|
||||
globalyzer "0.1.0"
|
||||
globrex "^0.1.2"
|
||||
|
||||
tinycolor2@^1.4.1:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
||||
|
@ -4238,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"
|
||||
|
@ -4301,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"
|
||||
|
@ -4365,14 +4289,6 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
|
|||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wrap-ansi@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba"
|
||||
integrity sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==
|
||||
dependencies:
|
||||
string-width "^2.1.1"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue