Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cf/src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
return b.i32(0xFFFFFFFF)

type = types[i]
x = options.transform.value.to ? options.transform.value.to(x, { type }) : x
parameters[i] = x = type in options.serializers
? options.serializers[type](x)
: '' + x
Expand Down
10 changes: 9 additions & 1 deletion cf/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,28 +341,36 @@ function createJsonTransform(fn) {
return typeof x === 'object' && x !== null && (column.type === 114 || column.type === 3802)
? Array.isArray(x)
? x.map(x => jsonTransform(x, column))
: Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: Object.getPrototypeOf(x) === Object.prototype || Object.getPrototypeOf(x) === null
? Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: x
: x
}
}

toCamel.column = { from: toCamel }
toCamel.value = { from: createJsonTransform(toCamel) }
fromCamel.column = { to: fromCamel }
fromCamel.value = { to: createJsonTransform(fromCamel) }

export const camel = { ...toCamel }
camel.column.to = fromCamel
camel.value.to = fromCamel.value.to

toPascal.column = { from: toPascal }
toPascal.value = { from: createJsonTransform(toPascal) }
fromPascal.column = { to: fromPascal }
fromPascal.value = { to: createJsonTransform(fromPascal) }

export const pascal = { ...toPascal }
pascal.column.to = fromPascal
pascal.value.to = fromPascal.value.to

toKebab.column = { from: toKebab }
toKebab.value = { from: createJsonTransform(toKebab) }
fromKebab.column = { to: fromKebab }
fromKebab.value = { to: createJsonTransform(fromKebab) }

export const kebab = { ...toKebab }
kebab.column.to = fromKebab
kebab.value.to = fromKebab.value.to
1 change: 1 addition & 0 deletions cjs/src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
return b.i32(0xFFFFFFFF)

type = types[i]
x = options.transform.value.to ? options.transform.value.to(x, { type }) : x
parameters[i] = x = type in options.serializers
? options.serializers[type](x)
: '' + x
Expand Down
10 changes: 9 additions & 1 deletion cjs/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,28 +340,36 @@ function createJsonTransform(fn) {
return typeof x === 'object' && x !== null && (column.type === 114 || column.type === 3802)
? Array.isArray(x)
? x.map(x => jsonTransform(x, column))
: Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: Object.getPrototypeOf(x) === Object.prototype || Object.getPrototypeOf(x) === null
? Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: x
: x
}
}

toCamel.column = { from: toCamel }
toCamel.value = { from: createJsonTransform(toCamel) }
fromCamel.column = { to: fromCamel }
fromCamel.value = { to: createJsonTransform(fromCamel) }

const camel = module.exports.camel = { ...toCamel }
camel.column.to = fromCamel
camel.value.to = fromCamel.value.to

toPascal.column = { from: toPascal }
toPascal.value = { from: createJsonTransform(toPascal) }
fromPascal.column = { to: fromPascal }
fromPascal.value = { to: createJsonTransform(fromPascal) }

const pascal = module.exports.pascal = { ...toPascal }
pascal.column.to = fromPascal
pascal.value.to = fromPascal.value.to

toKebab.column = { from: toKebab }
toKebab.value = { from: createJsonTransform(toKebab) }
fromKebab.column = { to: fromKebab }
fromKebab.value = { to: createJsonTransform(fromKebab) }

const kebab = module.exports.kebab = { ...toKebab }
kebab.column.to = fromKebab
kebab.value.to = fromKebab.value.to
71 changes: 71 additions & 0 deletions cjs/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,77 @@ t('Json', async() => {
return ['hello,42', [x.a, x.b].join()]
})

t('Json transform parameter keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.json({ aTest: 1 }) }->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json without transform keeps parameter keys', async() => {
const x = (await sql`select ${ sql.json({ aTest: 1 }) }->>'aTest' as x`)[0].x
return ['1', x]
})

t('Json transform nested parameter keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`
select ${ sql.json({ aTest: [{ bTest: 1 }, { bTest: 2 }] }) }#>>'{a_test,1,b_test}' as x
`)[0].x
return ['2', x]
})

t('Json transform typed json parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.typed({ aTest: 1 }, 114) }->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform implicit jsonb parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ { aTest: 1 } }::jsonb->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform implicit json parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ { aTest: 1 } }::json->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform result keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select '{"a_test":1}'::jsonb as x`)[0].x
return [1, x.aTest]
})

