### Instruction:
Create a Node.js application that serves as a RESTful API for managing a collection of products. The API should support creating, reading, updating, and deleting products, as well as filtering products based on certain criteria (e.g., price range, category). Implement the API using Express.js and store product data in a PostgreSQL database.
PLAINFORMAT

### Response:

const express = require('express');
const bodyParser = require('body-parser');
const { Pool } = require('pg');

const app = express();
const port = process.env.PORT || 3000;

// Configure PostgreSQL connection
const pool = new Pool({
  user: 'your_user',
  host: 'localhost',
  database: 'your_database',
  password: 'your_password',
  port: 5432,
});

app.use(bodyParser.json());
app.use(
  bodyParser.urlencoded({
    extended: true,
  })
);

// Get all products or filter by price range or category
app.get('/products', async (req, res) => {
  const { minPrice, maxPrice, category } = req.query;
  let query = 'SELECT * FROM products WHERE 1=1';

  if (minPrice) query += ` AND price >= ${minPrice}`;
  if (maxPrice) query += ` AND price <= ${maxPrice}`;
  if (category) query += ` AND category = '${category}'`;

  try {
    const result = await pool.query(query);
    res.status(200).json(result.rows);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Get a single product by ID
app.get('/products/:id', async (req, res) => {
  const id = parseInt(req.params.id);

  try {
    const result = await pool.query('SELECT * FROM products WHERE id = $1', [id]);
    res.status(200).json(result.rows[0]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Create a new product
app.post('/products', async (req, res) => {
  const { name, category, price } = req.body;

  try {
    const result = await pool.query(
      'INSERT INTO products (name, category, price) VALUES ($1, $2, $3) RETURNING *',
      [name, category, price]
    );
    res.status(201).json(result.rows[0]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Update a product
app.put('/products/:id', async (req, res) => {
  const id = parseInt(req.params.id);
  const { name, category, price } = req.body;

  try {
    const result = await pool.query(
      'UPDATE products SET name = $1, category = $2, price = $3 WHERE id = $4 RETURNING *',
      [name, category, price, id]
    );
    res.status(200).json(result.rows[0]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Delete a product
app.delete('/products/:id', async (req, res) => {
  const id = parseInt(req.params.id);

  try {
    await pool.query('DELETE FROM products WHERE id = $1', [id]);
    res.status(204).send();
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(port, () => {
  console.log(`App running on port ${port}.`);
});