You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.7 KiB
134 lines
3.7 KiB
6 years ago
|
import axios, { AxiosResponse } from 'axios'
|
||
6 years ago
|
|
||
6 years ago
|
export interface Imported {
|
||
6 years ago
|
content: string;
|
||
|
cleanURL: string;
|
||
|
type: string;
|
||
|
}
|
||
|
|
||
6 years ago
|
interface PreviouslyHandledImports {
|
||
6 years ago
|
[filePath: string]: Imported
|
||
|
}
|
||
|
|
||
|
interface Handler {
|
||
|
type: string;
|
||
|
match(url: string): any;
|
||
|
handle(match: any): any;
|
||
|
}
|
||
|
|
||
6 years ago
|
export class RemixURLResolver {
|
||
6 years ago
|
private previouslyHandled: PreviouslyHandledImports
|
||
6 years ago
|
constructor() {
|
||
|
this.previouslyHandled = {}
|
||
|
}
|
||
|
/**
|
||
|
* Handle an import statement based on github
|
||
|
* @params root The root of the github import statement
|
||
|
* @params filePath path of the file in github
|
||
|
*/
|
||
6 years ago
|
async handleGithubCall(root: string, filePath: string) {
|
||
|
try {
|
||
|
let req: string = 'https://api.github.com/repos/' + root + '/contents/' + filePath
|
||
6 years ago
|
const response: AxiosResponse = await axios.get(req)
|
||
6 years ago
|
return Buffer.from(response.data.content, 'base64').toString()
|
||
6 years ago
|
} catch(e) {
|
||
|
throw e
|
||
|
}
|
||
6 years ago
|
}
|
||
|
/**
|
||
|
* Handle an import statement based on http
|
||
|
* @params url The url of the import statement
|
||
|
* @params cleanURL
|
||
|
*/
|
||
6 years ago
|
async handleHttp(url: string, _: string) {
|
||
|
try {
|
||
|
const response: AxiosResponse = await axios.get(url)
|
||
|
return response.data
|
||
|
} catch(e) {
|
||
|
throw e
|
||
|
}
|
||
6 years ago
|
}
|
||
|
/**
|
||
|
* Handle an import statement based on https
|
||
|
* @params url The url of the import statement
|
||
|
* @params cleanURL
|
||
|
*/
|
||
6 years ago
|
async handleHttps(url: string, _: string) {
|
||
6 years ago
|
try {
|
||
6 years ago
|
const response: AxiosResponse = await axios.get(url)
|
||
6 years ago
|
return response.data
|
||
|
} catch(e) {
|
||
|
throw e
|
||
|
}
|
||
6 years ago
|
}
|
||
|
handleSwarm(url: string, cleanURL: string) {
|
||
|
return
|
||
|
}
|
||
|
/**
|
||
|
* Handle an import statement based on IPFS
|
||
|
* @params url The url of the IPFS import statement
|
||
|
*/
|
||
|
async handleIPFS(url: string) {
|
||
|
// replace ipfs:// with /ipfs/
|
||
|
url = url.replace(/^ipfs:\/\/?/, 'ipfs/')
|
||
|
try {
|
||
|
const req = 'https://gateway.ipfs.io/' + url
|
||
|
// If you don't find greeter.sol on ipfs gateway use local
|
||
|
// const req = 'http://localhost:8080/' + url
|
||
6 years ago
|
const response: AxiosResponse = await axios.get(req)
|
||
6 years ago
|
return response.data
|
||
|
} catch (e) {
|
||
|
throw e
|
||
|
}
|
||
|
}
|
||
|
getHandlers(): Handler[] {
|
||
|
return [
|
||
|
{
|
||
|
type: 'github',
|
||
|
match: (url) => { return /^(https?:\/\/)?(www.)?github.com\/([^/]*\/[^/]*)\/(.*)/.exec(url) },
|
||
|
handle: (match) => this.handleGithubCall(match[3], match[4])
|
||
|
},
|
||
|
{
|
||
|
type: 'http',
|
||
|
match: (url) => { return /^(http?:\/\/?(.*))$/.exec(url) },
|
||
|
handle: (match) => this.handleHttp(match[1], match[2])
|
||
|
},
|
||
|
{
|
||
|
type: 'https',
|
||
|
match: (url) => { return /^(https?:\/\/?(.*))$/.exec(url) },
|
||
|
handle: (match) => this.handleHttps(match[1], match[2])
|
||
|
},
|
||
|
{
|
||
|
type: 'swarm',
|
||
|
match: (url) => { return /^(bzz-raw?:\/\/?(.*))$/.exec(url) },
|
||
|
handle: (match) => this.handleSwarm(match[1], match[2])
|
||
|
},
|
||
|
{
|
||
|
type: 'ipfs',
|
||
|
match: (url) => { return /^(ipfs:\/\/?.+)/.exec(url) },
|
||
|
handle: (match) => this.handleIPFS(match[1])
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
|
||
|
public async resolve(filePath: string, customHandlers?: Handler[]): Promise<Imported> {
|
||
|
var imported: Imported = this.previouslyHandled[filePath]
|
||
|
if(imported) {
|
||
|
return imported
|
||
|
}
|
||
|
const builtinHandlers: Handler[] = this.getHandlers()
|
||
|
const handlers: Handler[] = customHandlers ? [...builtinHandlers, ...customHandlers] : [...builtinHandlers]
|
||
|
const matchedHandler = handlers.filter(handler => handler.match(filePath))
|
||
|
const handler: Handler = matchedHandler[0]
|
||
|
const match = handler.match(filePath)
|
||
|
const content: string = await handler.handle(match)
|
||
|
imported = {
|
||
|
content,
|
||
|
cleanURL: filePath,
|
||
|
type: handler.type
|
||
|
}
|
||
|
this.previouslyHandled[filePath] = imported
|
||
|
return imported
|
||
|
}
|
||
|
}
|