envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
545 lines (523 loc) • 16.8 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
function panic(message, params) {
let error = new Error(`[rescript-rest] ` + message);
if (params !== undefined) {
error.params = Primitive_option.valFromOption(params);
}
throw error;
}
async function $$default(args) {
let result = await fetch(args.path, args);
let contentType = result.headers.get("content-type");
if (contentType && contentType.includes("application/") && contentType.includes("json")) {
return {
data: await result.json(),
status: result.status,
headers: result.headers
};
} else if (contentType && contentType.includes("text/")) {
return {
data: await result.text(),
status: result.status,
headers: result.headers
};
} else {
return {
data: await result.blob(),
status: result.status,
headers: result.headers
};
}
}
let ApiFetcher = {
$$default: $$default
};
function register(map, status, builder) {
if (status in map) {
return panic(`Response for the "` + status + `" status registered multiple times`, undefined);
} else {
map[status] = builder;
return;
}
}
function parsePath(_path, pathItems, pathParams) {
while (true) {
let path = _path;
if (path === "") {
return;
}
let paramStartIdx = path.indexOf("{");
if (paramStartIdx !== -1) {
let paramEndIdx = path.indexOf("}");
if (paramEndIdx === -1) {
return panic("Path contains an unclosed parameter", undefined);
}
if (paramStartIdx > paramEndIdx) {
panic("Path parameter is not enclosed in curly braces", undefined);
}
let paramName = path.slice(paramStartIdx + 1 | 0, paramEndIdx);
if (paramName === "") {
panic("Path parameter name cannot be empty", undefined);
}
let param = {
name: paramName
};
pathItems.push(path.slice(0, paramStartIdx));
pathItems.push(param);
pathParams[paramName] = param;
_path = path.slice(paramEndIdx + 1 | 0);
continue;
}
pathItems.push(path);
return;
};
}
function coerceSchema(schema) {
return S$RescriptSchema.preprocess(schema, s => {
let optionalSchema = s.schema.t;
let tagged;
tagged = typeof optionalSchema !== "object" || optionalSchema.TAG !== "option" ? optionalSchema : optionalSchema._0.t;
let exit = 0;
if (typeof tagged !== "object") {
switch (tagged) {
case "int32" :
case "number" :
exit = 2;
break;
case "boolean" :
exit = 1;
break;
default:
return {};
}
} else {
switch (tagged.TAG) {
case "literal" :
switch (tagged._0.kind) {
case "Number" :
exit = 2;
break;
case "Boolean" :
exit = 1;
break;
default:
return {};
}
break;
default:
return {};
}
}
switch (exit) {
case 1 :
return {
p: unknown => {
switch (unknown) {
case "false" :
return false;
case "true" :
return true;
default:
return unknown;
}
}
};
case 2 :
return {
p: unknown => {
let float = (+unknown);
if (Number.isNaN(float)) {
return unknown;
} else {
return float;
}
}
};
}
});
}
function getSchemaField(schema, fieldName) {
return schema.t.fields[fieldName];
}
function isNestedFlattenSupported(schema) {
let match = schema.t;
if (typeof match !== "object") {
return false;
}
if (match.TAG !== "object") {
return false;
}
if (match.advanced) {
return false;
}
let match$1 = S$RescriptSchema.reverse(schema).t;
if (typeof match$1 !== "object" || match$1.TAG !== "object") {
return false;
} else {
return !match$1.advanced;
}
}
let bearerAuthSchema = S$RescriptSchema.transform(S$RescriptSchema.string, s => ({
p: string => {
let match = string.split(" ");
if (match.length !== 2) {
return s.fail("Invalid Bearer token", undefined);
}
let match$1 = match[0];
if (match$1 === "Bearer") {
return match[1];
} else {
return s.fail("Invalid Bearer token", undefined);
}
},
s: token => `Bearer ` + token
}));
let basicAuthSchema = S$RescriptSchema.transform(S$RescriptSchema.string, s => ({
p: string => {
let match = string.split(" ");
if (match.length !== 2) {
return s.fail("Invalid Basic token", undefined);
}
let match$1 = match[0];
if (match$1 === "Basic") {
return match[1];
} else {
return s.fail("Invalid Basic token", undefined);
}
},
s: token => `Basic ` + token
}));
function params(route) {
let params$1 = route._rest;
if (params$1 !== undefined) {
return params$1;
}
let definition = route();
let params$2;
if (definition.output) {
let p = definition.operationId;
let path = `/` + (
p !== undefined ? p : route.name
);
let inputSchema = S$RescriptSchema.object(s => s.f("body", definition.input));
inputSchema.t.unknownKeys = "Strip";
inputSchema.f = undefined;
let outputSchema = S$RescriptSchema.object(s => s.f("data", definition.output));
outputSchema.t.unknownKeys = "Strip";
outputSchema.f = undefined;
let response_status = 200;
let response_dataSchema = definition.input;
let response = {
status: response_status,
description: undefined,
dataSchema: response_dataSchema,
emptyData: false,
schema: outputSchema
};
let responsesMap = {};
responsesMap["200"] = response;
params$2 = {
method: "POST",
path: path,
pathItems: [path],
inputSchema: inputSchema,
outputSchema: outputSchema,
responses: [response],
responsesMap: responsesMap,
isRawBody: false,
summary: definition.summary,
description: definition.description,
deprecated: definition.deprecated,
operationId: definition.operationId,
tags: definition.tags
};
} else {
let pathItems = [];
let pathParams = {};
parsePath(definition.path, pathItems, pathParams);
let isRawBody = false;
let inputSchema$1 = S$RescriptSchema.object(s => definition.input({
field: (fieldName, schema) => s.nested("body").f(fieldName, schema),
body: schema => {
if (isNestedFlattenSupported(schema)) {
return s.nested("body").flatten(schema);
} else {
return s.f("body", schema);
}
},
rawBody: schema => {
let match = schema.t;
let isNonStringBased;
isNonStringBased = typeof match !== "object" ? match !== "string" : (
match.TAG === "literal" ? match._0.kind !== "String" : true
);
if (isNonStringBased) {
panic("Only string-based schemas are allowed in rawBody", undefined);
}
((isRawBody = true));
return s.f("body", schema);
},
header: (fieldName, schema) => s.nested("headers").f(fieldName.toLowerCase(), coerceSchema(schema)),
query: (fieldName, schema) => s.nested("query").f(fieldName, coerceSchema(schema)),
param: (fieldName, schema) => {
if (!(fieldName in pathParams)) {
panic(`Path parameter "` + fieldName + `" is not defined in the path`, undefined);
}
return s.nested("params").f(fieldName, coerceSchema(schema));
},
auth: auth => {
let tmp;
tmp = auth === "Bearer" ? bearerAuthSchema : basicAuthSchema;
return s.nested("headers").f("authorization", tmp);
}
}));
inputSchema$1.t.unknownKeys = "Strip";
inputSchema$1.f = undefined;
let match = getSchemaField(inputSchema$1, "headers");
if (match !== undefined) {
let schema = match.schema;
schema.t.unknownKeys = "Strip";
schema.f = undefined;
}
let match$1 = getSchemaField(inputSchema$1, "params");
if (match$1 !== undefined) {
match$1.schema.f = undefined;
}
let match$2 = getSchemaField(inputSchema$1, "query");
if (match$2 !== undefined) {
match$2.schema.f = undefined;
}
let responsesMap$1 = {};
let responses = [];
definition.responses.forEach(r => {
let builder = {
emptyData: true
};
let schema = S$RescriptSchema.object(s => {
let status = status$1 => {
builder.status = status$1;
register(responsesMap$1, status$1, builder);
s.tag("status", status$1);
};
let header = (fieldName, schema) => s.nested("headers").f(fieldName.toLowerCase(), coerceSchema(schema));
let definition = r({
status: status,
description: d => {
builder.description = d;
},
data: schema => {
builder.emptyData = false;
if (isNestedFlattenSupported(schema)) {
return s.nested("data").flatten(schema);
} else {
return s.f("data", schema);
}
},
field: (fieldName, schema) => {
builder.emptyData = false;
return s.nested("data").f(fieldName, schema);
},
header: header,
redirect: schema => {
status(307);
return header("location", coerceSchema(schema));
}
});
if (builder.emptyData) {
s.tag("data", null);
}
return definition;
});
if (builder.status === undefined) {
register(responsesMap$1, "default", builder);
}
schema.t.unknownKeys = "Strip";
schema.f = undefined;
let dataSchema = getSchemaField(schema, "data").schema;
builder.dataSchema = dataSchema;
let match = dataSchema.t;
if (typeof match === "object" && match.TAG === "literal") {
let dataTypeValidation = dataSchema.f;
schema.f = (b, inputVar) => dataTypeValidation(b, inputVar + `.data`);
}
let match$1 = getSchemaField(schema, "headers");
if (match$1 !== undefined) {
let schema$1 = match$1.schema;
schema$1.t.unknownKeys = "Strip";
schema$1.f = undefined;
}
builder.schema = schema;
responses.push(builder);
});
if (responses.length === 0) {
panic("At least single response should be registered", undefined);
}
params$2 = {
method: definition.method,
path: definition.path,
pathItems: pathItems,
inputSchema: inputSchema$1,
outputSchema: S$RescriptSchema.union(responses.map(r => r.schema)),
responses: responses,
responsesMap: responsesMap$1,
isRawBody: isRawBody,
summary: definition.summary,
description: definition.description,
deprecated: definition.deprecated,
operationId: definition.operationId,
tags: definition.tags,
jsonQuery: definition.jsonQuery
};
}
route._rest = params$2;
return params$2;
}
function tokeniseValue(key, value, append) {
if (Array.isArray(value)) {
value.forEach((v, idx) => tokeniseValue(key + `[` + idx.toString() + `]`, v, append));
return;
} else if (value === null) {
return append(key, "");
} else if (value === (void 0)) {
return;
} else if (typeof value === "object") {
Object.keys(value).forEach(k => tokeniseValue(key + `[` + encodeURIComponent(k) + `]`, value[k], append));
return;
} else {
return append(key, value);
}
}
function getCompletePath(baseUrl, pathItems, maybeQuery, maybeParams, jsonQueryOpt) {
let jsonQuery = jsonQueryOpt !== undefined ? jsonQueryOpt : false;
let path = baseUrl;
for (let idx = 0, idx_finish = pathItems.length; idx < idx_finish; ++idx) {
let pathItem = pathItems[idx];
if (typeof pathItem === "string") {
path = path + pathItem;
} else {
let name = pathItem.name;
let param = maybeParams && maybeParams[name];
if (param !== undefined) {
path = path + param;
} else {
panic(`Path parameter "` + name + `" is not defined in input`, undefined);
}
}
}
if (maybeQuery !== undefined) {
let queryItems = [];
let append = (key, value) => {
queryItems.push(key + "=" + encodeURIComponent(value));
};
let queryNames = Object.keys(maybeQuery);
for (let idx$1 = 0, idx_finish$1 = queryNames.length; idx$1 < idx_finish$1; ++idx$1) {
let queryName = queryNames[idx$1];
let value = maybeQuery[queryName];
let key = encodeURIComponent(queryName);
if (value !== (void 0)) {
if (jsonQuery) {
append(key, typeof value === "string" && value !== "true" && value !== "false" && value !== "null" && Number.isNaN(parseFloat(value)) ? value : JSON.stringify(value));
} else {
tokeniseValue(key, value, append);
}
}
}
if (queryItems.length !== 0) {
path = path + "?" + queryItems.join("&");
}
}
return path;
}
function url(route, input, baseUrlOpt) {
let baseUrl = baseUrlOpt !== undefined ? baseUrlOpt : "";
let match = params(route);
let data = S$RescriptSchema.reverseConvertOrThrow(input, match.inputSchema);
return getCompletePath(baseUrl, match.pathItems, data.query, data.params, false);
}
let global = {
c: undefined
};
function fetch$1(route, input, client) {
let match = params(route);
let responsesMap = match.responsesMap;
let client$1;
if (client !== undefined) {
client$1 = client;
} else {
let client$2 = global.c;
client$1 = client$2 !== undefined ? client$2 : panic(`Client is not set for the ` + match.path + ` fetch request. Please, use Rest.setGlobalClient or pass a client explicitly to the Rest.fetch arguments`, undefined);
}
let data = S$RescriptSchema.reverseConvertOrThrow(input, match.inputSchema);
if (data.body !== (void 0)) {
if (!match.isRawBody) {
data.body = (JSON.stringify(data["body"]));
}
if (data.headers === (void 0)) {
data.headers = {};
}
data.headers["content-type"] = "application/json";
}
return client$1.fetcher({
body: data.body,
headers: data.headers,
method: match.method,
path: getCompletePath(client$1.baseUrl, match.pathItems, data.query, data.params, match.jsonQuery)
}).then(fetcherResponse => {
let responseStatus = fetcherResponse.status;
let response = responsesMap[responseStatus] || responsesMap[(responseStatus / 100 | 0) + "XX"] || responsesMap["default"];
if (response !== undefined) {
try {
return S$RescriptSchema.parseOrThrow(fetcherResponse, response.schema);
} catch (raw_error) {
let error = Primitive_exceptions.internalToException(raw_error);
if (error.RE_EXN_ID === S$RescriptSchema.Raised) {
let error$1 = error._1;
let match = error$1.code;
if (typeof match === "object" && match.TAG === "InvalidType" && error$1.path === S$RescriptSchema.Path.empty) {
return panic(`Failed parsing response data. Reason: Expected ` + getSchemaField(match.expected, "data").schema.n() + `, received ` + match.received.data, undefined);
}
return panic(`Failed parsing response at ` + error$1.path + `. Reason: ` + S$RescriptSchema.$$Error.reason(error$1), {
response: fetcherResponse
});
}
throw error;
}
} else {
let error$2 = `Unexpected response status "` + fetcherResponse.status.toString() + `"`;
if (fetcherResponse.data && typeof fetcherResponse.data.message === "string") {
error$2 = error$2 + ". Message: " + fetcherResponse.data.message;
}
return panic(error$2, undefined);
}
});
}
function client(baseUrl, fetcherOpt) {
let fetcher = fetcherOpt !== undefined ? fetcherOpt : $$default;
return {
baseUrl: baseUrl,
fetcher: fetcher
};
}
function setGlobalClient(baseUrl, fetcher) {
let match = global.c;
if (match !== undefined) {
return panic("There's already a global client defined. You can have only one global client at a time.", undefined);
} else {
global.c = client(baseUrl, fetcher);
return;
}
}
let Response = {};
export {
Response,
params,
ApiFetcher,
url,
client,
setGlobalClient,
fetch$1 as fetch,
}
/* bearerAuthSchema Not a pure module */