From 38210cebe5bce05fe636897f18d4027c0c080535 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Mon, 28 Nov 2022 12:04:44 +0000 Subject: [PATCH 1/2] Don't parse number arrays as date --- packages/server/src/integrations/mysql.ts | 2 +- .../src/integrations/tests/mysql.spec.ts | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index 69dbb40480..65f8323fea 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -106,7 +106,7 @@ function bindingTypeCoerce(bindings: any[]) { } // if not a number, see if it is a date - important to do in this order as any // integer will be considered a valid date - else if (/^\d/.test(binding) && dayjs(binding).isValid()) { + else if (/^\d/.test(binding) && dayjs(binding).isValid() && !binding.includes(",")) { bindings[i] = dayjs(binding).toDate() } } diff --git a/packages/server/src/integrations/tests/mysql.spec.ts b/packages/server/src/integrations/tests/mysql.spec.ts index a70eb73857..6ad3b4e6e2 100644 --- a/packages/server/src/integrations/tests/mysql.spec.ts +++ b/packages/server/src/integrations/tests/mysql.spec.ts @@ -73,4 +73,49 @@ describe("MySQL Integration", () => { expect(response).toEqual([{ deleted: true }]) }) }) + + describe("binding type coerce", () => { + it("ignores non-string types ", async () => { + const sql = "select * from users;" + const date = new Date() + await config.integration.read({ + sql, + bindings: [11, date, ["a", "b", "c"], { id: 1}] + }) + expect(config.integration.client.query).toHaveBeenCalledWith(sql, [11, date, ["a", "b", "c"], { id: 1}]) + }) + + it("parses strings matching a number regex", async () => { + const sql = "select * from users;" + await config.integration.read({ + sql, + bindings: ["101", "3.14"] + }) + expect(config.integration.client.query).toHaveBeenCalledWith(sql, [101, 3.14]) + }) + + it("parses strings matching a valid date format", async () => { + const sql = "select * from users;" + await config.integration.read({ + sql, + bindings: ["2001-10-30", "2010-09-01T13:30:59.123Z", "2021-02-05 12:01 PM"] + }) + expect(config.integration.client.query).toHaveBeenCalledWith(sql, [ + new Date("2001-10-30T00:00:00.000Z"), + new Date("2010-09-01T13:30:59.123Z"), + new Date("2021-02-05T12:01:00.000Z") + ]) + }) + + it("does not parse string matching a valid array of numbers as date", async () => { + const sql = "select * from users;" + await config.integration.read({ + sql, + bindings: ["1,2,2017"] + }) + expect(config.integration.client.query).toHaveBeenCalledWith(sql, [ + "1,2,2017" + ]) + }) + }) }) From cde3c2e8ff6d04128e0d657d88675b91cdea4e97 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Mon, 28 Nov 2022 12:05:19 +0000 Subject: [PATCH 2/2] lint --- packages/server/src/integrations/mysql.ts | 6 +++- .../src/integrations/tests/mysql.spec.ts | 30 +++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index 65f8323fea..acf8f4904a 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -106,7 +106,11 @@ function bindingTypeCoerce(bindings: any[]) { } // if not a number, see if it is a date - important to do in this order as any // integer will be considered a valid date - else if (/^\d/.test(binding) && dayjs(binding).isValid() && !binding.includes(",")) { + else if ( + /^\d/.test(binding) && + dayjs(binding).isValid() && + !binding.includes(",") + ) { bindings[i] = dayjs(binding).toDate() } } diff --git a/packages/server/src/integrations/tests/mysql.spec.ts b/packages/server/src/integrations/tests/mysql.spec.ts index 6ad3b4e6e2..c4a26beb60 100644 --- a/packages/server/src/integrations/tests/mysql.spec.ts +++ b/packages/server/src/integrations/tests/mysql.spec.ts @@ -80,30 +80,42 @@ describe("MySQL Integration", () => { const date = new Date() await config.integration.read({ sql, - bindings: [11, date, ["a", "b", "c"], { id: 1}] + bindings: [11, date, ["a", "b", "c"], { id: 1 }], }) - expect(config.integration.client.query).toHaveBeenCalledWith(sql, [11, date, ["a", "b", "c"], { id: 1}]) + expect(config.integration.client.query).toHaveBeenCalledWith(sql, [ + 11, + date, + ["a", "b", "c"], + { id: 1 }, + ]) }) it("parses strings matching a number regex", async () => { const sql = "select * from users;" await config.integration.read({ sql, - bindings: ["101", "3.14"] + bindings: ["101", "3.14"], }) - expect(config.integration.client.query).toHaveBeenCalledWith(sql, [101, 3.14]) + expect(config.integration.client.query).toHaveBeenCalledWith( + sql, + [101, 3.14] + ) }) it("parses strings matching a valid date format", async () => { const sql = "select * from users;" await config.integration.read({ sql, - bindings: ["2001-10-30", "2010-09-01T13:30:59.123Z", "2021-02-05 12:01 PM"] + bindings: [ + "2001-10-30", + "2010-09-01T13:30:59.123Z", + "2021-02-05 12:01 PM", + ], }) expect(config.integration.client.query).toHaveBeenCalledWith(sql, [ - new Date("2001-10-30T00:00:00.000Z"), + new Date("2001-10-30T00:00:00.000Z"), new Date("2010-09-01T13:30:59.123Z"), - new Date("2021-02-05T12:01:00.000Z") + new Date("2021-02-05T12:01:00.000Z"), ]) }) @@ -111,10 +123,10 @@ describe("MySQL Integration", () => { const sql = "select * from users;" await config.integration.read({ sql, - bindings: ["1,2,2017"] + bindings: ["1,2,2017"], }) expect(config.integration.client.query).toHaveBeenCalledWith(sql, [ - "1,2,2017" + "1,2,2017", ]) }) })