-
Notifications
You must be signed in to change notification settings - Fork 59
/
Http.ts
134 lines (122 loc) · 4.7 KB
/
Http.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
134
import {
RestError, userAgentPolicyName, setClientRequestIdPolicyName,
} from '@azure/core-rest-pipeline';
import { OperationOptions } from '@azure/core-client';
import {
Compiler as CompilerApi,
ErrorModel,
CompilerError as CompilerErrorApi,
} from '../../apis/compiler';
import { genErrorFormatterPolicy, genVersionCheckPolicy } from '../../utils/autorest';
import CompilerBase, { Aci, CompileResult } from './Base';
import { Encoded } from '../../utils/encoder';
import { CompilerError, NotImplementedError } from '../../utils/errors';
type GeneralCompilerError = ErrorModel & {
info?: object;
parameter?: string;
};
/**
* Contract Compiler over HTTP
*
* This class include api call's related to contract compiler functionality.
* @category contract
* @example CompilerHttp('COMPILER_URL')
*/
export default class CompilerHttp extends CompilerBase {
readonly api: CompilerApi;
/**
* @param compilerUrl - Url for compiler API
* @param options - Options
* @param options.ignoreVersion - Don't check compiler version
*/
constructor(compilerUrl: string, { ignoreVersion = false }: { ignoreVersion?: boolean } = {}) {
super();
let version: string | undefined;
const getVersion = async (opts: OperationOptions): Promise<string> => {
if (version != null) return version;
version = (await this.api.apiVersion(opts)).apiVersion;
return version;
};
this.api = new CompilerApi(compilerUrl, {
allowInsecureConnection: true,
additionalPolicies: [
...ignoreVersion ? [] : [genVersionCheckPolicy('compiler', getVersion, '7.3.0', '9.0.0')],
genErrorFormatterPolicy((body: GeneralCompilerError | CompilerErrorApi[]) => {
let message = '';
if ('reason' in body) {
message += ` ${body.reason
}${body.parameter != null ? ` in ${body.parameter}` : ''
// TODO: revising after improving documentation https://github.com/aeternity/aesophia_http/issues/78
}${body.info != null ? ` (${JSON.stringify(body.info)})` : ''}`;
}
if (Array.isArray(body)) {
message += `\n${body
.map((e) => `${e.type}:${e.pos.line}:${e.pos.col}: ${e.message}${e.context != null ? ` (${e.context})` : ''}`)
.join('\n')}`;
}
return message;
}),
],
});
this.api.pipeline.removePolicy({ name: userAgentPolicyName });
this.api.pipeline.removePolicy({ name: setClientRequestIdPolicyName });
}
async compileBySourceCode(
sourceCode: string,
fileSystem?: Record<string, string>,
): CompileResult {
try {
const cmpOut = await this.api.compileContract({ code: sourceCode, options: { fileSystem } });
cmpOut.warnings ??= []; // TODO: remove after requiring http compiler above or equal to 8.0.0
const warnings = cmpOut.warnings.map(({ type, ...warning }) => warning);
const res = { ...cmpOut, warnings };
// TODO: should be fixed when the compiledAci interface gets updated
return res as Awaited<CompileResult>;
} catch (error) {
if (error instanceof RestError && error.statusCode === 400) {
throw new CompilerError(error.message);
}
throw error;
}
}
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
async compile(path: string): CompileResult {
throw new NotImplementedError('File system access, use CompilerHttpNode instead');
}
async generateAciBySourceCode(
sourceCode: string,
fileSystem?: Record<string, string>,
): Promise<Aci> {
try {
return await this.api.generateACI({ code: sourceCode, options: { fileSystem } });
} catch (error) {
if (error instanceof RestError && error.statusCode === 400) {
throw new CompilerError(error.message);
}
throw error;
}
}
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
async generateAci(path: string): Promise<Aci> {
throw new NotImplementedError('File system access, use CompilerHttpNode instead');
}
async validateBySourceCode(
bytecode: Encoded.ContractBytearray,
sourceCode: string,
fileSystem?: Record<string, string>,
): Promise<boolean> {
try {
await this.api.validateByteCode({ bytecode, source: sourceCode, options: { fileSystem } });
return true;
} catch {
return false;
}
}
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
async validate(bytecode: Encoded.ContractBytearray, path: string): Promise<boolean> {
throw new NotImplementedError('File system access, use CompilerHttpNode instead');
}
async version(): Promise<string> {
return (await this.api.version()).version;
}
}