diff --git a/apps/api/package.json b/apps/api/package.json index 54740921e1..64e0ad8be6 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -34,8 +34,7 @@ "test:unit": "jest --selectProjects unit", "test:unit:cov": "jest --selectProjects unit --coverage", "test:unit:watch": "jest --selectProjects unit --watch", - "test:watch": "jest --selectProjects unit functional --watch", - "validate:types-strict": "tsc -p tsconfig.strict.json && echo" + "test:watch": "jest --selectProjects unit functional --watch" }, "dependencies": { "@akashnetwork/akash-api": "^1.3.0", diff --git a/apps/api/src/app.ts b/apps/api/src/app.ts index c03478745a..940f085cc4 100644 --- a/apps/api/src/app.ts +++ b/apps/api/src/app.ts @@ -22,6 +22,7 @@ import { bidsRouter } from "./bid/routes/bids/bids.router"; import { certificateRouter } from "./certificate/routes/certificate.router"; import { FeatureFlagsService } from "./core/services/feature-flags/feature-flags.service"; import { shutdownServer } from "./core/services/shutdown-server/shutdown-server"; +import type { AppEnv } from "./core/types/app-context"; import { chainDb, syncUserSchema, userDb } from "./db/dbConnection"; import { deploymentSettingRouter } from "./deployment/routes/deployment-setting/deployment-setting.router"; import { deploymentsRouter } from "./deployment/routes/deployments/deployments.router"; @@ -75,7 +76,7 @@ import { transactionsRouter } from "./transaction"; import { createAnonymousUserRouter, getAnonymousUserRouter } from "./user"; import { validatorsRouter } from "./validator"; -const appHono = new Hono(); +const appHono = new Hono(); appHono.use( "/*", cors({ diff --git a/apps/api/src/console.ts b/apps/api/src/console.ts index 35c21aeafe..646fabe909 100644 --- a/apps/api/src/console.ts +++ b/apps/api/src/console.ts @@ -118,7 +118,7 @@ async function executeCliHandler(name: string, handler: () => Promise) logger.info({ event: "COMMAND_END", name }); } } catch (error) { - logger.error({ event: "COMMAND_ERROR", name, message: error.message, stack: error.stack }); + logger.error({ event: "COMMAND_ERROR", name, error }); process.exitCode = 1; } finally { await closeConnections(); diff --git a/apps/api/test/functional/api-key.spec.ts b/apps/api/test/functional/api-key.spec.ts index 08817fd3da..08262f6c7e 100644 --- a/apps/api/test/functional/api-key.spec.ts +++ b/apps/api/test/functional/api-key.spec.ts @@ -251,8 +251,8 @@ describe("API Keys", () => { const storedKey = await apiKeyRepository.findOneBy({ id: result.data.id }); expect(storedKey).toBeDefined(); - expect(storedKey.keyFormat).toMatch(OBFUSCATED_API_KEY_PATTERN); - expect(storedKey.hashedKey).not.toMatch(FULL_API_KEY_PATTERN); + expect(storedKey?.keyFormat).toMatch(OBFUSCATED_API_KEY_PATTERN); + expect(storedKey?.hashedKey).not.toMatch(FULL_API_KEY_PATTERN); }); it("should reject API key creation with past expiration date", async () => { diff --git a/apps/api/test/functional/bids.spec.ts b/apps/api/test/functional/bids.spec.ts index 4d7f5269f7..f3c2a25629 100644 --- a/apps/api/test/functional/bids.spec.ts +++ b/apps/api/test/functional/bids.spec.ts @@ -45,8 +45,9 @@ describe("Bids API", () => { ); }); - jest.spyOn(apiKeyAuthService, "getAndValidateApiKeyFromHeader").mockImplementation(async (key: string) => { - return Promise.resolve(knownApiKeys[key]); + jest.spyOn(apiKeyAuthService, "getAndValidateApiKeyFromHeader").mockImplementation(async (key: string | undefined) => { + if (!key || !knownApiKeys[key]) throw new Error(`Unknown API key ${key}`); + return knownApiKeys[key]; }); const fakeWalletRepository = { diff --git a/apps/api/test/functional/blocks.spec.ts b/apps/api/test/functional/blocks.spec.ts index 7c9d782541..24c1361f4e 100644 --- a/apps/api/test/functional/blocks.spec.ts +++ b/apps/api/test/functional/blocks.spec.ts @@ -1,6 +1,5 @@ import type { AkashBlock } from "@akashnetwork/database/dbSchemas/akash"; import { addMinutes, addSeconds, getUnixTime, subSeconds } from "date-fns"; -import { map } from "lodash"; import { app } from "@src/app"; @@ -35,11 +34,11 @@ describe("Blocks", () => { return testData; }; - const expectBlocks = (blocksFound: AkashBlock[], blocksExpected: AkashBlock[]) => { - expect(blocksFound.length).toBe(blocksExpected.length); + const expectBlocks = (blocksFound?: AkashBlock[], blocksExpected?: AkashBlock[]) => { + expect(blocksFound?.length).toBe(blocksExpected?.length); - const heightsFound = map(blocksFound, "height"); - blocksExpected.forEach(blockExpected => { + const heightsFound = blocksFound?.map(block => block.height) || []; + blocksExpected?.forEach(blockExpected => { expect(heightsFound).toContain(blockExpected.height); }); }; @@ -52,7 +51,7 @@ describe("Blocks", () => { const blocksFound = (await response.json()) as AkashBlock[]; expect(response.status).toBe(200); - expectBlocks(blocksFound, blocks.slice(81, 101).reverse()); + expectBlocks(blocksFound, blocks?.slice(81, 101).reverse()); }); it("resolves list of most recent blocks", async () => { @@ -62,7 +61,7 @@ describe("Blocks", () => { const blocksFound = (await response.json()) as AkashBlock[]; expect(response.status).toBe(200); - expectBlocks(blocksFound, blocks.slice(99, 101).reverse()); + expectBlocks(blocksFound, blocks?.slice(99, 101).reverse()); }); it("will not resolve more than 100 blocks", async () => { @@ -81,14 +80,14 @@ describe("Blocks", () => { it("resolves block by height", async () => { const { blocks } = await setup(); - const response = await app.request(`/v1/blocks/${blocks[0].height}`, { + const response = await app.request(`/v1/blocks/${blocks?.[0].height}`, { method: "GET", headers: new Headers({ "Content-Type": "application/json" }) }); - const blockFound = (await response.json()) as any; + const blockFound = (await response.json()) as AkashBlock; expect(response.status).toBe(200); - expectBlocks([blocks[0]], [blockFound]); + expectBlocks(blocks?.slice(0, 1), [blockFound]); }); it("responds 400 for invalid height", async () => { diff --git a/apps/api/test/functional/dashboard-data.spec.ts b/apps/api/test/functional/dashboard-data.spec.ts index 191d6ee163..b6c5f98796 100644 --- a/apps/api/test/functional/dashboard-data.spec.ts +++ b/apps/api/test/functional/dashboard-data.spec.ts @@ -214,11 +214,11 @@ describe("Dashboard Data", () => { activeCPU: blocks[2].activeCPU, activeGPU: blocks[2].activeGPU, activeMemory: blocks[2].activeMemory, - activeStorage: blocks[2].activeEphemeralStorage + blocks[2].activePersistentStorage, - dailyLeaseCount: blocks[2].totalLeaseCount - blocks[1].totalLeaseCount, - dailyUAktSpent: blocks[2].totalUAktSpent - blocks[1].totalUAktSpent, - dailyUUsdSpent: blocks[2].totalUUsdSpent - blocks[1].totalUUsdSpent, - dailyUUsdcSpent: blocks[2].totalUUsdcSpent - blocks[1].totalUUsdcSpent, + activeStorage: (blocks[2].activeEphemeralStorage ?? 0) + (blocks[2].activePersistentStorage ?? 0), + dailyLeaseCount: (blocks[2].totalLeaseCount ?? 0) - (blocks[1].totalLeaseCount ?? 0), + dailyUAktSpent: (blocks[2].totalUAktSpent ?? 0) - (blocks[1].totalUAktSpent ?? 0), + dailyUUsdSpent: (blocks[2].totalUUsdSpent ?? 0) - (blocks[1].totalUUsdSpent ?? 0), + dailyUUsdcSpent: (blocks[2].totalUUsdcSpent ?? 0) - (blocks[1].totalUUsdcSpent ?? 0), totalUAktSpent: blocks[2].totalUAktSpent, totalUUsdSpent: blocks[2].totalUUsdSpent, totalUUsdcSpent: blocks[2].totalUUsdcSpent @@ -233,11 +233,11 @@ describe("Dashboard Data", () => { activeCPU: blocks[1].activeCPU, activeGPU: blocks[1].activeGPU, activeMemory: blocks[1].activeMemory, - activeStorage: blocks[1].activeEphemeralStorage + blocks[1].activePersistentStorage, - dailyLeaseCount: blocks[1].totalLeaseCount - blocks[0].totalLeaseCount, - dailyUAktSpent: blocks[1].totalUAktSpent - blocks[0].totalUAktSpent, - dailyUUsdSpent: blocks[1].totalUUsdSpent - blocks[0].totalUUsdSpent, - dailyUUsdcSpent: blocks[1].totalUUsdcSpent - blocks[0].totalUUsdcSpent, + activeStorage: (blocks[1].activeEphemeralStorage ?? 0) + (blocks[1].activePersistentStorage ?? 0), + dailyLeaseCount: (blocks[1].totalLeaseCount ?? 0) - (blocks[0].totalLeaseCount ?? 0), + dailyUAktSpent: (blocks[1].totalUAktSpent ?? 0) - (blocks[0].totalUAktSpent ?? 0), + dailyUUsdSpent: (blocks[1].totalUUsdSpent ?? 0) - (blocks[0].totalUUsdSpent ?? 0), + dailyUUsdcSpent: (blocks[1].totalUUsdcSpent ?? 0) - (blocks[0].totalUUsdcSpent ?? 0), totalUAktSpent: blocks[1].totalUAktSpent, totalUUsdSpent: blocks[1].totalUUsdSpent, totalUUsdcSpent: blocks[1].totalUUsdcSpent diff --git a/apps/api/test/functional/gpu.spec.ts b/apps/api/test/functional/gpu.spec.ts index 189516d598..1ac561f2b8 100644 --- a/apps/api/test/functional/gpu.spec.ts +++ b/apps/api/test/functional/gpu.spec.ts @@ -62,7 +62,7 @@ describe("GPU API", () => { expect(data.gpus.total.allocatable).toBe(6); expect(data.gpus.total.allocated).toBe(3); expect(data.gpus.details).toEqual({ - nvidia: expectedVendors.nvidia + nvidia: expectedVendors?.nvidia }); }); @@ -77,7 +77,7 @@ describe("GPU API", () => { expect(data.gpus.total.allocatable).toBe(2); expect(data.gpus.total.allocated).toBe(1); expect(data.gpus.details).toEqual({ - nvidia: [expectedVendors.nvidia[0]] + nvidia: [expectedVendors?.nvidia[0]] }); }); @@ -92,14 +92,14 @@ describe("GPU API", () => { expect(data.gpus.total.allocatable).toBe(4); expect(data.gpus.total.allocated).toBe(2); expect(data.gpus.details).toEqual({ - nvidia: [expectedVendors.nvidia[1]] + nvidia: [expectedVendors?.nvidia[1]] }); }); it(`returns GPU data when filtering by provider address`, async () => { const { providers, expectedVendors } = await setup(); - const response = await app.request(`/v1/gpu?provider=${providers[0].owner}`); + const response = await app.request(`/v1/gpu?provider=${providers?.[0].owner}`); expect(response.status).toBe(200); const data = (await response.json()) as ListGpuResponse; @@ -107,14 +107,14 @@ describe("GPU API", () => { expect(data.gpus.total.allocatable).toBe(6); expect(data.gpus.total.allocated).toBe(3); expect(data.gpus.details).toEqual({ - nvidia: expectedVendors.nvidia + nvidia: expectedVendors?.nvidia }); }); it(`returns GPU data when filtering by provider hostURI`, async () => { const { providers, expectedVendors } = await setup(); - const response = await app.request(`/v1/gpu?provider=${providers[1].hostUri}`); + const response = await app.request(`/v1/gpu?provider=${providers?.[1].hostUri}`); expect(response.status).toBe(200); const data = (await response.json()) as ListGpuResponse; @@ -122,7 +122,7 @@ describe("GPU API", () => { expect(data.gpus.total.allocatable).toBe(24); expect(data.gpus.total.allocated).toBe(12); expect(data.gpus.details).toEqual({ - amd: expectedVendors.amd + amd: expectedVendors?.amd }); }); }); diff --git a/apps/api/test/functional/provider-regions.spec.ts b/apps/api/test/functional/provider-regions.spec.ts index 724ae5cea3..5821d9bcb2 100644 --- a/apps/api/test/functional/provider-regions.spec.ts +++ b/apps/api/test/functional/provider-regions.spec.ts @@ -33,7 +33,7 @@ describe("ProviderRegions", () => { const expectRegion = (data: ProviderRegionsResponse, key: string, providers: string[]) => { const region = data.find(item => item.key === key); expect(region).toBeDefined(); - expect([...region.providers].sort()).toEqual([...providers].sort()); + expect([...(region?.providers || [])].sort()).toEqual([...providers].sort()); }; describe("GET /v1/provider-regions", () => { diff --git a/apps/api/test/functional/start-trial.spec.ts b/apps/api/test/functional/start-trial.spec.ts index 3ac264a788..129050af31 100644 --- a/apps/api/test/functional/start-trial.spec.ts +++ b/apps/api/test/functional/start-trial.spec.ts @@ -38,6 +38,8 @@ describe("start trial", () => { const getWalletsResponse = await app.request(`/v1/wallets?userId=${userId}`, { headers }); const userWallet = await userWalletsQuery.findFirst({ where: eq(userWalletsTable.userId, userId) }); const masterWalletAddress = await resolveWallet("MANAGED").getFirstAddress(); + if (!userWallet?.address) throw new Error("User wallet address is null-ish"); + const allowances = await Promise.all([ authzHttpService.getValidDepositDeploymentGrantsForGranterAndGrantee(masterWalletAddress, userWallet.address), authzHttpService.getValidFeeAllowancesForGrantee(userWallet.address) diff --git a/apps/api/test/functional/stripe-webhook.spec.ts b/apps/api/test/functional/stripe-webhook.spec.ts index 6e1770cfaf..793bd2d832 100644 --- a/apps/api/test/functional/stripe-webhook.spec.ts +++ b/apps/api/test/functional/stripe-webhook.spec.ts @@ -31,6 +31,8 @@ describe("Stripe webhook", () => { const getWebhookResponse = async (sessionId: string, eventType: string) => { const payload = generatePayload(sessionId, eventType); + const stripeWebhookSecret = process.env.STRIPE_WEBHOOK_SECRET; + if (!stripeWebhookSecret) throw new Error("STRIPE_WEBHOOK_SECRET env variable is not set"); return await app.request("/v1/stripe-webhook", { method: "POST", @@ -39,7 +41,7 @@ describe("Stripe webhook", () => { "Content-Type": "text/plain", "Stripe-Signature": stripe.webhooks.generateTestHeaderString({ payload, - secret: process.env.STRIPE_WEBHOOK_SECRET + secret: stripeWebhookSecret }) }) }); diff --git a/apps/api/test/functional/templates.spec.ts b/apps/api/test/functional/templates.spec.ts index 00df820cb3..78868944ab 100644 --- a/apps/api/test/functional/templates.spec.ts +++ b/apps/api/test/functional/templates.spec.ts @@ -43,8 +43,8 @@ describe("Templates API", () => { const expectCategory = (result: GetTemplatesFullResponse, expectedCategory: string, expectedTemplateIds: string[]) => { const category = result.find((c: { title: string }) => c.title === expectedCategory); - expect(category.templates).toHaveLength(expectedTemplateIds.length); - const templateIds = category.templates.map(({ id }) => id); + expect(category?.templates).toHaveLength(expectedTemplateIds.length); + const templateIds = category?.templates.map(({ id }) => id) || []; templateIds.forEach(templateId => { expect(expectedTemplateIds).toContain(templateId); }); diff --git a/apps/api/test/functional/user-init.spec.ts b/apps/api/test/functional/user-init.spec.ts index 77def7de3a..56ac9fa2e3 100644 --- a/apps/api/test/functional/user-init.spec.ts +++ b/apps/api/test/functional/user-init.spec.ts @@ -98,20 +98,20 @@ describe("User Init", () => { expect(res.status).toBe(200); expect(anonymousWallet.userId).toEqual(anonymousUser.id); - expect(wallet.userId).toEqual(existingUser.id); + expect(wallet?.userId).toEqual(existingUser?.id); }); it("should resolve with existing user without transferring anonymous wallet", async () => { const { user: anonymousUser, wallet: anonymousWallet, token: anonymousToken } = await walletService.createAnonymousUserAndWallet(); const existingUser = first(await db.insert(usersTable).values(dbPayload).returning()); - await userWalletRepository.create({ userId: existingUser.id, address: faker.string.alphanumeric(10) }); + await userWalletRepository.create({ userId: existingUser?.id, address: faker.string.alphanumeric(10) }); const res = await sendTokenInfo(anonymousToken); const anonymousWalletAfterResponse = await userWalletRepository.findById(anonymousWallet.id); expect(res.status).toBe(200); expect(anonymousWallet.userId).toEqual(anonymousUser.id); - expect(anonymousWalletAfterResponse.userId).toEqual(anonymousUser.id); + expect(anonymousWalletAfterResponse?.userId).toEqual(anonymousUser.id); }); async function sendTokenInfo(token?: string) { diff --git a/apps/api/test/functional/wallets-refill.spec.ts b/apps/api/test/functional/wallets-refill.spec.ts index d2fbab58d0..5af43ae782 100644 --- a/apps/api/test/functional/wallets-refill.spec.ts +++ b/apps/api/test/functional/wallets-refill.spec.ts @@ -29,7 +29,7 @@ describe("Wallets Refill", () => { let walletRecord = await userWalletRepository.findById(wallet.id); expect(wallet.creditAmount).toBe(config.TRIAL_DEPLOYMENT_ALLOWANCE_AMOUNT); - expect(walletRecord.feeAllowance).toBe(config.TRIAL_FEES_ALLOWANCE_AMOUNT); + expect(walletRecord?.feeAllowance).toBe(config.TRIAL_FEES_ALLOWANCE_AMOUNT); const limits = { fees: config.FEE_ALLOWANCE_REFILL_THRESHOLD @@ -61,10 +61,10 @@ describe("Wallets Refill", () => { ...records.map(async ({ wallet }) => { const walletRecord = await userWalletRepository.findById(wallet.id); - expect(walletRecord.feeAllowance).toBe(config.FEE_ALLOWANCE_REFILL_AMOUNT); + expect(walletRecord?.feeAllowance).toBe(config.FEE_ALLOWANCE_REFILL_AMOUNT); }), - userWalletRepository.findById(trialingWallet.wallet.id).then(walletRecord => { - expect(walletRecord.feeAllowance).toBe(config.FEE_ALLOWANCE_REFILL_THRESHOLD); + userWalletRepository.findById(trialingWallet?.wallet.id).then(walletRecord => { + expect(walletRecord?.feeAllowance).toBe(config.FEE_ALLOWANCE_REFILL_THRESHOLD); }) ]); }); diff --git a/apps/api/test/seeders/lease-api-response.seeder.ts b/apps/api/test/seeders/lease-api-response.seeder.ts index e4840e1488..d826253e9b 100644 --- a/apps/api/test/seeders/lease-api-response.seeder.ts +++ b/apps/api/test/seeders/lease-api-response.seeder.ts @@ -33,7 +33,7 @@ export interface LeaseOutput { amount: string; }; created_at: string; - closed_on: string; + closed_on?: string; }; escrow_payment: { account_id: { diff --git a/apps/api/test/services/wallet-testing.service.ts b/apps/api/test/services/wallet-testing.service.ts index f34a98a46c..8230ff905e 100644 --- a/apps/api/test/services/wallet-testing.service.ts +++ b/apps/api/test/services/wallet-testing.service.ts @@ -1,8 +1,8 @@ import type { Hono } from "hono"; import { decode } from "jsonwebtoken"; -export class WalletTestingService { - constructor(private readonly app: Hono) {} +export class WalletTestingService> { + constructor(private readonly app: T) {} async createUserAndWallet() { const { user, token } = await this.createRegisteredUser(); diff --git a/apps/api/tsconfig.build.json b/apps/api/tsconfig.build.json index 306ea8d76b..abc725c59d 100644 --- a/apps/api/tsconfig.build.json +++ b/apps/api/tsconfig.build.json @@ -5,7 +5,8 @@ "paths": { "@src/*": ["./src/*"], "@test/*": ["./test/*"] - } + }, + "strict": true }, "extends": "@akashnetwork/dev-config/tsconfig.base-node.json" } diff --git a/apps/api/tsconfig.strict.json b/apps/api/tsconfig.strict.json deleted file mode 100644 index 8a51549429..0000000000 --- a/apps/api/tsconfig.strict.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "extends": "./tsconfig.build.json", - "compilerOptions": { - "strict": true, - "noEmit": true - }, - "include": [ - "src/utils/**/*.ts", - "src/verify-rsa-jwt-cloudflare-worker-main/**/*.ts", - "src/types/**/*.ts", - "src/lib/**/*.ts", - "src/core/**/*.ts", - "src/db/**/*.ts", - "src/healthz/**/*.ts", - "src/middlewares/**/*.ts", - "src/features/**/*.ts", - "src/chain/**/*.ts", - "src/notifications/**/*.ts", - "src/services/**/*.ts", - "src/open-telemetry.ts", - "src/scheduler.ts", - "src/validator/**/*.ts", - "src/transaction/**/*.ts", - "src/pricing/**/*.ts", - "src/caching/**/*.ts", - "src/block/**/*.ts", - "src/bid/**/*.ts", - "src/auth/**/*.ts", - "src/proposal/**/*.ts", - "src/dashboard/**/*.ts", - "src/address/**/*.ts", - "src/billing/**/*.ts", - "src/user/**/*.ts", - "src/template/**/*.ts", - "src/provider/**/*.ts", - "src/auth/**/*.ts", - "src/certificate/**/*.ts", - "src/deployment/**/*.ts", - "src/gpu/**/*.ts", - "src/network/**/*.ts" - ] -} diff --git a/package.json b/package.json index 9dafdfba1a..2bf277e7ef 100644 --- a/package.json +++ b/package.json @@ -54,9 +54,6 @@ ], "./packages/database/**/*.ts": [ "npm run validate:types -w packages/database" - ], - "./apps/api/**/*.ts": [ - "npm run validate:types-strict -w apps/api" ] }, "dependencies": {