forked from ethereum/remix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resolve.ts
133 lines (128 loc) · 3.74 KB
/
resolve.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import axios, { AxiosResponse } from 'axios'
export interface Imported {
content: string;
cleanURL: string;
type: string;
}
interface PreviouslyHandledImports {
[filePath: string]: Imported
}
interface Handler {
type: string;
match(url: string): any;
handle(match: any): any;
}
export class RemixURLResolver {
private previouslyHandled: PreviouslyHandledImports
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
*/
async handleGithubCall(root: string, filePath: string) {
try {
let req: string = 'https://api.github.com/repos/' + root + '/contents/' + filePath
const response: AxiosResponse = await axios.get(req)
return Buffer.from(response.data.content, 'base64').toString()
} catch(e) {
throw e
}
}
/**
* Handle an import statement based on http
* @params url The url of the import statement
* @params cleanURL
*/
async handleHttp(url: string, _: string) {
try {
const response: AxiosResponse = await axios.get(url)
return response.data
} catch(e) {
throw e
}
}
/**
* Handle an import statement based on https
* @params url The url of the import statement
* @params cleanURL
*/
async handleHttps(url: string, _: string) {
try {
const response: AxiosResponse = await axios.get(url)
return response.data
} catch(e) {
throw e
}
}
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
const response: AxiosResponse = await axios.get(req)
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
}
}