Install circom via cli

circom-desktop
ioedeveloper 4 months ago
parent 2f93105f36
commit 89e6c0ce1d
  1. 1
      .gitignore
  2. 296
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  3. 6
      apps/remix-ide/src/app.js
  4. 12
      apps/remix-ide/src/app/plugins/electron/circomElectronPlugin.ts
  5. 2
      apps/remix-ide/src/remixAppManager.js
  6. 1
      apps/remix-ide/src/remixEngine.js
  7. 22
      apps/remixdesktop/package.json
  8. 3
      apps/remixdesktop/src/engine.ts
  9. 52
      apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts
  10. 4
      apps/remixdesktop/src/preload.ts
  11. 55
      apps/remixdesktop/src/tools/circom.ts
  12. 83
      apps/remixdesktop/yarn.lock

1
.gitignore vendored

@ -68,4 +68,5 @@ apps/remix-ide/src/assets/esbuild.wasm
apps/remixdesktop/build*
apps/remixdesktop/reports
apps/remixdesktop/logs/
apps/remixdesktop/bin/
logs

@ -8,7 +8,8 @@ import * as compilerV217 from 'circom_wasm/v2.1.7'
import * as compilerV216 from 'circom_wasm/v2.1.6'
import * as compilerV215 from 'circom_wasm/v2.1.5'
import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper'
import { CompilationConfig, CompilerReport, PrimeValue, ResolverOutput } from '../types'
import { CompilationConfig, CompilerReport, PrimeValue } from '../types'
import isElectron from 'is-electron'
export class CircomPluginClient extends PluginClient {
public internalEvents: EventManager
@ -61,179 +62,194 @@ export class CircomPluginClient extends PluginClient {
}
async parse(path: string, fileContent?: string): Promise<[CompilerReport[], Record<string, string>]> {
if (!fileContent) {
if (isElectron()) {
// @ts-ignore
fileContent = await this.call('fileManager', 'readFile', path)
}
this.lastParsedFiles = await this.resolveDependencies(path, fileContent)
const parsedOutput = this.compiler ? this.compiler.parse(path, this.lastParsedFiles) : parse(path, this.lastParsedFiles)
return await this.call('circom', 'parse', path)
} else {
if (!fileContent) {
// @ts-ignore
fileContent = await this.call('fileManager', 'readFile', path)
}
this.lastParsedFiles = await this.resolveDependencies(path, fileContent)
const parsedOutput = this.compiler ? this.compiler.parse(path, this.lastParsedFiles) : parse(path, this.lastParsedFiles)
try {
const result: CompilerReport[] = JSON.parse(parsedOutput.report())
const mapReportFilePathToId: Record<string, string> = {}
try {
const result: CompilerReport[] = JSON.parse(parsedOutput.report())
const mapReportFilePathToId: Record<string, string> = {}
if (result.length === 0) {
// @ts-ignore
await this.call('editor', 'clearErrorMarkers', [path])
} else {
const markers = []
if (result.length === 0) {
// @ts-ignore
await this.call('editor', 'clearErrorMarkers', [path])
} else {
const markers = []
for (const report of result) {
for (const label in report.labels) {
const file_id = report.labels[label].file_id
for (const report of result) {
for (const label in report.labels) {
const file_id = report.labels[label].file_id
mapReportFilePathToId[file_id] = parsedOutput.get_report_name(parseInt(file_id))
if (file_id === '0') {
// @ts-ignore
const startPosition: { lineNumber: number; column: number } = await this.call(
'editor',
mapReportFilePathToId[file_id] = parsedOutput.get_report_name(parseInt(file_id))
if (file_id === '0') {
// @ts-ignore
'getPositionAt',
report.labels[label].range.start
)
// @ts-ignore
const endPosition: { lineNumber: number; column: number } = await this.call(
'editor',
const startPosition: { lineNumber: number; column: number } = await this.call(
'editor',
// @ts-ignore
'getPositionAt',
report.labels[label].range.start
)
// @ts-ignore
'getPositionAt',
report.labels[label].range.end
)
markers.push({
message: report.message,
severity: report.type.toLowerCase(),
position: {
start: {
line: startPosition.lineNumber,
column: startPosition.column,
const endPosition: { lineNumber: number; column: number } = await this.call(
'editor',
// @ts-ignore
'getPositionAt',
report.labels[label].range.end
)
markers.push({
message: report.message,
severity: report.type.toLowerCase(),
position: {
start: {
line: startPosition.lineNumber,
column: startPosition.column,
},
end: {
line: endPosition.lineNumber,
column: endPosition.column,
},
},
end: {
line: endPosition.lineNumber,
column: endPosition.column,
},
},
file: path,
})
file: path,
})
}
}
}
}
if (markers.length > 0) {
// @ts-ignore
await this.call('editor', 'addErrorMarker', markers)
} else {
// @ts-ignore
await this.call('editor', 'clearErrorMarkers', [path])
this.emit('statusChanged', { key: 'none' })
if (markers.length > 0) {
// @ts-ignore
await this.call('editor', 'addErrorMarker', markers)
} else {
// @ts-ignore
await this.call('editor', 'clearErrorMarkers', [path])
this.emit('statusChanged', { key: 'none' })
}
}
}
return [result, mapReportFilePathToId]
} catch (e) {
throw new Error(e)
return [result, mapReportFilePathToId]
} catch (e) {
throw new Error(e)
}
}
}
async compile(path: string, compilationConfig?: CompilationConfig): Promise<void> {
this.internalEvents.emit('circuit_compiling_start')
this.emit('statusChanged', { key: 'loading', title: 'Compiling...', type: 'info' })
// @ts-ignore
this.call('terminal', 'log', { type: 'log', value: 'Compiling ' + path })
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
this.internalEvents.emit('circuit_parsing_errored', parseErrors, filePathToId)
this.logCompilerReport(parseErrors)
return
} else if (parseErrors[0].type === 'Warning') {
this.internalEvents.emit('circuit_parsing_warning', parseErrors, filePathToId)
this.logCompilerReport(parseErrors)
}
if (isElectron()) {
// @ts-ignore
return await this.call('circom', 'compile', path)
} else {
this.internalEvents.emit('circuit_parsing_done', parseErrors, filePathToId)
this.emit('statusChanged', { key: 'succeed', title: 'circuit compiled successfully', type: 'success' })
}
if (compilationConfig) {
const { prime, version } = compilationConfig
this.internalEvents.emit('circuit_compiling_start')
this.emit('statusChanged', { key: 'loading', title: 'Compiling...', type: 'info' })
// @ts-ignore
this.call('terminal', 'log', { type: 'log', value: 'Compiling ' + path })
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
this.internalEvents.emit('circuit_parsing_errored', parseErrors, filePathToId)
this.logCompilerReport(parseErrors)
return
} else if (parseErrors[0].type === 'Warning') {
this.internalEvents.emit('circuit_parsing_warning', parseErrors, filePathToId)
this.logCompilerReport(parseErrors)
}
} else {
this.internalEvents.emit('circuit_parsing_done', parseErrors, filePathToId)
this.emit('statusChanged', { key: 'succeed', title: 'circuit compiled successfully', type: 'success' })
}
if (compilationConfig) {
const { prime, version } = compilationConfig
this.compilerVersion = version
this.compilerPrime = prime
}
const circuitApi = this.compiler ? this.compiler.compile(path, this.lastParsedFiles, { prime: this._compilationConfig.prime }) : compile(path, this.lastParsedFiles, { prime: this._compilationConfig.prime })
const circuitProgram = circuitApi.program()
this.compilerVersion = version
this.compilerPrime = prime
}
const circuitApi = this.compiler ? this.compiler.compile(path, this.lastParsedFiles, { prime: this._compilationConfig.prime }) : compile(path, this.lastParsedFiles, { prime: this._compilationConfig.prime })
const circuitProgram = circuitApi.program()
if (circuitProgram.length < 1) {
const circuitErrors = circuitApi.report()
if (circuitProgram.length < 1) {
const circuitErrors = circuitApi.report()
this.logCompilerReport(circuitErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation failed'])
throw new Error(circuitErrors)
} else {
this.lastCompiledFile = path
const fileName = extractNameFromKey(path)
this.logCompilerReport(circuitErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation failed'])
throw new Error(circuitErrors)
} else {
this.lastCompiledFile = path
const fileName = extractNameFromKey(path)
this.lastCompiledCircuitPath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'wasm')
// @ts-ignore
await this.call('fileManager', 'writeFile', this.lastCompiledCircuitPath, circuitProgram, { encoding: null })
const fileContent = this.lastParsedFiles[path]
const searchComponentName = fileContent.match(/component\s+main\s*(?:{[^{}]*})?\s*=\s*([A-Za-z_]\w*)\s*\(.*\)/)
this.lastCompiledCircuitPath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'wasm')
// @ts-ignore
await this.call('fileManager', 'writeFile', this.lastCompiledCircuitPath, circuitProgram, { encoding: null })
const fileContent = this.lastParsedFiles[path]
const searchComponentName = fileContent.match(/component\s+main\s*(?:{[^{}]*})?\s*=\s*([A-Za-z_]\w*)\s*\(.*\)/)
if (searchComponentName) {
const componentName = searchComponentName[1]
const signals = circuitApi.input_signals(componentName)
if (searchComponentName) {
const componentName = searchComponentName[1]
const signals = circuitApi.input_signals(componentName)
this.internalEvents.emit('circuit_compiling_done', signals)
} else {
this.internalEvents.emit('circuit_compiling_done', [])
this.internalEvents.emit('circuit_compiling_done', signals)
} else {
this.internalEvents.emit('circuit_compiling_done', [])
}
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation successful'])
circuitApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
// @ts-ignore
this.call('terminal', 'log', { type: 'typewritersuccess', value: 'Everything went okay' })
}
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation successful'])
circuitApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
// @ts-ignore
this.call('terminal', 'log', { type: 'typewritersuccess', value: 'Everything went okay' })
}
}
async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> {
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
this.logCompilerReport(parseErrors)
return
} else if (parseErrors[0].type === 'Warning') {
this.logCompilerReport(parseErrors)
if (isElectron()) {
// @ts-ignore
return await this.call('circom', 'generateR1cs', path)
} else {
const [parseErrors, filePathToId] = await this.parse(path)
if (parseErrors && (parseErrors.length > 0)) {
if (parseErrors[0].type === 'Error') {
this.logCompilerReport(parseErrors)
return
} else if (parseErrors[0].type === 'Warning') {
this.logCompilerReport(parseErrors)
}
}
}
if (compilationConfig) {
const { prime, version } = compilationConfig
if (compilationConfig) {
const { prime, version } = compilationConfig
this.compilerVersion = version
this.compilerPrime = prime
}
const r1csApi = this.compiler ? this.compiler.generate_r1cs(path, this.lastParsedFiles, { prime: this._compilationConfig.prime }) : generate_r1cs(path, this.lastParsedFiles, { prime: this._compilationConfig.prime })
const r1csProgram = r1csApi.program()
this.compilerVersion = version
this.compilerPrime = prime
}
const r1csApi = this.compiler ? this.compiler.generate_r1cs(path, this.lastParsedFiles, { prime: this._compilationConfig.prime }) : generate_r1cs(path, this.lastParsedFiles, { prime: this._compilationConfig.prime })
const r1csProgram = r1csApi.program()
if (r1csProgram.length < 1) {
const r1csErrors = r1csApi.report()
if (r1csProgram.length < 1) {
const r1csErrors = r1csApi.report()
this.logCompilerReport(r1csErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation failed'])
throw new Error(r1csErrors)
} else {
const fileName = extractNameFromKey(path)
const writePath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'r1cs')
this.logCompilerReport(r1csErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation failed'])
throw new Error(r1csErrors)
} else {
const fileName = extractNameFromKey(path)
const writePath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'r1cs')
// @ts-ignore
await this.call('fileManager', 'writeFile', writePath, r1csProgram, true)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation successful'])
r1csApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
// @ts-ignore
this.call('terminal', 'log', { type: 'typewritersuccess', value: 'Everything went okay' })
// @ts-ignore
await this.call('fileManager', 'writeFile', writePath, r1csProgram, true)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation successful'])
r1csApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
// @ts-ignore
this.call('terminal', 'log', { type: 'typewritersuccess', value: 'Everything went okay' })
}
}
}

@ -66,7 +66,7 @@ import { FoundryHandle } from './app/files/foundry-handle'
import { FoundryHandleDesktop } from './app/plugins/electron/foundryPlugin'
import { HardhatHandle } from './app/files/hardhat-handle'
import { HardhatHandleDesktop } from './app/plugins/electron/hardhatPlugin'
import { circomPlugin } from './app/plugins/electron/circomElectronPlugin'
import { GitPlugin } from './app/plugins/git'
import { Matomo } from './app/plugins/matomo'
@ -419,6 +419,8 @@ class AppComponent {
this.engine.register([xterm])
const ripgrep = new ripgrepPlugin()
this.engine.register([ripgrep])
const circom = new circomPlugin()
this.engine.register([circom])
const appUpdater = new appUpdaterPlugin()
this.engine.register([appUpdater])
const remixAIDesktop = new remixAIDesktopPlugin()
@ -565,7 +567,7 @@ class AppComponent {
await this.appManager.activatePlugin(['solidity-script', 'remix-templates'])
if (isElectron()) {
await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep', 'appUpdater', 'slither', 'foundry', 'hardhat']) // 'remixAID'
await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep', 'appUpdater', 'slither', 'foundry', 'hardhat', 'circom']) // 'remixAID'
}
this.appManager.on(

@ -0,0 +1,12 @@
import { ElectronPlugin } from '@remixproject/engine-electron'
export class circomPlugin extends ElectronPlugin {
constructor() {
super({
displayName: 'circom',
name: 'circom',
description: 'circom language compiler',
})
this.methods = []
}
}

@ -171,7 +171,7 @@ export class RemixAppManager extends PluginManager {
this.pluginsDirectory = 'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json'
this.pluginLoader = new PluginLoader()
if (Registry.getInstance().get('platform').api.isDesktop()) {
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig', 'xterm', 'compilerloader', 'ripgrep', 'slither', 'remixAID']
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig', 'xterm', 'compilerloader', 'ripgrep', 'slither', 'remixAID', 'circom']
}
}

@ -30,6 +30,7 @@ export class RemixEngine extends Engine {
if (name === 'remixAI') return { queueTimeout: 60000 * 20 }
if (name === 'cookbookdev') return { queueTimeout: 60000 * 3 }
if (name === 'contentImport') return { queueTimeout: 60000 * 3 }
if (name === 'circom') return { queueTimeout: 60000 * 4 }
return { queueTimeout: 10000 }
}

@ -21,8 +21,25 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"appId": "org.ethereum.remixdesktop",
"mac": {
"category": "public.app-category.productivity"
"build": {
"files": [
"build/**/*"
],
"mac": {
"category": "public.app-category.productivity",
"icon": "assets/icon.png",
"darkModeSupport": true,
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "entitlements.mac.plist",
"entitlementsInherit": "entitlements.mac.plist",
"extraResources": [
{
"from": "bin/circom-macos-amd64",
"to": "bin/circom-macos-amd64"
}
]
}
},
"scripts": {
"start:dev": "yarn webpack --config webpack.config.js && electron --inspect=5858 .",
@ -75,6 +92,7 @@
"axios": "^1.7.4",
"byline": "^5.0.0",
"chokidar": "^3.5.3",
"dockerode": "^4.0.2",
"electron-updater": "^6.1.8",
"express": "^4.20.0",
"isomorphic-git": "^1.24.2",

@ -14,6 +14,7 @@ import { AppUpdaterPlugin } from './plugins/appUpdater';
import { RemixAIDesktopPlugin } from './plugins/remixAIDektop';
import { FoundryPlugin } from './plugins/foundryPlugin';
import { HardhatPlugin } from './plugins/hardhatPlugin';
import { CircomElectronPlugin } from './plugins/circomElectronBasePlugin';
import { isE2E } from './main';
const engine = new Engine()
@ -30,6 +31,7 @@ const appUpdaterPlugin = new AppUpdaterPlugin()
const foundryPlugin = new FoundryPlugin()
const hardhatPlugin = new HardhatPlugin()
const remixAIDesktopPlugin = new RemixAIDesktopPlugin()
const circomPlugin = new CircomElectronPlugin()
engine.register(appManager)
engine.register(fsPlugin)
@ -44,6 +46,7 @@ engine.register(foundryPlugin)
engine.register(appUpdaterPlugin)
engine.register(hardhatPlugin)
engine.register(remixAIDesktopPlugin)
engine.register(circomPlugin)
appManager.activatePlugin('electronconfig')
appManager.activatePlugin('fs')

@ -0,0 +1,52 @@
import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron"
import { Profile } from "@remixproject/plugin-utils"
import { circomCli } from "../tools/circom"
const profile: Profile = {
displayName: 'circom',
name: 'circom',
description: 'Circom language compiler'
}
export class CircomElectronPlugin extends ElectronBasePlugin {
clients: CircomElectronPluginClient[] = []
constructor() {
super(profile, clientProfile, CircomElectronPluginClient)
this.methods = [...super.methods]
}
async onActivation(): Promise<void> {
console.log('activating to exec')
if (!(await circomCli.isCargoInstalled())) await circomCli.installRustup()
if (!(await circomCli.isCircomInstalled())) await circomCli.installCircom()
}
}
const clientProfile: Profile = {
name: 'circom',
displayName: 'circom',
description: 'Circom Language Compiler',
methods: ['parse', 'compile', 'generateR1cs']
}
class CircomElectronPluginClient extends ElectronBasePluginClient {
circomIsInstalled: boolean = false
constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile)
this.onload()
}
async compile() {
console.log('compiling circom circuit...')
}
parse(): void {
console.log('parsing circom electron plugin...')
}
generateR1cs(): void {
console.log('generating r1cs circom electron plugin...')
}
}

@ -6,7 +6,7 @@ console.log('preload.ts', new Date().toLocaleTimeString())
/* preload script needs statically defined API for each plugin */
const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader', 'appUpdater', 'slither', 'foundry', 'hardhat', 'remixAID']
const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader', 'appUpdater', 'slither', 'foundry', 'hardhat', 'remixAID', 'circom']
let webContentsId: number | undefined
@ -18,7 +18,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
isPackaged: () => ipcRenderer.invoke('config:isPackaged'),
isE2E: () => ipcRenderer.invoke('config:isE2E'),
canTrackMatomo: () => ipcRenderer.invoke('config:canTrackMatomo'),
trackEvent: (args: any[]) => ipcRenderer.invoke('matomo:trackEvent', args),
trackEvent: (args: any[]) => ipcRenderer.invoke('matomo:trackEvent', args),
openFolder: (path: string) => ipcRenderer.invoke('fs:openFolder', webContentsId, path),
openFolderInSameWindow: (path: string) => ipcRenderer.invoke('fs:openFolderInSameWindow', webContentsId, path),
activatePlugin: (name: string) => {

@ -0,0 +1,55 @@
import { app } from 'electron'
import { promisify } from 'util'
import { exec } from 'child_process'
import { gitProxy } from './git'
import path from 'path'
import { existsSync } from 'fs'
const execAsync = promisify(exec)
export const circomCli = {
async installRustup () {
try {
console.log('installing rustup')
const { stdout } = await execAsync(`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y`)
console.log('stdout: ', stdout)
} catch (e) {
console.error(e)
}
},
async installCircom () {
try {
const appPath = app.getAppPath()
const targetPath = path.join(appPath, 'bin')
console.log('cloning circom repo to ' + targetPath)
if (!existsSync(`${targetPath}/circom`)) await gitProxy.clone('https://github.com/iden3/circom.git', targetPath)
console.log('builing circom with cargo')
await execAsync(`cd ${targetPath}/circom && cargo build --release && cargo install --path circom`)
} catch (e) {
console.error(e)
}
},
async isCircomInstalled () {
try {
await execAsync(`circom --version`)
return true
} catch (e) {
return false
}
},
async isCargoInstalled () {
try {
await execAsync(`cargo version`)
return true
} catch (e) {
return false
}
}
}

@ -14,6 +14,11 @@
dependencies:
regenerator-runtime "^0.14.0"
"@balena/dockerignore@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d"
integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==
"@develar/schema-utils@~2.6.5":
version "2.6.5"
resolved "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz"
@ -1724,7 +1729,7 @@ arrify@^2.0.1:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
asn1@~0.2.3:
asn1@^0.2.6, asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
@ -1853,7 +1858,7 @@ base64-js@^1.3.1, base64-js@^1.5.1:
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
bcrypt-pbkdf@^1.0.0:
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
@ -2088,6 +2093,11 @@ bufferutil@^4.0.1:
dependencies:
node-gyp-build "^4.3.0"
buildcheck@~0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238"
integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==
builder-util-runtime@9.2.3:
version "9.2.3"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz#0a82c7aca8eadef46d67b353c638f052c206b83c"
@ -2234,7 +2244,7 @@ chokidar@3.5.3, chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"
chownr@^1.1.4:
chownr@^1.1.1, chownr@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@ -2491,6 +2501,14 @@ cors@^2.8.1:
object-assign "^4"
vary "^1"
cpu-features@~0.0.9:
version "0.0.10"
resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.10.tgz#9aae536db2710c7254d7ed67cb3cbc7d29ad79c5"
integrity sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==
dependencies:
buildcheck "~0.0.6"
nan "^2.19.0"
crc-32@^1.2.0:
version "1.2.2"
resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz"
@ -2790,6 +2808,25 @@ dmg-license@^1.0.11:
smart-buffer "^4.0.2"
verror "^1.10.0"
docker-modem@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-5.0.3.tgz#50c06f11285289f58112b5c4c4d89824541c41d0"
integrity sha512-89zhop5YVhcPEt5FpUFGr3cDyceGhq/F9J+ZndQ4KfqNvfbJpPMfgeixFgUj5OjCYAboElqODxY5Z1EBsSa6sg==
dependencies:
debug "^4.1.1"
readable-stream "^3.5.0"
split-ca "^1.0.1"
ssh2 "^1.15.0"
dockerode@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-4.0.2.tgz#dedc8529a1db3ac46d186f5912389899bc309f7d"
integrity sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w==
dependencies:
"@balena/dockerignore" "^1.0.2"
docker-modem "^5.0.3"
tar-fs "~2.0.1"
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
@ -5148,6 +5185,11 @@ minizlib@^2.1.1:
minipass "^3.0.0"
yallist "^4.0.0"
mkdirp-classic@^0.5.2:
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mkdirp-promise@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
@ -5277,6 +5319,11 @@ nan@^2.17.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3"
integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==
nan@^2.18.0, nan@^2.19.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3"
integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==
nano-json-stream-parser@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f"
@ -5841,7 +5888,7 @@ read-config-file@6.3.2:
json5 "^2.2.0"
lazy-val "^1.0.4"
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@ -6384,11 +6431,27 @@ source-map@^0.7.4:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
split-ca@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6"
integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==
sprintf-js@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
ssh2@^1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.15.0.tgz#2f998455036a7f89e0df5847efb5421748d9871b"
integrity sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==
dependencies:
asn1 "^0.2.6"
bcrypt-pbkdf "^1.0.2"
optionalDependencies:
cpu-features "~0.0.9"
nan "^2.18.0"
sshpk@^1.7.0:
version "1.18.0"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028"
@ -6584,6 +6647,16 @@ tapable@^2.1.1, tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
tar-fs@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2"
integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==
dependencies:
chownr "^1.1.1"
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^2.0.0"
tar-stream@3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab"
@ -6593,7 +6666,7 @@ tar-stream@3.1.6:
fast-fifo "^1.2.0"
streamx "^2.15.0"
tar-stream@^2.1.0:
tar-stream@^2.0.0, tar-stream@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==

Loading…
Cancel
Save