UNPKG

@clipboard-health/json-api-nestjs

Version:

TypeScript-friendly utilities for adhering to the JSON:API specification with NestJS.

89 lines (72 loc) 2.37 kB
# @clipboard-health/json-api-nestjs <!-- omit from toc --> TypeScript-friendly utilities for adhering to the [JSON:API](https://jsonapi.org/) specification with [NestJS](https://nestjs.com/). ## Table of contents <!-- omit from toc --> - [Install](#install) - [Usage](#usage) - [Query helpers](#query-helpers) - [Local development commands](#local-development-commands) ## Install ```bash npm install @clipboard-health/json-api-nestjs ``` ## Usage ### Query helpers Create Zod schemas for your API's queries: <embedex source="packages/example-nestjs/examples/query.ts"> ```ts import { booleanString } from "@clipboard-health/contract-core"; import { cursorPaginationQuery, fieldsQuery, type FilterMap, filterQuery, includeQuery, sortQuery, } from "@clipboard-health/json-api-nestjs"; import { z } from "zod"; import { type ArticleAttributeFields, type UserAttributeFields, type UserIncludeFields, } from "../src/contract"; const articleFields = ["title"] as const satisfies readonly ArticleAttributeFields[]; const userFields = ["age", "dateOfBirth"] as const satisfies readonly UserAttributeFields[]; const userIncludeFields = [ "articles", "articles.comments", ] as const satisfies readonly UserIncludeFields[]; const userFilterMap = { age: { filters: ["eq", "gt"], schema: z.coerce.number().int().positive().max(125), }, dateOfBirth: { filters: ["gte"], schema: z.coerce.date().min(new Date("1900-01-01")).max(new Date()), }, isActive: { filters: ["eq"], schema: booleanString, }, } as const satisfies FilterMap<UserAttributeFields>; /** * Disclaimer: Just because JSON:API supports robust querying doesn’t mean your service should * implement them as they may require database indexes, which have a cost. **Implement only access * patterns required by clients.** * * The spec says that if clients provide fields the server doesn’t support, it **MUST** return 400 * Bad Request, hence the `.strict()`. *\/ export const query = z .object({ ...cursorPaginationQuery(), ...fieldsQuery({ article: articleFields, user: userFields }), ...filterQuery(userFilterMap), ...sortQuery(userFields), ...includeQuery(userIncludeFields), }) .strict(); ``` </embedex> ## Local development commands See [`package.json`](./package.json) `scripts` for a list of commands.