Skip to content

Commit

Permalink
Improve api typing (#129)
Browse files Browse the repository at this point in the history
* Improve api typings

* Remove unused proposal code in deploy-web

* Enable noImplicitAny in tsconfig

* Fix eslint errors

* Add missing typing for axios calls

* Remove  eslint-disable-next-line

* PR Fixes
  • Loading branch information
Redm4x authored Mar 20, 2024
1 parent 5cd87d0 commit eca93a6
Show file tree
Hide file tree
Showing 34 changed files with 304 additions and 234 deletions.
68 changes: 34 additions & 34 deletions api/src/caching/memoryCacheEngine.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import mcache from "memory-cache";

export default function MemoryCacheEngine() {}

/**
* Used to retrieve data from memcache
* @param {*} key
*/
MemoryCacheEngine.prototype.getFromCache = (key) => {
const cachedBody = mcache.get(key);
if (cachedBody) {
return cachedBody;
export default class MemoryCacheEngine {
/**
* Used to retrieve data from memcache
* @param {*} key
*/
getFromCache(key: string) {
const cachedBody = mcache.get(key);
if (cachedBody) {
return cachedBody;
}
return false;
}
return false;
};

/**
* Used to store data in a memcache
* @param {*} key
* @param {*} data
* @param {*} duration
*/
MemoryCacheEngine.prototype.storeInCache = (key, data, duration) => {
mcache.put(key, data, duration);
};
/**
* Used to delete all keys in a memcache
*/
MemoryCacheEngine.prototype.clearAllKeyInCache = () => {
mcache.clear();
};
/**
* Used to delete specific key from memcache
* @param {*} key
*/
MemoryCacheEngine.prototype.clearAllKeyInCache = (key) => {
mcache.del(key);
};
/**
* Used to store data in a memcache
* @param {*} key
* @param {*} data
* @param {*} duration
*/
storeInCache<T>(key: string, data: T, duration?: number) {
mcache.put(key, data, duration);
}
/**
* Used to delete all keys in a memcache
*/
clearAllKeyInCache() {
mcache.clear();
}
/**
* Used to delete specific key from memcache
* @param {*} key
*/
clearKeyInCache(key: string) {
mcache.del(key);
}
}
6 changes: 5 additions & 1 deletion api/src/db/dbConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { chainModels, getChainModels, userModels } from "@shared/dbSchemas";
import { Template, TemplateFavorite, UserAddressName, UserSetting } from "@shared/dbSchemas/user";
import { chainDefinitions } from "@shared/chainDefinitions";

function isValidNetwork(network: string): network is keyof typeof csMap {
return network in csMap;
}

const csMap = {
mainnet: env.AkashDatabaseCS,
testnet: env.AkashTestnetDatabaseCS,
sandbox: env.AkashSandboxDatabaseCS
};

if (!(env.Network in csMap)) {
if (!isValidNetwork(env.Network)) {
throw new Error(`Invalid network: ${env.Network}`);
}

Expand Down
4 changes: 2 additions & 2 deletions api/src/middlewares/privateMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { env } from "@src/utils/env";
import { Context } from "hono";
import { Context, Next } from "hono";

export async function privateMiddleware(c: Context, next) {
export async function privateMiddleware(c: Context, next: Next) {
if (!env.SecretToken) {
await next();
} else if (c.req.query("token") === env.SecretToken) {
Expand Down
11 changes: 7 additions & 4 deletions api/src/routers/internalRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ internalRouter.get("/provider-versions", async (c) => {
.filter((x) => x.version !== nullVersionName) // Remove <UNKNOWN> version for sorting
.sort((a, b) => semver.compare(b.version, a.version))
.concat(results.filter((x) => x.version === nullVersionName)) // Add back <UNKNOWN> version at the end
.reduce((acc, x) => {
acc[x.version] = x;
return acc;
}, {});
.reduce(
(acc, x) => {
acc[x.version] = x;
return acc;
},
{} as { [key: string]: (typeof results)[number] }
);

return c.json(sorted);
});
Expand Down
24 changes: 4 additions & 20 deletions api/src/routes/v1/graphData.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { getGraphData } from "@src/services/db/statsService";

const authorizedDataNames = [
"dailyUAktSpent",
"dailyUUsdcSpent",
"dailyUUsdSpent",
"dailyLeaseCount",
"totalUAktSpent",
"totalUUsdcSpent",
"totalUUsdSpent",
"activeLeaseCount",
"totalLeaseCount",
"activeCPU",
"activeGPU",
"activeMemory",
"activeStorage"
];
import { AuthorizedGraphDataNames, getGraphData, isValidGraphDataName } from "@src/services/db/statsService";

const route = createRoute({
method: "get",
path: "/graph-data/{dataName}",
tags: ["Analytics"],
request: {
params: z.object({
dataName: z.string().openapi({ example: "dailyUAktSpent", enum: authorizedDataNames })
dataName: z.string().openapi({ example: "dailyUAktSpent", enum: AuthorizedGraphDataNames })
})
},
responses: {
Expand Down Expand Up @@ -53,9 +37,9 @@ const route = createRoute({
export default new OpenAPIHono().openapi(route, async (c) => {
const dataName = c.req.valid("param").dataName;

if (!authorizedDataNames.includes(dataName)) {
if (!isValidGraphDataName(dataName)) {
console.log("Rejected graph request: " + dataName);
return c.text("Graph not found", 404);
return c.text("Graph not found: " + dataName, 404);
}

const graphData = await getGraphData(dataName);
Expand Down
4 changes: 3 additions & 1 deletion api/src/routes/v1/nodes/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getMainnetNodes, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/cloudmos/main/config/mainnet-nodes.json"); //TODO: Add typing
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/mainnet-nodes.json"
);
return res.data;
});
return c.json(response);
Expand Down
4 changes: 3 additions & 1 deletion api/src/routes/v1/nodes/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getSandboxNodes, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/cloudmos/main/config/sandbox-nodes.json");
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/sandbox-nodes.json"
);
return res.data;
});
return c.json(response);
Expand Down
4 changes: 3 additions & 1 deletion api/src/routes/v1/nodes/testnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getTestnetNodes, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/cloudmos/main/config/testnet-nodes.json");
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/testnet-nodes.json"
);
return res.data;
});
return c.json(response);
Expand Down
2 changes: 1 addition & 1 deletion api/src/routes/v1/version/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 5, cacheKeys.getMainnetVersion, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt");
const res = await axios.get<string>("https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt");
return res.data;
});
return c.text(response);
Expand Down
2 changes: 1 addition & 1 deletion api/src/routes/v1/version/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 5, cacheKeys.getSandboxVersion, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt");
const res = await axios.get<string>("https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt");
return res.data;
});
return c.text(response);
Expand Down
2 changes: 1 addition & 1 deletion api/src/routes/v1/version/testnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const route = createRoute({

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 5, cacheKeys.getTestnetVersion, async () => {
const res = await axios.get("https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt");
const res = await axios.get<string>("https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt");
return res.data;
});
return c.text(response);
Expand Down
10 changes: 5 additions & 5 deletions api/src/services/db/deploymentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as v2 from "@src/proto/akash/v1beta2";
import { decodeMsg } from "@src/utils/protobuf";
import { Transaction } from "@shared/dbSchemas/base";
import { Deployment, Lease } from "@shared/dbSchemas/akash";
import { Op } from "sequelize";
import { Op, WhereOptions } from "sequelize";
import { Block, Message } from "@shared/dbSchemas";

export async function getDeploymentRelatedMessages(owner: string, dseq: string) {
Expand Down Expand Up @@ -71,9 +71,9 @@ export async function getDeploymentRelatedMessages(owner: string, dseq: string)
}

export async function getProviderDeploymentsCount(provider: string, status?: "active" | "closed") {
const leaseFilter = { providerAddress: provider };
const leaseFilter: WhereOptions<Lease> = { providerAddress: provider };
if (status) {
leaseFilter["closedHeight"] = status === "active" ? null : { [Op.ne]: null };
leaseFilter.closedHeight = status === "active" ? null : { [Op.ne]: null };
}

const result = await Deployment.count({
Expand All @@ -84,10 +84,10 @@ export async function getProviderDeploymentsCount(provider: string, status?: "ac
}

export async function getProviderDeployments(provider: string, skip: number, limit: number, status?: "active" | "closed") {
const leaseFilter = { providerAddress: provider };
const leaseFilter: WhereOptions<Lease> = { providerAddress: provider };

if (status) {
leaseFilter["closedHeight"] = status === "active" ? null : { [Op.ne]: null };
leaseFilter.closedHeight = status === "active" ? null : { [Op.ne]: null };
}

const deploymentDseqs = await Deployment.findAll({
Expand Down
10 changes: 5 additions & 5 deletions api/src/services/db/providerDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ export async function getProviderRegions() {
const providerAttributesSchema = await getProviderAttributesSchema();
const regions = providerAttributesSchema["location-region"].values;

const providerRegions = await Provider.findAll({
const providers = await Provider.findAll({
attributes: ["owner"],
include: [{ model: ProviderAttribute, attributes: [["value", "location_region"]], where: { key: "location-region" } }],
raw: true
include: [{ model: ProviderAttribute, attributes: ["value"], where: { key: "location-region" } }]
});

console.log(JSON.stringify(providers, null, 2));
const result = regions.map((region) => {
const providers = providerRegions.filter((x) => x["providerAttributes.location_region"] === region.key).map((x) => x.owner);
return { ...region, providers };
const filteredProviders = providers.filter((p) => p.providerAttributes.some((attr) => attr.value === region.key)).map((x) => x.owner);
return { ...region, providers: filteredProviders };
});

return result;
Expand Down
57 changes: 49 additions & 8 deletions api/src/services/db/statsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,47 @@ export const getDashboardData = async () => {
};
};

export async function getGraphData(dataName: string): Promise<GraphData> {
type AuthorizedGraphDataName =
| "dailyUAktSpent"
| "dailyUUsdcSpent"
| "dailyUUsdSpent"
| "dailyLeaseCount"
| "totalUAktSpent"
| "totalUUsdcSpent"
| "totalUUsdSpent"
| "activeLeaseCount"
| "totalLeaseCount"
| "activeCPU"
| "activeGPU"
| "activeMemory"
| "activeStorage";

export const AuthorizedGraphDataNames: AuthorizedGraphDataName[] = [
"dailyUAktSpent",
"dailyUUsdcSpent",
"dailyUUsdSpent",
"dailyLeaseCount",
"totalUAktSpent",
"totalUUsdcSpent",
"totalUUsdSpent",
"activeLeaseCount",
"totalLeaseCount",
"activeCPU",
"activeGPU",
"activeMemory",
"activeStorage"
];

export function isValidGraphDataName(x: string): x is AuthorizedGraphDataName {
return AuthorizedGraphDataNames.includes(x as AuthorizedGraphDataName);
}

export async function getGraphData(dataName: AuthorizedGraphDataName): Promise<GraphData> {
console.log("getGraphData: " + dataName);

let attributes = [dataName];
let attributes: (keyof Block)[] = [];
let isRelative = false;
let getter = (block: Block) => block[dataName] as number;
let getter: (block: Block) => number = null;

switch (dataName) {
case "dailyUAktSpent":
Expand All @@ -107,6 +142,9 @@ export async function getGraphData(dataName: string): Promise<GraphData> {
attributes = ["activeEphemeralStorage", "activePersistentStorage"];
getter = (block: Block) => block.activeEphemeralStorage + block.activePersistentStorage;
break;
default:
attributes = [dataName];
getter = (block: Block) => block[dataName];
}

const result = await Day.findAll({
Expand Down Expand Up @@ -158,7 +196,7 @@ export const getProviderGraphData = async (dataName: ProviderStatsKey) => {
60 * 5, // 5 minutes
cacheKeys.getProviderGraphData,
async () => {
return (await chainDb.query(
return await chainDb.query<ProviderStats>(
`SELECT d."date", (SUM("activeCPU") + SUM("pendingCPU") + SUM("availableCPU")) AS "cpu", (SUM("activeGPU") + SUM("pendingGPU") + SUM("availableGPU")) AS "gpu", (SUM("activeMemory") + SUM("pendingMemory") + SUM("availableMemory")) AS memory, (SUM("activeStorage") + SUM("pendingStorage") + SUM("availableStorage")) as storage, COUNT(*) as count
FROM "day" d
INNER JOIN (
Expand All @@ -174,7 +212,7 @@ export const getProviderGraphData = async (dataName: ProviderStatsKey) => {
{
type: QueryTypes.SELECT
}
)) as ProviderStats[];
);
},
true
);
Expand All @@ -183,12 +221,15 @@ export const getProviderGraphData = async (dataName: ProviderStatsKey) => {
return {
currentValue: 0,
compareValue: 0,
snapshots: []
snapshots: [] as {
date: string;
value: number;
}[]
};
}

const currentValue = result[result.length - 1] as ProviderStats;
const compareValue = result[result.length - 2] as ProviderStats;
const currentValue = result[result.length - 1];
const compareValue = result[result.length - 2];

const stats = result.map((day) => ({
date: day.date,
Expand Down
4 changes: 2 additions & 2 deletions api/src/services/db/templateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export async function saveTemplateDesc(id: string, userId: string, description:
});

if (!id || !template) {
return null;
return;
}

template.description = description;
Expand Down Expand Up @@ -140,7 +140,7 @@ export async function addTemplateFavorite(userId: string, templateId: string) {
});

if (template) {
return null;
return;
}

await TemplateFavorite.create({
Expand Down
Loading

0 comments on commit eca93a6

Please sign in to comment.