t('Json transform does not transform parameter values with .toJSON()', async() => {
const now = new Date()
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.json({ aTest: now }) }->>'a_test' as x`)[0].x
return [now.toJSON(), x]
})

t('implicit json', async() => {
const x = (await sql`select ${ { a: 'hello', b: 42 } }::json as x`)[0].x
return ['hello,42', [x.a, x.b].join()]
Expand Down
1 change: 1 addition & 0 deletions deno/src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
return b.i32(0xFFFFFFFF)

type = types[i]
x = options.transform.value.to ? options.transform.value.to(x, { type }) : x
parameters[i] = x = type in options.serializers
? options.serializers[type](x)
: '' + x
Expand Down
10 changes: 9 additions & 1 deletion deno/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,28 +341,36 @@ function createJsonTransform(fn) {
return typeof x === 'object' && x !== null && (column.type === 114 || column.type === 3802)
? Array.isArray(x)
? x.map(x => jsonTransform(x, column))
: Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: Object.getPrototypeOf(x) === Object.prototype || Object.getPrototypeOf(x) === null
? Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
: x
: x
}
}

toCamel.column = { from: toCamel }
toCamel.value = { from: createJsonTransform(toCamel) }
fromCamel.column = { to: fromCamel }
fromCamel.value = { to: createJsonTransform(fromCamel) }

export const camel = { ...toCamel }
camel.column.to = fromCamel
camel.value.to = fromCamel.value.to

toPascal.column = { from: toPascal }
toPascal.value = { from: createJsonTransform(toPascal) }
fromPascal.column = { to: fromPascal }
fromPascal.value = { to: createJsonTransform(fromPascal) }

export const pascal = { ...toPascal }
pascal.column.to = fromPascal
pascal.value.to = fromPascal.value.to

toKebab.column = { from: toKebab }
toKebab.value = { from: createJsonTransform(toKebab) }
fromKebab.column = { to: fromKebab }
fromKebab.value = { to: createJsonTransform(fromKebab) }

export const kebab = { ...toKebab }
kebab.column.to = fromKebab
kebab.value.to = fromKebab.value.to
71 changes: 71 additions & 0 deletions deno/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,77 @@ t('Json', async() => {
return ['hello,42', [x.a, x.b].join()]
})

t('Json transform parameter keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.json({ aTest: 1 }) }->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json without transform keeps parameter keys', async() => {
const x = (await sql`select ${ sql.json({ aTest: 1 }) }->>'aTest' as x`)[0].x
return ['1', x]
})

t('Json transform nested parameter keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`
select ${ sql.json({ aTest: [{ bTest: 1 }, { bTest: 2 }] }) }#>>'{a_test,1,b_test}' as x
`)[0].x
return ['2', x]
})

t('Json transform typed json parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.typed({ aTest: 1 }, 114) }->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform implicit jsonb parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ { aTest: 1 } }::jsonb->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform implicit json parameters', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ { aTest: 1 } }::json->>'a_test' as x`)[0].x
return ['1', x]
})

t('Json transform result keys', async() => {
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select '{"a_test":1}'::jsonb as x`)[0].x
return [1, x.aTest]
})

t('Json transform does not transform parameter values with .toJSON()', async() => {
const now = new Date()
const sql = postgres({
...options,
transform: postgres.camel
})
const x = (await sql`select ${ sql.json({ aTest: now }) }->>'a_test' as x`)[0].x
return [now.toJSON(), x]
})

t('implicit json', async() => {
const x = (await sql`select ${ { a: 'hello', b: 42 } }::json as x`)[0].x
return ['hello,42', [x.a, x.b].join()]
Expand Down
26 changes: 19 additions & 7 deletions deno/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ declare namespace postgres {
function toPascal(str: string): string;
namespace toPascal {
namespace column { function from(str: string): string; }
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value { function from(str: unknown, column: Column<string>): unknown }
}
/**
* Convert a PascalCase string to snake_case.
Expand All @@ -246,6 +246,7 @@ declare namespace postgres {
function fromPascal(str: string): string;
namespace fromPascal {
namespace column { function to(str: string): string }
namespace value { function to(str: unknown, column: Column<string>): unknown }
}
/**
* Convert snake_case to and from PascalCase.
Expand All @@ -255,7 +256,10 @@ declare namespace postgres {
function from(str: string): string;
function to(str: string): string;
}
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value {
function from(str: unknown, column: Column<string>): unknown;
function to(str: unknown, column: Column<string>): unknown;
}
}
/**
* Convert a snake_case string to camelCase.
Expand All @@ -265,7 +269,7 @@ declare namespace postgres {
function toCamel(str: string): string;
namespace toCamel {
namespace column { function from(str: string): string; }
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value { function from(str: unknown, column: Column<string>): unknown }
}
/**
* Convert a camelCase string to snake_case.
Expand All @@ -275,6 +279,7 @@ declare namespace postgres {
function fromCamel(str: string): string;
namespace fromCamel {
namespace column { function to(str: string): string }
namespace value { function to(str: unknown, column: Column<string>): unknown }
}
/**
* Convert snake_case to and from camelCase.
Expand All @@ -284,7 +289,10 @@ declare namespace postgres {
function from(str: string): string;
function to(str: string): string;
}
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value {
function from(str: unknown, column: Column<string>): unknown;
function to(str: unknown, column: Column<string>): unknown;
}
}
/**
* Convert a snake_case string to kebab-case.
Expand All @@ -294,7 +302,7 @@ declare namespace postgres {
function toKebab(str: string): string;
namespace toKebab {
namespace column { function from(str: string): string; }
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value { function from(str: unknown, column: Column<string>): unknown }
}
/**
* Convert a kebab-case string to snake_case.
Expand All @@ -304,6 +312,7 @@ declare namespace postgres {
function fromKebab(str: string): string;
namespace fromKebab {
namespace column { function to(str: string): string }
namespace value { function to(str: unknown, column: Column<string>): unknown }
}
/**
* Convert snake_case to and from kebab-case.
Expand All @@ -313,7 +322,10 @@ declare namespace postgres {
function from(str: string): string;
function to(str: string): string;
}
namespace value { function from(str: unknown, column: Column<string>): string }
namespace value {
function from(str: unknown, column: Column<string>): unknown;
function to(str: unknown, column: Column<string>): unknown;
}
}

const BigInt: PostgresType<bigint>;
Expand Down Expand Up @@ -404,7 +416,7 @@ declare namespace postgres {
/** Transform function for values in result rows */
from: ((value: any, column?: Column<string>) => any) | undefined;
/** Transform function for interpolated values passed to tagged template literal */
to: undefined; // (value: any) => any
to: ((value: any, column?: Column<string>) => any) | undefined;
};
row: {
/** Transform function for entire result rows */
Expand Down
1 change: 1 addition & 0 deletions src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
return b.i32(0xFFFFFFFF)

type = types[i]
x = options.transform.value.to ? options.transform.value.to(x, { type }) : x
parameters[i] = x = type in options.serializers
? options.serializers[type](x)
: '' + x
Expand Down
Loading
Loading