I'm using Postgres.js to build an application and I'm creating an Enum for user roles like the following
import { PostgresError } from 'postgres';
import sql from './database/index.js';
const RolesEnum = {
user : 'user',
moderator : 'moderator',
admin : 'admin'
} as const;
const Enum = ['user', 'moderator', 'admin'] as const;
async function Build() {
try {
await sql`DROP TYPE F_that;`.catch(() => {}); // IF DOESN'T EXIST THEN PASS
const { statement } = await sql`CREATE TYPE F_that AS ENUM (${sql(
Enum
)});`;
console.log(statement);
} catch (error) {
console.error(
(error as PostgresError).query ?? (error as Error).message ?? error
);
/* Logs the following
CREATE TYPE F_that AS ENUM ( "user", "moderator" , "admin" );*/
}
}
await Build() // Logs the following: CREATE TYPE F_that AS ENUM ( "user", "moderator" , "admin" );`
The problem is the double quotes in the Enum values, which gives an Error in Postgres. How to make them single quotes in the query?
The closest solution I got was adding this to the catch block:
if (error instanceof postgres.PostgresError) {
error.query.replaceAll('"', "'"); // gets query with single quotes for the Enum
}
which gives the right query but I can't use it like above (whenever I try to get an error about a positional parameter, I guess it runs at run time?)
Use sql.unsafe
. This is safe because you're using a hardcoded array.
await sql`DROP TYPE IF EXISTS F_that;`;
# to escape single quotes if any
const enumValues = Enum.map(v => `'${v.replace(/'/g, "''")}'`).join(', ');
await sql`CREATE TYPE F_that AS ENUM (${sql.unsafe(enumValues)});`;