From a5dbda5c6baad536ae0e8ce7e7d44b93381b2491 Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Thu, 5 Feb 2026 05:05:18 -0300 Subject: [PATCH] fix: preserve `JSON` path expressions --- src/index.ts | 3 ++- test/everyday-queries.test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 018d8ef..72234df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -312,8 +312,9 @@ export const escapeId = ( } const identifier = String(value); + const hasJsonOperator = identifier.indexOf('->') !== -1; - if (forbidQualified) { + if (forbidQualified || hasJsonOperator) { if (identifier.indexOf('`') === -1) return `\`${identifier}\``; return `\`${identifier.replace(regex.backtick, '``')}\``; diff --git a/test/everyday-queries.test.ts b/test/everyday-queries.test.ts index 73c65c1..761d660 100644 --- a/test/everyday-queries.test.ts +++ b/test/everyday-queries.test.ts @@ -459,6 +459,35 @@ describe('Nice to have: escapeId edge cases', () => { }); }); +describe('JSON path expressions with ?? placeholder', () => { + test('should handle JSON arrow operator with path expression', () => { + const query = format('SELECT * FROM ?? WHERE (?? = ?) LIMIT ?, ?', [ + 'certification', + "cert->>'$.name'", + 'myname', + 0, + 20, + ]); + + assert.equal( + query, + "SELECT * FROM `certification` WHERE (`cert->>'$.name'` = 'myname') LIMIT 0, 20" + ); + }); + + test('escapeId should not break JSON path expressions', () => { + const escaped = escapeId("cert->>'$.name'"); + + assert.equal(escaped, "`cert->>'$.name'`"); + }); + + test('escapeId with JSON double arrow operator', () => { + const escaped = escapeId("data->'$.user.address.city'"); + + assert.equal(escaped, "`data->'$.user.address.city'`"); + }); +}); + describe('Nice to have: Deeply nested arrays', () => { test('triple nested array for bulk insert', () => { const data = [