Skip to content

Commit

Permalink
fix: Setup next-axiom
Browse files Browse the repository at this point in the history
  • Loading branch information
FleetAdmiralJakob committed Jun 13, 2024
1 parent 7a783e8 commit 533c405
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 132 deletions.
6 changes: 3 additions & 3 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import createJiti from 'jiti'
import { fileURLToPath } from 'node:url'
import {fileURLToPath} from 'node:url'
import withBundleAnalyzer from '@next/bundle-analyzer'
import withPWAInit from '@ducanh2912/next-pwa'
import { withAxiom } from 'next-axiom'
import {withAxiomNextConfig} from 'next-axiom'

const withPWA = withPWAInit({
dest: 'public',
Expand All @@ -28,7 +28,7 @@ jiti('@weatherio/api/env')

/** @type {import("next").NextConfig} */
const config = withMyBundleAnalyzer(withPWA(
withAxiom({
withAxiomNextConfig({
reactStrictMode: true,

/** Enables hot reloading for local packages without a build step */
Expand Down
8 changes: 4 additions & 4 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"@t3-oss/env-nextjs": "^0.9.2",
"@tanstack/react-query": "^5.28.6",
"@tanstack/react-query-devtools": "^5.28.6",
"@trpc/client": "^11.0.0-next-beta.318",
"@trpc/next": "^11.0.0-next-beta.318",
"@trpc/react-query": "^11.0.0-next-beta.318",
"@trpc/server": "^11.0.0-next-beta.318",
"@trpc/client": "^11.0.0-rc.403",
"@trpc/next": "^11.0.0-rc.403",
"@trpc/react-query": "^11.0.0-rc.403",
"@trpc/server": "^11.0.0-rc.403",
"@vercel/analytics": "^1.2.2",
"@vercel/speed-insights": "^1.0.10",
"@weatherio/api": "workspace:^0.1.0",
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/pages/api/trpc/[trpc].ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { NextRequest } from "next/server";
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { withAxiomRouteHandler } from "next-axiom";

import { appRouter, createTRPCContext } from "@weatherio/api";

Expand All @@ -8,7 +9,7 @@ import { env } from "~/env";
export const config = { runtime: "edge" };

// export API handler
export default async function handler(req: NextRequest) {
const handler = withAxiomRouteHandler((req: NextRequest) => {
return fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
Expand All @@ -23,4 +24,6 @@ export default async function handler(req: NextRequest) {
}
: undefined,
});
}
});

export default handler;
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"engines": {
"node": ">=20.11.1"
},
"packageManager": "pnpm@9.1.2",
"packageManager": "pnpm@9.3.0",
"scripts": {
"build": "turbo build",
"clean": "git clean -xdf node_modules",
Expand All @@ -29,7 +29,7 @@
"@turbo/gen": "^1.12.5",
"@weatherio/prettier-config": "workspace:^0.1.0",
"prettier": "^3.2.5",
"turbo": "^1.13.2",
"turbo": "^2.0.3",
"typescript": "^5.4.2"
},
"prettier": "@weatherio/prettier-config"
Expand Down
5 changes: 3 additions & 2 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
},
"dependencies": {
"@t3-oss/env-nextjs": "^0.9.2",
"@trpc/client": "^11.0.0-next-beta.318",
"@trpc/server": "^11.0.0-next-beta.318",
"@trpc/client": "^11.0.0-rc.403",
"@trpc/server": "^11.0.0-rc.403",
"@upstash/ratelimit": "^1.0.1",
"@upstash/redis": "^1.28.4",
"@weatherio/types": "workspace:^0.1.0",
"dayjs": "^1.11.10",
"next": "^14.1.3",
"next-axiom": "^1.3.0",
"resend": "^3.2.0",
"superjson": "2.2.1",
Expand Down
3 changes: 1 addition & 2 deletions packages/api/src/routers/email.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { log } from "next-axiom";
import { Resend } from "resend";
import { z } from "zod";

Expand All @@ -19,7 +18,7 @@ export const emailRouter = createTRPCRouter({
}),
)
.mutation(async ({ input, ctx }) => {
log.info("User sent email", {
ctx.log.info("User sent email", {
firstName: input.firstName,
lastName: input.lastName,
email: input.email,
Expand Down
31 changes: 15 additions & 16 deletions packages/api/src/routers/weather.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import { log } from "next-axiom";
import { z } from "zod";

import type { IDailyForecast, IHourlyForecast } from "@weatherio/types";
Expand Down Expand Up @@ -166,7 +165,7 @@ function calculateAirQualityIndex(
pm25: number,
nitrogenDioxide: number,
): number {
// log.debug("start running calculateAirQualityIndex");
// ctx.log.debug("start running calculateAirQualityIndex");
const maxPm10Value = 100;
const maxPm25Value = 71;
const maxNitrogenDioxideValue = 601;
Expand All @@ -180,9 +179,9 @@ function calculateAirQualityIndex(
? (nitrogenDioxide / maxNitrogenDioxideValue) * 100
: 100;

// log.debug("aqiPm10", { aqiPm10 });
// log.debug("aqiPm25", { aqiPm25 });
// log.debug("aqiNitrogenDioxide", { aqiNitrogenDioxide });
// ctx.log.debug("aqiPm10", { aqiPm10 });
// ctx.log.debug("aqiPm25", { aqiPm25 });
// ctx.log.debug("aqiNitrogenDioxide", { aqiNitrogenDioxide });
return Math.max(aqiPm10, aqiPm25, aqiNitrogenDioxide);
}

Expand All @@ -199,7 +198,7 @@ export const weatherRouter = createTRPCRouter({
}),
)
.query(async ({ input, ctx }) => {
log.info("User requested weather data for coordinates", {
ctx.log.info("User requested weather data for coordinates", {
coordinates: input.coordinates,
timezone: input.timezone,
user: ctx.ip,
Expand Down Expand Up @@ -266,21 +265,21 @@ export const weatherRouter = createTRPCRouter({
}
} catch (error) {
if (error instanceof z.ZodError) {
log.error(`Zod Errors in the ${errorMessage}`, {
ctx.log.error(`Zod Errors in the ${errorMessage}`, {
errorIssues: error.issues,
resultStatus: result.status,
resultValue: result.value,
});
} else {
log.error(`Else Error in the ${errorMessage}`, {
ctx.log.error(`Else Error in the ${errorMessage}`, {
error,
result,
});
}
}
} else {
log.debug("result", result);
log.error(`${errorMessage} request failed`, {
ctx.log.debug("result", result);
ctx.log.error(`${errorMessage} request failed`, {
status: result.status,
reason:
typeof result.reason === "string"
Expand Down Expand Up @@ -336,7 +335,7 @@ export const weatherRouter = createTRPCRouter({
);
}

// log.debug("presentAirQualityIndex", { presentAirQualityIndex });
// ctx.log.debug("presentAirQualityIndex", { presentAirQualityIndex });

const hourlyForecast: IHourlyForecast[] = [];

Expand Down Expand Up @@ -408,7 +407,7 @@ export const weatherRouter = createTRPCRouter({
// console.log("temperatureSumNight", temperatureSumNight);
}
} else {
log.debug("undefined value temperature: ", { j });
ctx.log.debug("undefined value temperature: ", { j });
}

if (hourlyAndDailyData.hourly.rain[j] !== undefined) {
Expand All @@ -417,7 +416,7 @@ export const weatherRouter = createTRPCRouter({
// console.log(hourlyAndDailyData.hourly.rain[j]!);
// console.log("rainSum", rainSum);
} else {
log.debug("undefined value rain: ", { j });
ctx.log.debug("undefined value rain: ", { j });
}

if (hourlyAndDailyData.hourly.showers[j] !== undefined) {
Expand All @@ -426,7 +425,7 @@ export const weatherRouter = createTRPCRouter({
// console.log(hourlyAndDailyData.hourly.showers[j]!);
// console.log("showersSum", showersSum);
} else {
log.debug("undefined value showers: ", { j });
ctx.log.debug("undefined value showers: ", { j });
}

if (hourlyAndDailyData.hourly.snowfall[j] !== undefined) {
Expand All @@ -435,7 +434,7 @@ export const weatherRouter = createTRPCRouter({
// console.log(hourlyAndDailyData.hourly.snowfall[j]!);
// console.log("snowfallSum", snowfallSum);
} else {
log.debug("undefined value snowfall: ", { j });
ctx.log.debug("undefined value snowfall: ", { j });
}

if (hourlyAndDailyData.hourly.cloudcover[j] !== undefined) {
Expand Down Expand Up @@ -545,7 +544,7 @@ export const weatherRouter = createTRPCRouter({
return (probabilities[startIndex]! + probabilities[endIndex]!) / 2;
}

/* log.debug("getTimeSlotAverage", {
/* ctx.log.debug("getTimeSlotAverage", {
startIndex,
endIndex,
probabilities,
Expand Down
31 changes: 28 additions & 3 deletions packages/api/src/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
*/

import type { FetchCreateContextFnOptions } from "@trpc/server/adapters/fetch";
import type { AxiomRequest } from "next-axiom";
import type { NextRequest } from "next/server";
import { initTRPC, TRPCError } from "@trpc/server";
import { Ratelimit } from "@upstash/ratelimit";
import { log } from "next-axiom";
import { log, Logger } from "next-axiom";
import superjson from "superjson";
import { ZodError } from "zod";

Expand Down Expand Up @@ -54,6 +56,10 @@ const UPSTASH_RATELIMITER_TIME_INTERVAL: Duration = validateDuration(
? env.UPSTASH_RATELIMITER_TIME_INTERVAL
: "1d";

function isAxiomRequest(req: unknown): req is AxiomRequest {
return (req as NextRequest & { log: Logger }).log instanceof Logger;
}

/**
* This is the actual context you will use in your router. It will be used to process every request
* that goes through your tRPC endpoint.
Expand All @@ -65,11 +71,13 @@ export const createTRPCContext = ({
resHeaders,
}: FetchCreateContextFnOptions) => {
const ip = req.headers.get("x-forwarded-for") ?? "";

return {
...createInnerTRPCContext({}),
req,
resHeaders,
ip,
axiomTRPCMeta: {},
};
};

Expand Down Expand Up @@ -155,6 +163,22 @@ const rateLimitMiddleware = t.middleware(async ({ ctx, path, next }) => {
return next();
});

const axiomMiddleware = t.middleware(async ({ ctx, next }) => {
const req = ctx.req;

if (!isAxiomRequest(req)) {
throw new Error(
"`nextAxiomTRPCMiddleware` could not find logger. Did you forget to wrap your route handler in `withAxiom`? See: TODO: link to docs",
);
}

const log = req.log.with({ axiomTRPCMeta: ctx.axiomTRPCMeta });

return next({
ctx: { log },
});
});

export const createTRPCRouter = t.router;

/**
Expand All @@ -164,5 +188,6 @@ export const createTRPCRouter = t.router;
* It does not guarantee that a user querying is authorized, but you can still access user session data if they
* are logged in.
*/
export const publicProcedure = t.procedure;
export const rateLimitedProcedure = t.procedure.use(rateLimitMiddleware);
export const axiomPublicProcedure = t.procedure.use(axiomMiddleware);
export const rateLimitedProcedure =
axiomPublicProcedure.use(rateLimitMiddleware);
Loading

0 comments on commit 533c405

Please sign in to comment.