Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const attributeSchemaType = z.object({
export const ProviderAttributesSchemaResponseSchema = z.object({
host: attributeSchemaType,
email: attributeSchemaType,
"discord-username": attributeSchemaType,
organization: attributeSchemaType,
website: attributeSchemaType,
tier: attributeSchemaType,
Expand All @@ -34,15 +35,18 @@ export const ProviderAttributesSchemaResponseSchema = z.object({
"hardware-cpu-arch": attributeSchemaType,
"hardware-gpu": attributeSchemaType,
"hardware-gpu-model": attributeSchemaType,
"hardware-disk": attributeSchemaType,
"hardware-gpu-capability": attributeSchemaType,
"hardware-persistent-storage-class": attributeSchemaType,
"hardware-persistent-storage-capability": attributeSchemaType,
"hardware-cuda": attributeSchemaType,
datacenter: attributeSchemaType,
"hardware-memory": attributeSchemaType,
"network-provider": attributeSchemaType,
"network-speed-up": attributeSchemaType,
"network-speed-down": attributeSchemaType,
"feat-persistent-storage": attributeSchemaType,
"feat-persistent-storage-type": attributeSchemaType,
"workload-support-chia": attributeSchemaType,
"workload-support-chia-capabilities": attributeSchemaType,
"feat-shm": attributeSchemaType,
"hardware-shm": attributeSchemaType,
"feat-endpoint-ip": attributeSchemaType,
"feat-endpoint-custom-domain": attributeSchemaType
});
Expand Down
20 changes: 12 additions & 8 deletions apps/api/src/provider/http-schemas/provider.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,19 @@ export const ProviderListResponseSchema = z.array(
hardwareCpuArch: z.string().nullable(),
hardwareGpuVendor: z.string().nullable(),
hardwareGpuModels: z.array(z.string()).nullable(),
hardwareDisk: z.array(z.string()).nullable(),
hardwareGpuCapabilities: z.array(z.string()).nullable(),
hardwarePersistentStorageClass: z.string().nullable(),
featPersistentStorage: z.boolean(),
featPersistentStorageType: z.array(z.string()).nullable(),
featShm: z.boolean(),
hardwareShm: z.array(z.string()).nullable(),
hardwareCuda: z.string().nullable(),
datacenter: z.string().nullable(),
hardwareMemory: z.string().nullable(),
networkProvider: z.string().nullable(),
networkSpeedDown: z.number(),
networkSpeedUp: z.number(),
tier: z.string().nullable(),
featEndpointCustomDomain: z.boolean(),
workloadSupportChia: z.boolean(),
workloadSupportChiaCapabilities: z.array(z.string()).nullable(),
featEndpointIp: z.boolean()
})
);
Expand Down Expand Up @@ -163,17 +165,19 @@ export const ProviderResponseSchema = z.object({
hardwareCpuArch: z.string().nullable(),
hardwareGpuVendor: z.string().nullable(),
hardwareGpuModels: z.array(z.string()),
hardwareDisk: z.array(z.string()),
hardwareGpuCapabilities: z.array(z.string()),
hardwarePersistentStorageClass: z.string().nullable(),
featPersistentStorage: z.boolean(),
featPersistentStorageType: z.array(z.string()),
featShm: z.boolean(),
hardwareShm: z.array(z.string()),
hardwareCuda: z.string().nullable(),
datacenter: z.string().nullable(),
hardwareMemory: z.string().nullable(),
networkProvider: z.string().nullable(),
networkSpeedDown: z.number(),
networkSpeedUp: z.number(),
tier: z.string().nullable(),
featEndpointCustomDomain: z.boolean(),
workloadSupportChia: z.boolean(),
workloadSupportChiaCapabilities: z.array(z.string()),
featEndpointIp: z.boolean(),
uptime: z.array(
z.object({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { GitHubHttpService } from "@akashnetwork/http-sdk";
import { minutesToSeconds } from "date-fns";
import fs from "fs/promises";
import path from "path";
import { singleton } from "tsyringe";

import { Memoize } from "@src/caching/helpers";
Expand All @@ -10,6 +12,11 @@ export class ProviderAttributesSchemaService {

@Memoize({ ttlInSeconds: minutesToSeconds(5) })
async getProviderAttributesSchema() {
if (process.env.DEPLOYMENT_ENV === "test") {
const schemaPath = path.join(__dirname, "../../../../../../config/provider-attributes.json");
return JSON.parse(await fs.readFile(schemaPath, "utf8"));
}

return await this.gitHubHttpService.getProviderAttributesSchema();
}
}
12 changes: 8 additions & 4 deletions apps/api/src/provider/services/provider/provider.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const schemaDetail = { key: "test", type: "string" as const, required: false, de
const providerAttributeSchemaStub: ProviderAttributesSchema = {
host: schemaDetail,
email: schemaDetail,
"discord-username": schemaDetail,
organization: schemaDetail,
website: schemaDetail,
tier: schemaDetail,
Expand All @@ -37,15 +38,18 @@ const providerAttributeSchemaStub: ProviderAttributesSchema = {
"hardware-cpu-arch": schemaDetail,
"hardware-gpu": schemaDetail,
"hardware-gpu-model": schemaDetail,
"hardware-disk": schemaDetail,
"hardware-gpu-capability": schemaDetail,
"hardware-persistent-storage-class": schemaDetail,
"hardware-persistent-storage-capability": schemaDetail,
"hardware-cuda": schemaDetail,
datacenter: schemaDetail,
"hardware-memory": schemaDetail,
"network-provider": schemaDetail,
"network-speed-up": schemaDetail,
"network-speed-down": schemaDetail,
"feat-persistent-storage": schemaDetail,
"feat-persistent-storage-type": schemaDetail,
"workload-support-chia": schemaDetail,
"workload-support-chia-capabilities": schemaDetail,
"feat-shm": schemaDetail,
"hardware-shm": schemaDetail,
"feat-endpoint-ip": schemaDetail,
"feat-endpoint-custom-domain": schemaDetail
};
Expand Down
10 changes: 6 additions & 4 deletions apps/api/src/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,19 @@ export interface ProviderList {
hardwareCpuArch: string | null;
hardwareGpuVendor: string | null;
hardwareGpuModels: string[] | null;
hardwareDisk: string[] | null;
hardwareGpuCapabilities: string[] | null;
hardwarePersistentStorageClass: string | null;
featPersistentStorage: boolean;
featPersistentStorageType: string[] | null;
featShm: boolean;
hardwareShm: string[] | null;
hardwareCuda: string | null;
datacenter: string | null;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
hardwareMemory: string | null;
networkProvider: string | null;
networkSpeedDown: number;
networkSpeedUp: number;
tier: string | null;
featEndpointCustomDomain: boolean;
workloadSupportChia: boolean;
workloadSupportChiaCapabilities: string[] | null;
featEndpointIp: boolean;
}

Expand Down
54 changes: 48 additions & 6 deletions apps/api/src/utils/map/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const mapProviderToList = (
host: getStringAttribute("host", attrMap, providerAttributeSchema),
organization: getStringAttribute("organization", attrMap, providerAttributeSchema),
statusPage: getStringAttribute("status-page", attrMap, providerAttributeSchema),
locationRegion: getStringAttribute("location-region", attrMap, providerAttributeSchema),
locationRegion: getLocationRegion(attrMap, providerAttributeSchema),
country: getStringAttribute("country", attrMap, providerAttributeSchema),
city: getStringAttribute("city", attrMap, providerAttributeSchema),
timezone: getStringAttribute("timezone", attrMap, providerAttributeSchema),
Expand All @@ -92,17 +92,19 @@ export const mapProviderToList = (
hardwareCpuArch: getStringAttribute("hardware-cpu-arch", attrMap, providerAttributeSchema),
hardwareGpuVendor: getStringAttribute("hardware-gpu", attrMap, providerAttributeSchema),
hardwareGpuModels: getStringArrayAttribute("hardware-gpu-model", provider, providerAttributeSchema),
hardwareDisk: getStringArrayAttribute("hardware-disk", provider, providerAttributeSchema),
featPersistentStorage: getBooleanAttribute("feat-persistent-storage", attrMap, providerAttributeSchema),
featPersistentStorageType: getStringArrayAttribute("feat-persistent-storage-type", provider, providerAttributeSchema),
hardwareGpuCapabilities: getStringArrayAttribute("hardware-gpu-capability", provider, providerAttributeSchema),
hardwarePersistentStorageClass: getStringAttribute("hardware-persistent-storage-class", attrMap, providerAttributeSchema),
featPersistentStorage: getPersistentStorageSupport(attrMap, providerAttributeSchema),
featShm: getShmSupport(attrMap, providerAttributeSchema),
hardwareShm: getStringArrayAttribute("hardware-shm", provider, providerAttributeSchema),
hardwareCuda: getStringAttribute("hardware-cuda", attrMap, providerAttributeSchema),
datacenter: getStringAttribute("datacenter", attrMap, providerAttributeSchema),
hardwareMemory: getStringAttribute("hardware-memory", attrMap, providerAttributeSchema),
networkProvider: getStringAttribute("network-provider", attrMap, providerAttributeSchema),
networkSpeedDown: getNumberAttribute("network-speed-down", attrMap, providerAttributeSchema),
networkSpeedUp: getNumberAttribute("network-speed-up", attrMap, providerAttributeSchema),
tier: getStringAttribute("tier", attrMap, providerAttributeSchema),
featEndpointCustomDomain: getBooleanAttribute("feat-endpoint-custom-domain", attrMap, providerAttributeSchema),
workloadSupportChia: getBooleanAttribute("workload-support-chia", attrMap, providerAttributeSchema),
workloadSupportChiaCapabilities: getStringArrayAttribute("workload-support-chia-capabilities", provider, providerAttributeSchema),
featEndpointIp: getBooleanAttribute("feat-endpoint-ip", attrMap, providerAttributeSchema)
};
};
Expand All @@ -125,12 +127,52 @@ function getStringAttribute(key: keyof ProviderAttributesSchema, attrMap: Map<st
return attrMap.get(schemaKey) || null;
}

function getLocationRegion(attrMap: Map<string, string>, schema: ProviderAttributesSchema): string | null {
const locationRegion = getStringAttribute("location-region", attrMap, schema);
if (locationRegion) {
return locationRegion;
}

// Legacy providers may still have `region` on-chain; console expects `location-region`.
return attrMap.get("region") || null;
Comment thread
Zblocker64 marked this conversation as resolved.
Outdated
}
Comment on lines +131 to +133

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Normalize legacy region values in the fallback path.

Line 137 returns the old region value verbatim. This PR’s own fixtures migrate region: "us-west" to location-region: "na-us-west", so legacy providers will still emit the pre-migration value through locationRegion unless the fallback translates it first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/utils/map/provider.ts` around lines 130 - 138, The fallback in
getLocationRegion currently returns attrMap.get("region") verbatim, so legacy
values like "us-west" leak through; change the fallback to normalize legacy
region strings to the new location-region format before returning. Update
getLocationRegion to read the old region value (attrMap.get("region")), pass it
through a normalization helper (e.g., normalizeLegacyRegion or reuse existing
migration logic used by fixtures) to convert values like "us-west" ->
"na-us-west", and return the normalized value or null; reference
getLocationRegion, "location-region", and "region" when locating the code to
modify.


function getBooleanAttribute(key: keyof ProviderAttributesSchema, attrMap: Map<string, string>, schema: ProviderAttributesSchema): boolean {
const schemaKey = schema[key].key;
const value = attrMap.get(schemaKey);
return value === "true";
}

function hasShmCapability(attrMap: Map<string, string>): boolean {
for (const [key, value] of attrMap.entries()) {
if (/^capabilities\/storage\/\d+\/class$/.test(key) && value === "ram") {
return true;
}
}

return false;
}

function getShmSupport(attrMap: Map<string, string>, schema: ProviderAttributesSchema): boolean {
if (getBooleanAttribute("feat-shm", attrMap, schema)) {
return true;
}

return hasShmCapability(attrMap);
}

function getPersistentStorageSupport(attrMap: Map<string, string>, schema: ProviderAttributesSchema): boolean {
if (getBooleanAttribute("feat-persistent-storage", attrMap, schema)) {
return true;
}

if (getBooleanAttribute("hardware-persistent-storage-capability", attrMap, schema)) {
return true;
}

return attrMap.get("capabilities/storage/1/persistent") === "true";
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

function getNumberAttribute(key: keyof ProviderAttributesSchema, attrMap: Map<string, string>, schema: ProviderAttributesSchema): number {
const schemaKey = schema[key].key;
const value = attrMap.get(schemaKey);
Expand Down
Loading
Loading