SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js
https://adminjs.co
MIT License
8.27k stars 668 forks source link

[Bug]: Postgres JSON/JSONB update record error #1690

Open taoyuliang opened 4 months ago

taoyuliang commented 4 months ago

Contact Details

No response

What happened?

It's ok to show array of object via type:mixed. But it's not ok to update json element in the array Many thanks

Bug prevalence

always right now

AdminJS dependencies version

"dependencies": { "@adminjs/express": "^6.1.0", "@adminjs/sql": "^2.2.6", "adminjs": "^7.8.7", "connect-pg-simple": "^9.0.1", "express": "^4.19.2", "express-formidable": "^1.2.0", "express-session": "^1.18.0", "tslib": "^2.6.3" },

What browsers do you see the problem on?

No response

Relevant log output

error: update "public"."s_routes" set "name" = $1, "from" = $2, "stop" = $3, "to" = $4, "effective_date" = $5, "id" = $6, "arr" = $7, "arr_text"."0" = $8, "arr_text"."1" = $9, "arr_text" = $10 where "id" = $11 - cannot assign to field "0" of column "arr_text" because its type text[] is not a composite type
    at Parser.parseErrorMessage (/Users/anthony/Downloads/HTML/AdminJS/node_modules/pg-protocol/dist/parser.js:283:98)
    at Parser.handlePacket (/Users/anthony/Downloads/HTML/AdminJS/node_modules/pg-protocol/dist/parser.js:122:29)
    at Parser.parse (/Users/anthony/Downloads/HTML/AdminJS/node_modules/pg-protocol/dist/parser.js:35:38)
    at Socket.<anonymous> (/Users/anthony/Downloads/HTML/AdminJS/node_modules/pg-protocol/dist/index.js:11:42)
    at Socket.emit (node:events:518:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Readable.push (node:internal/streams/readable:390:5)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)

Relevant code that's giving you issues

import AdminJS from "adminjs"
import AdminJSExpress from "@adminjs/express"
import express from "express"
import Connect from "connect-pg-simple"
import session from "express-session"
import Plugin from "@adminjs/express"
import { Adapter, Database, Resource } from "@adminjs/sql"
import { ComponentLoader } from "adminjs"
import * as url from "url"
import path from "path"

// process.env.NODE_ENV = "production"
process.env.NODE_ENV = "development"
// console.log(process.env.NODE_ENV === "production")
const __dirname = url.fileURLToPath(new URL(".", import.meta.url))
const componentLoader = new ComponentLoader()
AdminJS.registerAdapter({
  Database,
  Resource,
})

const PORT = 3000

const DEFAULT_ADMIN = {
  email: "admin@example.com",
  password: "password",
}

const authenticate = async (email, password) => {
  if (email === DEFAULT_ADMIN.email && password === DEFAULT_ADMIN.password) {
    return Promise.resolve(DEFAULT_ADMIN)
  }
  return null
}

const start = async () => {
  const app = express()

  const db = await new Adapter("postgresql", {
    connectionString: "postgres://adminjs:changeme@localhost:5432/adminjs",
    database: "adminjs",
  }).init()
  const admin = new AdminJS({
    resources: [
      {
        resource: db.table("supplier"),
        options: { id: "supplier" },
      },
      {
        resource: db.table("s_routes"),
        options: {
          id: "s_routes",
          properties: {
            arr: { isArray: true, isDraggable: false, type: "mixed" },
            "arr.ratio": {
              type: "string", // PostgreSQL text
            },
            "arr.r45": {
              type: "number", // PostgreSQL numeric
            },
            "arr.r100": {
              type: "number",
            },
            "arr.r300": {
              type: "number",
            },
            "arr.r500": {
              type: "number",
            },
            "arr.r1000": {
              type: "number",
            },
            // Example from Documentation
            // "photoImage.tags": {
            //   reference: "Tag",
            //   isArray: true,
            // },
          },
        },
      },
    ],
    dashboard: {
      component: componentLoader.add("Dashboard", "./dashboard"),
    },
    componentLoader,
    branding: {
      companyName: "Your project name",
      softwareBrothers: false,
      logo: false, // OR false to hide the default one
    },
    locale: {
      language: "en",
      translations: {
        labels: {
          // navigation: "Навигација",
          // pages: "Страници",
          // selectedRecords: "Избрано ({{selected}})",
          // filters: "Филтри",
          // adminVersion: "Администратор: {{version}}",
          // appVersion: "Апликација: {{version}}",
          loginWelcome: "A Big Welcome !",
          // dashboard: "Контролна табла",
        },
        messages: {
          loginWelcome: "A Big Welcome !!",
        },
      },
    },
    // assets: {
    // styles: ["/styles.css"],
    // },
  })
  admin.watch()
  const ConnectSession = Connect(session)
  const sessionStore = new ConnectSession({
    conObject: {
      connectionString: "postgres://adminjs:changeme@localhost:5432/adminjs",
      ssl: process.env.NODE_ENV === "production",
    },
    tableName: "session",
    createTableIfMissing: true,
  })

  const adminRouter = AdminJSExpress.buildAuthenticatedRouter(
    admin,
    {
      authenticate,
      cookieName: "adminjs",
      cookiePassword: "sessionsecret",
    },
    null,
    {
      store: sessionStore,
      resave: true,
      saveUninitialized: true,
      secret: "sessionsecret",
      cookie: {
        httpOnly: process.env.NODE_ENV === "production",
        secure: process.env.NODE_ENV === "production",
      },
      name: "adminjs",
    }
  )
  app.use(express.static(path.join(__dirname, "./public")))
  app.use(admin.options.rootPath, adminRouter)

  app.listen(PORT, () => {
    console.log(
      `AdminJS started on http://localhost:${PORT}${admin.options.rootPath}`
    )
  })
}

start()
beautyfree commented 1 month ago

same error when i try to use @adminjs/sql