@lodestar/api
Version:
A Typescript REST client for the Ethereum Consensus API
97 lines • 3.1 kB
JavaScript
export var TokenType;
(function (TokenType) {
TokenType["String"] = "String";
TokenType["Variable"] = "Variable";
})(TokenType || (TokenType = {}));
export function urlToTokens(path) {
const tokens = [];
let ptr = 0;
let inVariable = false;
for (let i = 0, len = path.length; i < len; i++) {
switch (path[i]) {
case "{": {
if (inVariable) {
throw Error(`Invalid path variable not closed: ${path}`);
}
if (i > ptr) {
tokens.push({ type: TokenType.String, str: path.slice(ptr, i) });
}
ptr = i + 1;
inVariable = true;
break;
}
case "}": {
if (!inVariable) {
throw Error(`Invalid path variable not open: ${path}`);
}
if (ptr === i) {
throw Error(`Empty variable: ${path}`);
}
tokens.push({ type: TokenType.Variable, var: path.slice(ptr, i) });
inVariable = false;
ptr = i + 1;
break;
}
}
}
if (inVariable) {
throw Error(`Invalid path variable not closed: ${path}`);
}
if (ptr < path.length) {
tokens.push({ type: TokenType.String, str: path.slice(ptr) });
}
return tokens;
}
/**
* Compile a route URL formatter with syntax `/path/{var1}/{var2}`.
* Returns a function that expects an object `{var1: 1, var2: 2}`, and returns`/path/1/2`.
*
* It's cheap enough to be negligible. For the sample input below it costs:
* - compile: 1010 ns / op
* - execute: 105 ns / op
* - execute with template literal: 12 ns / op
* @param path `/eth/v1/validator/:name/attester/:epoch`
*/
export function compileRouteUrlFormatter(path) {
const tokens = urlToTokens(path);
// Return a faster function if there's not ':' token
if (tokens.length === 1 && tokens[0].type === TokenType.String) {
return () => path;
}
const fns = tokens.map((token) => {
switch (token.type) {
case TokenType.String:
return () => token.str;
case TokenType.Variable: {
const argKey = token.var;
return (args) => args[argKey];
}
}
});
return function urlFormatter(args) {
// Don't use .map() or .join(), it's x3 slower
let s = "";
for (const fn of fns)
s += fn(args);
return s;
};
}
/**
* Converts notation used in OpenAPI spec '/states/{state_id}',
* into colon notation used by fastify '/states/:state_id'
*/
export function toColonNotationPath(path) {
const tokens = urlToTokens(path);
return tokens
.map((token) => {
switch (token.type) {
case TokenType.String:
return token.str;
case TokenType.Variable: {
return `:${token.var}`;
}
}
})
.join("");
}
//# sourceMappingURL=urlFormat.js.map