Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Troubleshooting 'npm run generate:types' Command Issue

so i get an error by doing npm run generate:types :

PS C:\Users\hacke\complete_fullstack_digital_marketplace_app> npm run generate:types

> complete_fullstack_digital_marketplace_app@0.1.0 generate:types
> cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types

C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\fields\config\sanitize.js:52
                        throw new _errors.InvalidFieldRelationship(field, relationship);
                              ^

InvalidFieldRelationship: Field Product file(s) has invalid relationship 'product_files'.
    at C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\fields\config\sanitize.js:52:31
    at Array.forEach (<anonymous>)
    at C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\fields\config\sanitize.js:50:31
    at Array.map (<anonymous>)
    at sanitizeFields (C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\fields\config\sanitize.js:25:19)
    at sanitizeCollection (C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\collections\config\sanitize.js:135:53)
    at C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\config\sanitize.js:81:85
    at Array.map (<anonymous>)
    at sanitizeConfig (C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\config\sanitize.js:81:45)
    at buildConfig (C:\Users\hacke\complete_fullstack_digital_marketplace_app\node_modules\payload\dist\config\build.js:21:41) {
  data: null,
  isOperational: true,
  isPublic: false,
  status: 500
}

Node.js v20.10.0.



i do not know what is the issue becasue everything worked till this point and i need to generate typscript types based on configuration in src/payload.config.ts recognise collection.

github repo: https://github.com/RenePung/complete_fullstack_digital_marketplace_app

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package.json :

{
  "name": "complete_fullstack_digital_marketplace_app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
    "generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.3.2",
    "@payloadcms/bundler-webpack": "^1.0.5",
    "@payloadcms/db-mongodb": "^1.0.8",
    "@payloadcms/richtext-slate": "^1.2.0",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-dropdown-menu": "^2.0.6",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@tanstack/react-query": "^4.36.1",
    "@trpc/client": "^10.44.1",
    "@trpc/next": "^10.44.1",
    "@trpc/react-query": "^10.44.1",
    "@trpc/server": "^10.44.1",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.0.0",
    "cross-env": "^7.0.3",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "lucide-react": "^0.292.0",
    "next": "14.0.3",
    "nodemailer": "^6.9.7",
    "payload": "^2.2.2",
    "react": "^18",
    "react-dom": "^18",
    "react-hook-form": "^7.48.2",
    "sonner": "^1.2.4",
    "tailwind-merge": "^2.0.0",
    "tailwindcss-animate": "^1.0.7",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20",
    "@types/nodemailer": "^6.4.14",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-next": "14.0.3",
    "nodemon": "^3.0.1",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  }
}

Products.ts file :

import { PRODUCT_CATEGORIES } from "../../config";
import { CollectionConfig } from "payload/types";

export  const Products: CollectionConfig = {
    slug: "products",
    admin: {
        useAsTitle: "name"
    },
    access: {},
    fields: [
        {
            name: "user",
            type: "relationship",
            relationTo: "users",
            required: true,
            hasMany: false,
            admin: {
                condition: () => false
            },
        },
        {
            name: "name",
            label: "Name",
            type: "text",
            required: true,
        },
        {
            name: "description",
            type: "textarea",
            label: "Product details",
        },
        {
            name: "price",
            label: "Price in USD",
            min: 0,
            max: 1000,
            type: "number",
            required: true,
        },
        {
            name: "category",
            label: "Category",
            type: "select",
            options: PRODUCT_CATEGORIES.map(({ label, value }) => ({ label, value })
            ),
            required: true,
        },
        {
            name: "product_files",
            label: "Product file(s)",
            type: "relationship",
            required: true,
            relationTo: "product_files",
            hasMany: false,
        },
        {
            name: "approvedForSale",
            label: "Product Status",
            type: "select",
            defaultValue: "pending",
            access: {
                create: ({ req }) => req.user.role === "admin",
                read: ({ req }) => req.user.role === "admin",
                update: ({ req }) => req.user.role === "admin",
            },
            options: [
                {
                    label: "Pending verification",
                    value: "pending",
                },
                {
                    label: "Approved",
                    value: "approved",
                },
                {
                    label: "Denied",
                    value: "denied",
                },
            ],
        },
        {
            name: "priceId",
            access: {
                create: () => false,
                read: () => false,
                update: () => false,
            },
            type: "text",
            admin: {
                hidden: true,
            },
        },
        {
            name: "stripeId",
            access: {
                create: () => false,
                read: () => false,
                update: () => false,
            },
            type: "text",
            admin: {
                hidden: true,
            },
        },
        {
            name: "images",
            type: "array",
            label: "Product images",
            minRows: 1,
            maxRows: 4,
            required: true,
            labels: {
                singular: "Image",
                plural: "Images",
            },
            fields: [
                {
                    name: "image",
                    type: "upload",
                    relationTo: "media",
                    required: true,
                },
            ],
        },
    ],
}


ProductFile.ts file :

import { User } from "../payload-types";
import { BeforeChangeHook } from "payload/dist/collections/config/types";
import { Access, CollectionConfig } from "payload/types";

const addUser: BeforeChangeHook = ({ req, data }) => {
    const user = req.user as User | null
    return {...data, user: user?.id}
}

const yourOwnAndPurchased: Access = async ({ req }) => {
    const user = req.user as User | null

    if( user?.role === "admin" ) return true
    if( !user ) return false

    const {} = await req.payload.find({
        collection: "products"
    })
}

export const ProductFiles: CollectionConfig = {
    slug: "product_files",
    admin: {
        hidden: ({ user }) => user.role !== "admin",
    },
    hooks: {
        beforeChange: [addUser]
    },
    access: {
        read: yourOwnAndPurchased
    },
    upload: {
        staticURL: "/product_files",
        staticDir: "product_files",
        mimeTypes: ["image/*", "font/*", "application/postscript"],
    },
    fields: [
        {
            name: "user",
            type: "relationship",
            relationTo: "users",
            admin: {
                condition: () => false
            },
            hasMany: false,
            required: true,
        },
    ],
}

payload.config.ts file :

import { mongooseAdapter } from "@payloadcms/db-mongodb";
import { slateEditor } from "@payloadcms/richtext-slate";
import { buildConfig } from "payload/config";
import { webpackBundler } from "@payloadcms/bundler-webpack";
import path from "path";
import { Users } from "./collections/Users";
import dotenv from "dotenv";
import { Products } from "./collections/Products/Products";
import { Media } from "./collections/Media";
//*****************************IMPORTS*****************************************************

dotenv.config({
    path: path.resolve(__dirname, "../.env"),
})

export default buildConfig({
    serverURL: process.env.NEXT_PUBLIC_SERVER_URL || '',
    collections: [Users, Products, Media],
    routes: {
        admin: '/sell'
    },
    admin: {
        user: "users",
        bundler: webpackBundler(),
        meta: {
            titleSuffix: "- HippoHub",
            favicon: "/favicon.ico",
            ogImage: "/thumbnail.jpg",
        },
    },
    rateLimit: {
        max: 2000,
    },
    editor: slateEditor({}),
    db: mongooseAdapter({
        url: process.env.MONGODB_URL!,
    }),
    typescript: {
        outputFile: path.resolve(__dirname, 'payload-types.ts'),
    },
})


>Solution :

You just need to import and use the ProductFiles collection in your payload config file.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading