Initial commit
This commit is contained in:
12
packages/navigation/src/integrations/api/procedures.ts
Normal file
12
packages/navigation/src/integrations/api/procedures.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { t } from "@repo/core-shared/trpc/init";
|
||||
import { defineErrorMiddleware } from "@repo/core-shared/trpc/define-error-middleware";
|
||||
|
||||
import { HeaderNotFoundError } from "../../entities/errors/header";
|
||||
import { InputParseError } from "../../entities/errors/common";
|
||||
|
||||
export const navigationProcedure = t.procedure.use(
|
||||
defineErrorMiddleware([
|
||||
[InputParseError, "BAD_REQUEST"],
|
||||
[HeaderNotFoundError, "NOT_FOUND"],
|
||||
]),
|
||||
);
|
||||
93
packages/navigation/src/integrations/api/router.test.ts
Normal file
93
packages/navigation/src/integrations/api/router.test.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { injectable } from "inversify";
|
||||
import { navigationContainer } from "@/di/container";
|
||||
import { NavigationModule } from "@/di/module";
|
||||
import { NAVIGATION_SYMBOLS } from "@/di/symbols";
|
||||
import { getHeaderUseCase } from "@/application/use-cases/get-header.use-case";
|
||||
import { getHeaderController } from "@/interface-adapters/controllers/get-header.controller";
|
||||
import { navigationRouter } from "@/integrations/api/router";
|
||||
|
||||
describe("navigationRouter", () => {
|
||||
beforeEach(() => {
|
||||
navigationContainer.unbindAll();
|
||||
navigationContainer.load(NavigationModule);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
navigationContainer.unbindAll();
|
||||
});
|
||||
|
||||
it("exposes header procedure", () => {
|
||||
const names = Object.keys(navigationRouter._def.procedures);
|
||||
expect(names).toContain("header");
|
||||
});
|
||||
|
||||
it("header returns 3 items", async () => {
|
||||
const caller = navigationRouter.createCaller({});
|
||||
const result = await caller.header({});
|
||||
expect(result.items).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("navigationRouter error mapping", () => {
|
||||
beforeEach(() => {
|
||||
navigationContainer.unbindAll();
|
||||
navigationContainer.load(NavigationModule);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
navigationContainer.unbindAll();
|
||||
});
|
||||
|
||||
it("translates InputParseError → BAD_REQUEST when extra fields are passed", async () => {
|
||||
const caller = navigationRouter.createCaller({});
|
||||
try {
|
||||
await caller.header({ unexpected: "field" } as unknown as Record<
|
||||
string,
|
||||
never
|
||||
>);
|
||||
throw new Error("expected throw");
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(TRPCError);
|
||||
expect((e as TRPCError).code).toBe("BAD_REQUEST");
|
||||
}
|
||||
});
|
||||
|
||||
it("translates HeaderNotFoundError → NOT_FOUND when repository returns null", async () => {
|
||||
@injectable()
|
||||
class NullHeaderRepository {
|
||||
async getHeader() {
|
||||
return null as never;
|
||||
}
|
||||
}
|
||||
|
||||
navigationContainer.unbindAll();
|
||||
navigationContainer
|
||||
.bind(NAVIGATION_SYMBOLS.IHeaderRepository)
|
||||
.to(NullHeaderRepository);
|
||||
navigationContainer
|
||||
.bind(NAVIGATION_SYMBOLS.IGetHeaderUseCase)
|
||||
.toDynamicValue((ctx) =>
|
||||
getHeaderUseCase(
|
||||
ctx.container.get(NAVIGATION_SYMBOLS.IHeaderRepository),
|
||||
),
|
||||
);
|
||||
navigationContainer
|
||||
.bind(NAVIGATION_SYMBOLS.IGetHeaderController)
|
||||
.toDynamicValue((ctx) =>
|
||||
getHeaderController(
|
||||
ctx.container.get(NAVIGATION_SYMBOLS.IGetHeaderUseCase),
|
||||
),
|
||||
);
|
||||
|
||||
const caller = navigationRouter.createCaller({});
|
||||
try {
|
||||
await caller.header({});
|
||||
throw new Error("expected throw");
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(TRPCError);
|
||||
expect((e as TRPCError).code).toBe("NOT_FOUND");
|
||||
}
|
||||
});
|
||||
});
|
||||
22
packages/navigation/src/integrations/api/router.ts
Normal file
22
packages/navigation/src/integrations/api/router.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { router } from "@repo/core-shared/trpc/init";
|
||||
|
||||
import { navigationContainer } from "../../di/container";
|
||||
import { NAVIGATION_SYMBOLS } from "../../di/symbols";
|
||||
|
||||
import { getHeaderInputSchema } from "../../application/use-cases/get-header.use-case";
|
||||
import type { IGetHeaderController } from "../../interface-adapters/controllers/get-header.controller";
|
||||
|
||||
import { navigationProcedure } from "./procedures";
|
||||
|
||||
export const navigationRouter = router({
|
||||
header: navigationProcedure
|
||||
.input(getHeaderInputSchema)
|
||||
.query(({ input }) => {
|
||||
const ctrl = navigationContainer.get<IGetHeaderController>(
|
||||
NAVIGATION_SYMBOLS.IGetHeaderController,
|
||||
);
|
||||
return ctrl(input);
|
||||
}),
|
||||
});
|
||||
|
||||
export type NavigationRouter = typeof navigationRouter;
|
||||
34
packages/navigation/src/integrations/cms/globals/header.ts
Normal file
34
packages/navigation/src/integrations/cms/globals/header.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { GlobalConfig } from "payload";
|
||||
|
||||
export const header: GlobalConfig = {
|
||||
slug: "header",
|
||||
custom: {
|
||||
retention: {
|
||||
purgeSchedule: "monthly",
|
||||
postDeletion: {
|
||||
duration: "P90D",
|
||||
trigger: "after-deletion",
|
||||
action: "hard-delete",
|
||||
},
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
group: "Navigation",
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: "logo",
|
||||
type: "upload",
|
||||
relationTo: "media",
|
||||
},
|
||||
{
|
||||
name: "items",
|
||||
type: "array",
|
||||
fields: [
|
||||
{ name: "label", type: "text", required: true },
|
||||
{ name: "href", type: "text", required: true },
|
||||
{ name: "external", type: "checkbox", defaultValue: false },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
2
packages/navigation/src/integrations/cms/index.ts
Normal file
2
packages/navigation/src/integrations/cms/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { header } from "./globals/header";
|
||||
// <gen:job-tasks>
|
||||
Reference in New Issue
Block a user