|
| 1 | +# nuxt-parse |
| 2 | + |
| 3 | +[![npm version][npm-version-src]][npm-version-href] |
| 4 | +[![npm downloads][npm-downloads-src]][npm-downloads-href] |
| 5 | +[](https://GitHub.com/sidebase/nuxt-parse/) |
| 6 | +[![License][license-src]][license-href] |
| 7 | +[](https://twitter.com/sidebase_io) |
| 8 | +[](https://discord.gg/9MUHR8WT9B) |
| 9 | + |
| 10 | +A nuxt focused package to make data validation and parsing easy. This package follows the design philosophy of the article [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/). It uses [`zod`](https://github.com/colinhacks/zod) for parsing data from the user, APIs, your own functions, ... |
| 11 | + |
| 12 | +Full tsdoc-documentation is here: https://nuxt-sidebase-parse.sidebase.io |
| 13 | + |
| 14 | +[Moved here from original mono-repo](https://github.com/sidebase/sidebase-libs/tree/main/packages/nuxt-sidebase-parse) |
| 15 | + |
| 16 | +## Features |
| 17 | + |
| 18 | +- ✔️ Validate Data using [`zod`](https://github.com/colinhacks/zod) |
| 19 | +- ✔️ Deserialize and Serialize user, backend, api data |
| 20 | +- ✔️ Helpers focused on Nuxt 3 usage and developer experience |
| 21 | + |
| 22 | +## Usage |
| 23 | + |
| 24 | + |
| 25 | +```bash |
| 26 | +npm i @sidebase/nuxt-parse |
| 27 | +``` |
| 28 | + |
| 29 | +Then, e.g., in your code: |
| 30 | + |
| 31 | +- Make an arbitrary parser, e.g., to deserialize data from an API: |
| 32 | + - Example with valid data: |
| 33 | + ```ts |
| 34 | + import { z, makeParser } from "@sidebase/nuxt-parse" |
| 35 | + |
| 36 | + // Define the expected response schema |
| 37 | + const responseSchema = z.object({ |
| 38 | + uuid: z.string().uuid(), |
| 39 | + }) |
| 40 | + |
| 41 | + // Perform the request, use `makeParse` to pass a transformer for the data |
| 42 | + const { data, error } = useFetch('https://httpbin.org/uuid', { |
| 43 | + transform: makeParser(responseSchema), |
| 44 | + }) |
| 45 | + |
| 46 | + console.log(`data is ${data.value}`) |
| 47 | + // -> `data is {"uuid":"f8df921c-d7f3-43c1-ac9b-3cf5d4da2f7b"}` |
| 48 | + |
| 49 | + console.log(`error is ${error.value}`) |
| 50 | + // -> `error is false` |
| 51 | + ``` |
| 52 | + - Example with invalid data: |
| 53 | + ```ts |
| 54 | + import { z, makeParser } from "@sidebase/nuxt-parse" |
| 55 | + |
| 56 | + // Define the expected response schema |
| 57 | + const responseSchema = z.object({ |
| 58 | + uuid: z.string().uuid(), |
| 59 | + }) |
| 60 | + |
| 61 | + // Perform the request, use `makeParse` to pass a transformer for the data |
| 62 | + const { data, error } = useFetch('https://httpbin.org/ip', { |
| 63 | + transform: makeParser(responseSchema), |
| 64 | + }) |
| 65 | + |
| 66 | + console.log(`data is ${data.value}`) |
| 67 | + // -> `data is null` |
| 68 | + |
| 69 | + console.log(`error is ${error.value}`) |
| 70 | + // -> `error is true` |
| 71 | + ``` |
| 72 | +- Handle user data in an endpoint: |
| 73 | + ```ts |
| 74 | + import { defineEventHandler } from 'h3' |
| 75 | + import type { CompatibilityEvent } from 'h3' |
| 76 | + import { z, parseParamsAs, parseBodyAs } from "@sidebase/nuxt-parse" |
| 77 | +
|
| 78 | + // Define the schema of the parameters you expect the user to provide you with |
| 79 | + const paramsSchema = z.object({ |
| 80 | + id: z.string().uuid(), |
| 81 | + }) |
| 82 | +
|
| 83 | + // Define the schema of the body you expect the user to provide you with |
| 84 | + const bodySchema = z.object({ |
| 85 | + name: z.string(), |
| 86 | + age: z.number() |
| 87 | + }) |
| 88 | +
|
| 89 | + // Get a nice type to use throughout your code and components |
| 90 | + type RequestBody = z.infer<typeof bodySchema> |
| 91 | +
|
| 92 | + export default defineEventHandler(async (event: CompatibilityEvent) => { |
| 93 | + // Validate and then get the parameters |
| 94 | + // This automatically throws a nice HTTP 422 error with more information if the data is invalid |
| 95 | + const params = parseParamsAs(event, paramsSchema) |
| 96 | +
|
| 97 | + let body: RequestBody; |
| 98 | + try { |
| 99 | + body = parseBodyAs(event, paramsSchema) |
| 100 | + } catch(error) { |
| 101 | + // Fallback, this avoids automatic raising + returning of the HTTP 422 error |
| 102 | + body = { |
| 103 | + name: 'Bernd', |
| 104 | + age: 88 |
| 105 | + } |
| 106 | + } |
| 107 | +
|
| 108 | + // Return the full entity |
| 109 | + return { |
| 110 | + id: params.id, |
| 111 | + ...body |
| 112 | + } |
| 113 | + }) |
| 114 | + ``` |
| 115 | +- Parse any data: |
| 116 | + ```ts |
| 117 | + import { z, parseDataAs } from "@sidebase/nuxt-parse" |
| 118 | +
|
| 119 | + const parsedData = await parseDataAs({ test: "1" }, z.object({ test: z.number() )})) |
| 120 | + // -> throws! `"1"` is not a number, but a string! |
| 121 | +
|
| 122 | + const parsedData = await parseDataAs({ test: 1 }, z.object({ test: z.number() )})) |
| 123 | + console.log(parsedData) |
| 124 | + // -> output: `1` |
| 125 | +
|
| 126 | +
|
| 127 | + const parsedData = await parseDataAs({ test: "1" }, z.object({ test: z.string().transform(v => parseInt(v)) )})) |
| 128 | + console.log(parsedData) |
| 129 | + // -> output: `1` (we used `.transform` to ensure that we get a number) |
| 130 | +
|
| 131 | +
|
| 132 | + ``` |
| 133 | +- Also works with async data, e.g., when fetching from another API or DB: |
| 134 | + ```ts |
| 135 | + import { z, parseDataAs } from "@sidebase/nuxt-parse" |
| 136 | +
|
| 137 | + const fakeDatabaseQuery = async () => { id: 1 } |
| 138 | + const parsedData = await parseDataAs(fakeDatabaseQuery, z.object({ id: z.number() )})) |
| 139 | +
|
| 140 | + console.log(parsedData) |
| 141 | + // -> output: `1` |
| 142 | + ``` |
| 143 | + |
| 144 | +## Documentation |
| 145 | + |
| 146 | +Full tsdoc-documentation is here: https://nuxt-sidebase-parse.sidebase.io |
| 147 | + |
| 148 | +This module exports: |
| 149 | +- `parseBodyAs`: Parse body of `h3` event |
| 150 | +- `parseParamsAs`: Parse params of `h3` event |
| 151 | +- `parseQueryAs`: Parse query of `h3` event |
| 152 | +- `parseCookieAs`: Parse cookies of `h3` event |
| 153 | +- `parseHeaderAs`: Parse header of `h3` event |
| 154 | +- `parseDataAs`: Parse sync or async data |
| 155 | +- `makeParser`: Make your own parser (see example above) |
| 156 | +- `z`: [`zod`](https://github.com/colinhacks/zod), the library used for parsing |
| 157 | + |
| 158 | + |
| 159 | +<!-- Badges --> |
| 160 | +[npm-version-src]: https://img.shields.io/npm/v/@sidebase/nuxt-parse/latest.svg |
| 161 | +[npm-version-href]: https://npmjs.com/package/@sidebase/nuxt-parse |
| 162 | + |
| 163 | +[npm-downloads-src]: https://img.shields.io/npm/dt/@sidebase/nuxt-parse.svg |
| 164 | +[npm-downloads-href]: https://npmjs.com/package/@sidebase/nuxt-parse |
| 165 | + |
| 166 | +[license-src]: https://img.shields.io/npm/l/@sidebase/nuxt-parse.svg |
| 167 | +[license-href]: https://npmjs.com/package/@sidebase/nuxt-parse |
0 commit comments