-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] Added schemas and runtime type validation, also renamed a few f…
…iles
- Loading branch information
1 parent
8757505
commit 1afa186
Showing
7 changed files
with
95 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,95 @@ | ||
/** | ||
* This file handles user-related API operations with runtime validation using Zod. | ||
* Each function includes a type-safe schema (e.g., `{{camelCase name}}Schema`) for parsing and validating | ||
* responses, ensuring that the data conforms to the expected structure at runtime. | ||
* | ||
* Zod is used here to provide robust validation and type inference, improving data integrity | ||
* throughout the API response lifecycle. | ||
* | ||
* We preserve the `ServiceResponse` structure in the return value, allowing the original metadata | ||
* (such as status, pagination, etc.) to pass through, while validating the actual `data` payload. | ||
* | ||
* The `URL.concat(["/", {{camelCase name}}Id].join(""))` approach is used for constructing dynamic URLs | ||
* due to limitations with Handlebars, preventing the use of template literals (e.g., `${URL}/whateverId}`). | ||
* However, the template literal format is preferred when possible for simplicity and readability. | ||
*/ | ||
import { z } from "zod"; | ||
|
||
import type { ServiceResponse } from "~/config/api"; | ||
import { api } from "~/config/api"; | ||
import { create{{camelCase name}}Schema, {{camelCase name}}Schema } from "./schemas"; | ||
|
||
export interface Base{{pascalCase name}} { | ||
id: string; | ||
name: string; | ||
address: string; | ||
} | ||
export type {{pascalCase name}} = z.infer<typeof {{camelCase name}}Schema>; | ||
export type Create{{pascalCase name}} = z.infer<typeof create{{camelCase name}}Schema>; | ||
|
||
export interface Base{{pascalCase name}}ListParams { | ||
export type {{pascalCase name}}ListParams = { | ||
page?: number; | ||
} | ||
}; | ||
|
||
const URL = "/{{kebabCase name}}"; | ||
|
||
export const get{{pascalCase name}}List = async (params: Base{{pascalCase name}}ListParams) => { | ||
const { data } = await api.get<ServiceResponse<Base{{pascalCase name}}[]>>(URL, { | ||
export const get{{pascalCase name}} = async (params: {{pascalCase name}}ListParams) => { | ||
const { data } = await api.get<ServiceResponse<{{pascalCase name}}[]>>(URL, { | ||
params, | ||
}); | ||
|
||
return data.data; | ||
// Runtime type check | ||
const parsed = data.data.map((item) => {{camelCase name}}Schema.parse(item)); | ||
|
||
return { | ||
...data, | ||
data: parsed, | ||
}; | ||
}; | ||
|
||
export const get{{pascalCase name}}Detail = async ({{camelCase name}}Id: string) => { | ||
const { data } = await api.get<ServiceResponse<Base{{pascalCase name}}>>( | ||
export const get{{pascalCase name}}ById = async ({{camelCase name}}Id: string) => { | ||
const { data } = await api.get<ServiceResponse<{{pascalCase name}}>>( | ||
URL.concat(["/", {{camelCase name}}Id].join("")), | ||
); | ||
|
||
return data.data; | ||
// Runtime type check | ||
const parsed = {{camelCase name}}Schema.parse(data.data); | ||
|
||
return { | ||
...data, | ||
data: parsed, | ||
}; | ||
}; | ||
|
||
export const create{{pascalCase name}} = async (body: Omit<Base{{pascalCase name}}, "id">) => { | ||
const { data } = await api.post<ServiceResponse<Base{{pascalCase name}}>>( | ||
export const create{{pascalCase name}} = async (body: Create{{pascalCase name}}) => { | ||
const { data } = await api.post<ServiceResponse<{{pascalCase name}}>>( | ||
URL, | ||
body, | ||
); | ||
|
||
return data.data; | ||
// Runtime type check | ||
const parsed = {{camelCase name}}Schema.parse(data.data); | ||
|
||
return { | ||
...data, | ||
data: parsed, | ||
}; | ||
}; | ||
|
||
export const update{{pascalCase name}} = async (body: Base{{pascalCase name}}) => { | ||
const { data } = await api.put<ServiceResponse<Base{{pascalCase name}}>>( | ||
export const update{{pascalCase name}} = async (body: {{pascalCase name}}) => { | ||
const { data } = await api.put<ServiceResponse<{{pascalCase name}}>>( | ||
URL.concat(["/", body.id].join("")), | ||
body, | ||
); | ||
|
||
return data.data; | ||
// Runtime type check | ||
const parsed = {{camelCase name}}Schema.parse(data.data); | ||
|
||
return { | ||
...data, | ||
data: parsed, | ||
}; | ||
}; | ||
|
||
export const delete{{pascalCase name}} = async ({{camelCase name}}Id: string) => { | ||
const { data } = await api.delete<ServiceResponse<void>>( | ||
URL.concat(["/", {{camelCase name}}Id].join("")), | ||
); | ||
|
||
return data.status; | ||
return data; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./schemas"; | ||
export * from "./{{kebabCase name}}"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { z } from "zod"; | ||
|
||
export const {{camelCase name}}Schema = z.object({ | ||
id: z.string(), | ||
name: z.string(), | ||
address: z.string(), | ||
}); | ||
|
||
export const create{{camelCase name}}Schema = {{camelCase name}}Schema.omit({ id: true }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./{{camelCase name}}Schemas"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
export * as {{camelCase name}}Queries from "./{{kebabCase name}}"; | ||
export * from "./{{kebabCase name}}"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters