parent
1c538acd80
commit
f068d3267e
@ -1,259 +0,0 @@ |
||||
import {ElectronBasePlugin, ElectronBasePluginClient} from '@remixproject/plugin-electron' |
||||
import path from 'path' |
||||
import * as esbuild from 'esbuild' |
||||
import fs from 'fs/promises' |
||||
import os, {arch} from 'os' |
||||
import {exec} from 'child_process' |
||||
import {promisify} from 'util' |
||||
const execAsync = promisify(exec) |
||||
|
||||
export const cacheDir = path.join(os.homedir(), '.cache_remix_ide') |
||||
|
||||
const profile = { |
||||
name: 'scriptRunner', |
||||
displayName: 'Script Runner', |
||||
description: 'Execute script and emit logs', |
||||
} |
||||
|
||||
const convertPathToPosix = (pathName: string): string => { |
||||
return pathName.split(path.sep).join(path.posix.sep) |
||||
} |
||||
|
||||
export class ScriptRunnerPlugin extends ElectronBasePlugin { |
||||
constructor() { |
||||
super(profile, clientProfile, ScriptRunnerClient) |
||||
this.methods = [...super.methods] |
||||
} |
||||
} |
||||
|
||||
const clientProfile = { |
||||
name: 'scriptRunner', |
||||
displayName: 'Script Runner', |
||||
description: 'Execute script and emit logs', |
||||
methods: ['execute', 'yarnAdd', 'yarnInit'], |
||||
} |
||||
|
||||
class ScriptRunnerClient extends ElectronBasePluginClient { |
||||
workingDir: string = '' |
||||
nodeVersion: string = '' |
||||
yarnVersion: string = '' |
||||
constructor(webContentsId: number, profile: any) { |
||||
super(webContentsId, profile) |
||||
this.onload(async () => { |
||||
this.on('fs' as any, 'workingDirChanged', async (path: string) => { |
||||
this.workingDir = path |
||||
}) |
||||
|
||||
try { |
||||
const result = await execAsync('node --version') |
||||
this.nodeVersion = result.stdout |
||||
this.call('terminal' as any, 'log', `Node version: ${this.nodeVersion}`) |
||||
return result.stdout |
||||
} catch (error) { |
||||
this.call('terminal' as any, 'log', `Node not found`) |
||||
} |
||||
|
||||
try { |
||||
const result = await execAsync('yarn --version') |
||||
console.log('result', result) |
||||
this.yarnVersion = result.stdout |
||||
this.call('terminal' as any, 'log', `Yarn version: ${this.yarnVersion}`) |
||||
return result.stdout |
||||
} catch (error) { |
||||
this.call('terminal' as any, 'log', `Yarn not found`) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
async yarnAdd(module: string, version: string = ''): Promise<void> { |
||||
const child = utilityProcess |
||||
.fork(path.join(__dirname, '/../tools/yarn/bin/', 'yarn.js'), [`--cwd=${this.workingDir}`, 'add', `${module}@${version}`], { |
||||
stdio: 'pipe', |
||||
}) |
||||
.addListener('exit', () => { |
||||
console.log('exit') |
||||
}) |
||||
child && |
||||
child.stdout && |
||||
child.stdout.on('data', (data) => { |
||||
this.call('terminal' as any, 'log', data.toString()) |
||||
}) |
||||
child && |
||||
child.stdout && |
||||
child.stdout.on('close', (data) => { |
||||
this.call('terminal' as any, 'log', 'close') |
||||
}) |
||||
child && |
||||
child.on('spawn', () => { |
||||
this.call('terminal' as any, 'log', 'yarn start') |
||||
}) |
||||
child && |
||||
child.on('exit', (data) => { |
||||
this.call('terminal' as any, 'log', 'yarn install done') |
||||
}) |
||||
} |
||||
|
||||
async yarnInit(): Promise<void> { |
||||
const child = utilityProcess |
||||
.fork(path.join(__dirname, '/../tools/yarn/bin/', 'yarn.js'), [`--cwd=${this.workingDir}`], { |
||||
stdio: 'pipe', |
||||
}) |
||||
.addListener('exit', () => { |
||||
console.log('exit') |
||||
}) |
||||
child && |
||||
child.stdout && |
||||
child.stdout.on('data', (data) => { |
||||
this.call('terminal' as any, 'log', data.toString()) |
||||
}) |
||||
child && |
||||
child.stdout && |
||||
child.stdout.on('close', (data) => { |
||||
this.call('terminal' as any, 'log', 'close') |
||||
}) |
||||
child && |
||||
child.on('spawn', () => { |
||||
this.call('terminal' as any, 'log', 'yarn start') |
||||
}) |
||||
child && |
||||
child.on('exit', (data) => { |
||||
this.call('terminal' as any, 'log', 'yarn install done') |
||||
}) |
||||
} |
||||
|
||||
async execute(content: string, dir: string): Promise<void> { |
||||
this.call('terminal' as any, 'log', this.workingDir) |
||||
dir = await convertPathToPosix(this.fixPath(dir)) |
||||
|
||||
const out = convertPathToPosix(this.fixPath('dist')) |
||||
try { |
||||
const build = await esbuild.build({ |
||||
entryPoints: [dir], |
||||
bundle: true, |
||||
outdir: out, |
||||
plugins: [], |
||||
platform: 'node', |
||||
inject: ['/Volumes/bunsen/code/basic6/remix.ts'] |
||||
}) |
||||
console.log('build', build) |
||||
if (build.errors.length > 0) { |
||||
console.log('ERRORS', build.errors) |
||||
return |
||||
} |
||||
console.log(path.join(out, 'test.js')) |
||||
const child2 = utilityProcess.fork(path.join(out, 'test.js'), [], { |
||||
stdio: 'pipe', |
||||
}) |
||||
child2 && |
||||
child2.stdout && |
||||
child2.stdout.on('data', (data) => { |
||||
this.call('terminal' as any, 'log', data.toString()) |
||||
}) |
||||
} catch (e: any) { |
||||
// find all errors in string with 'Could not resolve'
|
||||
const errors = e.toString().match(/Could not resolve "([^"]*)"/g) |
||||
if (errors) { |
||||
for (const error of errors) { |
||||
const match = error.match(/Could not resolve "([^"]*)"/) |
||||
if (match) { |
||||
const module = match[1] |
||||
const modulePath = path.join(this.workingDir, 'node_modules', module) |
||||
try { |
||||
await fs.stat(modulePath) |
||||
} catch (e) { |
||||
console.log('modulePath', modulePath) |
||||
this.emit('missingModule', module) |
||||
this.call('terminal' as any, 'log', { |
||||
type: 'error', |
||||
value: `Missing module ${module}`, |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
console.log('ERROR', e) |
||||
} |
||||
} |
||||
|
||||
fixPath(path: string): string { |
||||
if (this.workingDir === '') throw new Error('workingDir is not set') |
||||
if (path) { |
||||
if (path.startsWith('/')) { |
||||
path = path.slice(1) |
||||
} |
||||
} |
||||
path = this.workingDir + (!this.workingDir.endsWith('/') ? '/' : '') + path |
||||
return path |
||||
} |
||||
} |
||||
|
||||
let onEndPlugin = { |
||||
name: 'onEnd', |
||||
setup(build: esbuild.PluginBuild) { |
||||
build.onEnd((result) => { |
||||
console.log(`build ended with ${result.errors.length} errors`) |
||||
}) |
||||
}, |
||||
} |
||||
|
||||
const onResolvePlugin = { |
||||
name: 'onResolve', |
||||
setup(build: esbuild.PluginBuild) { |
||||
build.onLoad( |
||||
{ |
||||
filter: /.*/, |
||||
}, |
||||
async (args) => { |
||||
console.log('onLoad', args) |
||||
/*if(args.namespace && args.namespace !== 'file'){ |
||||
const imported = await resolver.resolve(args.path) |
||||
console.log('imported', imported) |
||||
return { |
||||
contents: imported.content, |
||||
loader: 'js', |
||||
} |
||||
}*/ |
||||
return undefined |
||||
} |
||||
) |
||||
}, |
||||
} |
||||
|
||||
import {URL} from 'url' |
||||
import axios from 'axios' |
||||
import {app, utilityProcess} from 'electron' |
||||
|
||||
let httpPlugin = { |
||||
name: 'http', |
||||
setup(build: esbuild.PluginBuild) { |
||||
// Intercept import paths starting with "http:" and "https:" so
|
||||
// esbuild doesn't attempt to map them to a file system location.
|
||||
// Tag them with the "http-url" namespace to associate them with
|
||||
// this plugin.
|
||||
build.onResolve({filter: /^https?:\/\//}, (args) => ({ |
||||
path: args.path, |
||||
namespace: 'http-url', |
||||
})) |
||||
|
||||
// We also want to intercept all import paths inside downloaded
|
||||
// files and resolve them against the original URL. All of these
|
||||
// files will be in the "http-url" namespace. Make sure to keep
|
||||
// the newly resolved URL in the "http-url" namespace so imports
|
||||
// inside it will also be resolved as URLs recursively.
|
||||
build.onResolve({filter: /.*/, namespace: 'http-url'}, (args) => ({ |
||||
path: new URL(args.path, args.importer).toString(), |
||||
namespace: 'http-url', |
||||
})) |
||||
|
||||
// When a URL is loaded, we want to actually download the content
|
||||
// from the internet. This has just enough logic to be able to
|
||||
// handle the example import from unpkg.com but in reality this
|
||||
// would probably need to be more complex.
|
||||
build.onLoad({filter: /.*/, namespace: 'http-url'}, async (args) => { |
||||
// Download the file
|
||||
const response = await axios.get(args.path, {responseType: 'arraybuffer'}) |
||||
//console.log('response', response.data.toString())
|
||||
return {contents: response.data.toString(), loader: 'js'} |
||||
}) |
||||
}, |
||||
} |
Loading…
Reference in new issue