From 10080ff2a229644f8846e14aee99ab8f2f42119f Mon Sep 17 00:00:00 2001 From: Zhu Zhanyan Date: Tue, 7 May 2024 10:53:57 +0800 Subject: [PATCH] revert(cms): Revert Order API Sync (#153) * revert(cms): revert "refactor!(cms): Sync Order schema from package/types (#142)" This reverts commit bb51b86a7e5d6b1a8b9222ec71132d5553ac20e2. * refactor(cms): manually sync orders api with Orders & OrderItem from merch * chore: remove unused import of media --- apps/cms/src/collections/Orders.ts | 100 ++++++++++++++++++++++++-- apps/cms/src/utilities/zodInteropt.ts | 81 --------------------- apps/cms/tsconfig.json | 3 +- packages/types/package.json | 2 + packages/types/src/lib/cms.ts | 24 ++++--- packages/types/src/lib/merch.ts | 43 +++++------ 6 files changed, 131 insertions(+), 122 deletions(-) delete mode 100644 apps/cms/src/utilities/zodInteropt.ts diff --git a/apps/cms/src/collections/Orders.ts b/apps/cms/src/collections/Orders.ts index 65d60f48..18f7ed1a 100644 --- a/apps/cms/src/collections/Orders.ts +++ b/apps/cms/src/collections/Orders.ts @@ -1,7 +1,4 @@ import { CollectionConfig } from "payload/types"; -import { OrderSchema } from "types"; -import { toPayloadZod } from "../utilities/zodInteropt"; - /** Orders collection stores merch orders from users. */ const Orders: CollectionConfig = { @@ -16,6 +13,101 @@ const Orders: CollectionConfig = { ], description: "Merchandise orders from users.", }, - fields: toPayloadZod(OrderSchema), + fields: [ + // by default, payload generates an 'id' field each order automatically + // order items + { + name: "items", + type: "array", + fields: [ + // by default, payload generates an 'id' field each order automatically + { + name: "name", + type: "text", + required: true, + }, + { + name: "image", + type: "text", + }, + { + name: "color", + type: "text", + required: true, + }, + { + name: "size", + type: "text", + required: true, + }, + { + name: "price", + type: "number", + required: true, + }, + { + name: "quantity", + type: "number", + required: true, + }, + ], + // direct paylaod to generate a OrderItem type + interfaceName: "OrderItem", + // validate: orders should not be empty + minRows: 1, + }, + { + name: "transaction_id", + label: "Transaction ID", + admin: { + description: "Transaction ID provided by Payment Gateway", + }, + type: "text", + required: true, + }, + { + name: "transaction_time", + label: "Transaction Time", + type: "date", + admin: { + date: { + pickerAppearance: "dayAndTime", + }, + }, + required: true, + }, + { + name: "payment_method", + label: "Payment Method", + type: "text", + required: true, + }, + { + name: "customerEmail", + label: "Customer Email", + type: "email", + required: true, + }, + { + name: "status", + label: "Order Status", + type: "select", + options: [ + { + value: "pending", + label: "Pending Payment", + }, + { + value: "paid", + label: "Payment Completed", + }, + { + value: "delivered", + label: "Order Completed", + }, + ], + required: true, + }, + ], }; export default Orders; diff --git a/apps/cms/src/utilities/zodInteropt.ts b/apps/cms/src/utilities/zodInteropt.ts deleted file mode 100644 index 4865ea06..00000000 --- a/apps/cms/src/utilities/zodInteropt.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Field } from "payload/types"; -import { z } from "zod"; - -/** - * Converts Zod field with given type to a corresponding Payload field. - * @param name Name of the Zod field to convert. - * @param zodType Data type of the field to convert. - * @returns Payload Field definition suitable for use in Payload collections. - */ -function toPayloadZodField( - name: string, - zodType: z.ZodFirstPartySchemaTypes -): Field { - const required = zodType.isOptional() ? {} : { required: true }; - const field = { - name: name, - ...required, - }; - - // zod types are matched by type name as matching with instanceof breaks bundler - switch (zodType._def.typeName) { - case z.ZodFirstPartyTypeKind.ZodString: - return { ...field, type: "text" }; - case z.ZodFirstPartyTypeKind.ZodNumber: - return { ...field, type: "number" }; - break; - case z.ZodFirstPartyTypeKind.ZodArray: - return { - ...field, - type: "array", - // convert nested type stored in array - fields: toPayloadZod( - (zodType as z.ZodArray>).element - ), - }; - case z.ZodFirstPartyTypeKind.ZodNativeEnum: - return { - ...field, - type: "select", - // unpack enum entries as select options - // typescript encodes enums are encoded as bidirectional dictionary - // with both entries from option -> value and value -> option - // use zod parsing to select only the options -> value entries - options: Object.entries((zodType as z.ZodNativeEnum).enum) - .filter(([_, right]) => zodType.safeParse(right).success) - .map(([option, value]) => { - return { label: option, value: `${value}` }; - }), - }; - - case z.ZodFirstPartyTypeKind.ZodOptional: - return { - ...toPayloadZodField( - name, - (zodType as z.ZodOptional).unwrap() - ), - // override nested field required true with false - ...field, - }; - - default: - throw new Error( - `Unable to convert unsupported Zod type: ${JSON.stringify( - zodType, - null, - 2 - )}` - ); - } -} - -/** - * Converts Zod Object into Payload field definitions. - * @param zodObject Zod Object to convert. - * @returns List of Payload fields corresponding to the fields of the Zod object. - */ -export function toPayloadZod(zodObject: z.ZodObject): Field[] { - return Object.entries(zodObject.shape).map(([name, zodType]) => - toPayloadZodField(name, zodType) - ); -} diff --git a/apps/cms/tsconfig.json b/apps/cms/tsconfig.json index 1cd213bd..d2830361 100644 --- a/apps/cms/tsconfig.json +++ b/apps/cms/tsconfig.json @@ -12,9 +12,8 @@ "jsx": "react", "allowSyntheticDefaultImports": true, "paths": { - // Ensure this matches the path to your typescript outputFile "payload/generated-types": [ - "../../packages/types/src/index.ts" + "../../packages/types/lib/cms.ts" // Ensure this matches the path to your typescript outputFile ] } }, diff --git a/packages/types/package.json b/packages/types/package.json index a2071353..37a23d61 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -3,6 +3,8 @@ "version": "0.0.1", "private": true, "main": "./dist/index.js", + "source": "./src/index.ts", + "types": "./dist/index.d.ts", "files": [ "dist/**" ], diff --git a/packages/types/src/lib/cms.ts b/packages/types/src/lib/cms.ts index 2038de45..7236123c 100644 --- a/packages/types/src/lib/cms.ts +++ b/packages/types/src/lib/cms.ts @@ -6,6 +6,16 @@ * and re-run `payload generate:types` to regenerate this file. */ +export type OrderItem = { + name: string; + image?: string; + color: string; + size: string; + price: number; + quantity: number; + id?: string; +}[]; + export interface Config { collections: { categories: Category; @@ -91,20 +101,12 @@ export interface User { } export interface Order { id: string; - items: { - id: string; - name: string; - image: string; - color: string; - size: string; - price: number; - quantity: number; - }[]; + items?: OrderItem; transaction_id: string; transaction_time: string; payment_method: string; - customer_email: string; - status: '1' | '2' | '3'; + customerEmail: string; + status: 'pending' | 'paid' | 'delivered'; updatedAt: string; createdAt: string; } diff --git a/packages/types/src/lib/merch.ts b/packages/types/src/lib/merch.ts index 983446d4..ac5ddfc8 100644 --- a/packages/types/src/lib/merch.ts +++ b/packages/types/src/lib/merch.ts @@ -19,36 +19,21 @@ export interface Product { } // Order -// use zod to define order types to allow runtime reflection of type structure. -// by default, typescript types lose type information time at compile time. export enum OrderStatus { PENDING_PAYMENT = 1, PAYMENT_COMPLETED = 2, ORDER_COMPLETED = 3, } -const OrderStatusSchema = z.nativeEnum(OrderStatus); -const OrderItem = z.object({ - id: z.string(), - name: z.string(), - image: z.string().optional(), - color: z.string(), - size: z.string(), - price: z.number(), - quantity: z.number(), -}); -export type OrderItem = z.infer; - -export const OrderSchema = z.object({ - id: z.string(), - items: z.array(OrderItem), - transaction_id: z.string(), - transaction_time: z.string().optional(), - payment_method: z.string(), - customer_email: z.string(), - status: OrderStatusSchema, -}); -export type Order = z.infer; +export interface Order { + id: string; + items: OrderItem[]; + transaction_id: string; + transaction_time: string | null; + payment_method: string; + customer_email: string; + status: OrderStatus; +} // Cart export type CartState = { @@ -73,6 +58,16 @@ export type Cart = z.infer; export type CartItem = z.infer; // Promotion +export interface OrderItem { + id: string; + name: string; + image?: string; + color: string; + size: string; + price: number; + quantity: number; +} + export interface Promotion { promoCode: string; maxRedemptions: number;