diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index e75b2c2d..c87c430b 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -90,7 +90,12 @@ jobs: run: npm run test-tedious - name: Run cli tests run: npm run test-cli -# The msnodesqlv8 tests fail with a segmentation fault + - name: Install tedious 20 + if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }} + run: npm install --no-save tedious@^20.0.0 + - name: Run tedious 20 tests + if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }} + run: npm run test-tedious # - name: Install OBDC 17 driver # run: | # sudo curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - @@ -145,6 +150,12 @@ jobs: run: npm run test-tedious - name: Run cli tests run: npm run test-cli + - name: Install tedious 20 + if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }} + run: npm install --no-save tedious@^20.0.0 + - name: Run tedious 20 tests + if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }} + run: npm run test-tedious # msnodesqlv8 is exercised across its supported major versions. Each major # is gated to the Node versions it ships prebuilt win32-x64 binaries for — # a combo without a prebuild falls back to a node-gyp source build, which is diff --git a/lib/tedious/request.js b/lib/tedious/request.js index 2c19213e..8a6f6913 100644 --- a/lib/tedious/request.js +++ b/lib/tedious/request.js @@ -23,22 +23,6 @@ const N_TYPES = { NumericN: 0x6C } -// Workaround for tedious TVP declaration not including schema name. -// See: https://github.com/tediousjs/node-mssql/issues/1759 -const SchemaAwareTVP = Object.create(tds.TYPES.TVP, { - declaration: { - value: function (parameter) { - const value = parameter.value - if (value && value.schema) { - return value.schema + '.' + value.name + ' readonly' - } - return value.name + ' readonly' - }, - writable: true, - configurable: true - } -}) - const getTediousType = function (type) { switch (type) { case TYPES.VarChar: return tds.TYPES.VarChar @@ -70,7 +54,7 @@ const getTediousType = function (type) { case TYPES.Binary: return tds.TYPES.Binary case TYPES.VarBinary: return tds.TYPES.VarBinary case TYPES.UDT: case TYPES.Geography: case TYPES.Geometry: return tds.TYPES.UDT - case TYPES.TVP: return SchemaAwareTVP + case TYPES.TVP: return tds.TYPES.TVP case TYPES.Variant: return tds.TYPES.Variant default: return type } diff --git a/package-lock.json b/package-lock.json index a420046c..18eb466d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "commander": "^11.0.0", "debug": "^4.3.3", "tarn": "^3.0.2", - "tedious": "^19.0.0" + "tedious": "^19.2.2" }, "bin": { "mssql": "bin/mssql" @@ -891,9 +891,10 @@ } }, "node_modules/@js-joda/core": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-5.6.5.tgz", - "integrity": "sha512-3zwefSMwHpu8iVUW8YYz227sIv6UFqO31p1Bf1ZH/Vom7CmNyUsXjDBlnNzcuhmOL1XfxZ3nvND42kR23XlbcQ==" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-6.0.1.tgz", + "integrity": "sha512-Iev3Cfa3MC+06JXXeFzSLew/7yeCXLMhjesyH/BD4EQYlUUDV49Ln3s8hd7p5XK5UesO/dO3K1LFJ7RT7v0Ddg==", + "license": "BSD-3-Clause" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -10035,14 +10036,15 @@ } }, "node_modules/tedious": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/tedious/-/tedious-19.2.1.tgz", - "integrity": "sha512-pk1Q16Yl62iocuQB+RWbg6rFUFkIyzqOFQ6NfysCltRvQqKwfurgj8v/f2X+CKvDhSL4IJ0cCOfCHDg9PWEEYA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/tedious/-/tedious-19.2.2.tgz", + "integrity": "sha512-ITsLV/XXXAuJ/+pgnod4lcJH83WPK7+y2aqOwK/ERoC4zX73wfRIVc7BofuHCqDTqpd6j1RwTBtjKNuuOLEvfw==", + "license": "MIT", "dependencies": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", - "@js-joda/core": "^5.6.5", + "@js-joda/core": "^6.0.1", "@types/node": ">=18", "bl": "^6.1.4", "iconv-lite": "^0.7.0", @@ -11470,9 +11472,9 @@ } }, "@js-joda/core": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-5.6.5.tgz", - "integrity": "sha512-3zwefSMwHpu8iVUW8YYz227sIv6UFqO31p1Bf1ZH/Vom7CmNyUsXjDBlnNzcuhmOL1XfxZ3nvND42kR23XlbcQ==" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-6.0.1.tgz", + "integrity": "sha512-Iev3Cfa3MC+06JXXeFzSLew/7yeCXLMhjesyH/BD4EQYlUUDV49Ln3s8hd7p5XK5UesO/dO3K1LFJ7RT7v0Ddg==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -17662,14 +17664,14 @@ "integrity": "sha512-QDihlHbXxQ4SnuQcRd1TPNBHUYo/hafDRDP82COYSVfRcx/3qnfGDkn1WFjozVl+AYr8ZyDKSQ/kIgHH1ri1yg==" }, "tedious": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/tedious/-/tedious-19.2.1.tgz", - "integrity": "sha512-pk1Q16Yl62iocuQB+RWbg6rFUFkIyzqOFQ6NfysCltRvQqKwfurgj8v/f2X+CKvDhSL4IJ0cCOfCHDg9PWEEYA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/tedious/-/tedious-19.2.2.tgz", + "integrity": "sha512-ITsLV/XXXAuJ/+pgnod4lcJH83WPK7+y2aqOwK/ERoC4zX73wfRIVc7BofuHCqDTqpd6j1RwTBtjKNuuOLEvfw==", "requires": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", - "@js-joda/core": "^5.6.5", + "@js-joda/core": "^6.0.1", "@types/node": ">=18", "bl": "^6.1.4", "iconv-lite": "^0.7.0", diff --git a/package.json b/package.json index d46112d4..5df02ee5 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "commander": "^11.0.0", "debug": "^4.3.3", "tarn": "^3.0.2", - "tedious": "^19.0.0" + "tedious": "^19.2.2 || ^20.0.0" }, "devDependencies": { "@commitlint/cli": "^20.0.0", diff --git a/test/common/unit.js b/test/common/unit.js index 623a3994..e9e80206 100644 --- a/test/common/unit.js +++ b/test/common/unit.js @@ -1088,27 +1088,7 @@ describe('connection string auth - tedious', () => { describe('TVP declaration with schema', () => { const tds = require('tedious') - it('documents upstream tedious bug: schema missing from TVP declaration', () => { - const tvp = new sql.Table('AI.UDT_StringArray') - tvp.columns.add('Name', sql.NVarChar(128), { nullable: false }) - tvp.rows.add('TestValue1') - - const tvpValue = { - name: tvp.name, - schema: tvp.schema, - columns: [], - rows: tvp.rows - } - - // tedious's own TVP type does NOT include schema in declaration - const req = new tds.Request('SELECT 1') - req.addParameter('InputList', tds.TYPES.TVP, tvpValue) - const paramsStr = req.makeParamsParameter(req.parameters) - assert.strictEqual(paramsStr, '@InputList UDT_StringArray readonly', - 'tedious itself does not include schema - this documents the upstream bug') - }) - - it('schema-aware TVP type includes schema in declaration', () => { + it('tedious includes schema in TVP declaration', () => { const tvp = new sql.Table('AI.UDT_StringArray') tvp.columns.add('Name', sql.NVarChar(128), { nullable: false }) tvp.rows.add('TestValue1') @@ -1123,29 +1103,13 @@ describe('connection string auth - tedious', () => { assert.strictEqual(tvp.name, 'UDT_StringArray') assert.strictEqual(tvp.schema, 'AI') - // Use the patched SchemaAwareTVP type from lib/tedious/request.js - // Since it's not exported, recreate the same pattern to verify behavior - const SchemaAwareTVP = Object.create(tds.TYPES.TVP, { - declaration: { - value: function (parameter) { - const value = parameter.value - if (value && value.schema) { - return value.schema + '.' + value.name + ' readonly' - } - return value.name + ' readonly' - }, - writable: true, - configurable: true - } - }) - const req = new tds.Request('SELECT 1') - req.addParameter('InputList', SchemaAwareTVP, tvpValue) + req.addParameter('InputList', tds.TYPES.TVP, tvpValue) const paramsStr = req.makeParamsParameter(req.parameters) assert.strictEqual(paramsStr, '@InputList AI.UDT_StringArray readonly') }) - it('schema-aware TVP works without schema', () => { + it('tedious TVP works without schema', () => { const tvp = new sql.Table('UDT_StringArray') tvp.columns.add('Name', sql.NVarChar(128), { nullable: false }) @@ -1159,52 +1123,11 @@ describe('connection string auth - tedious', () => { assert.strictEqual(tvp.name, 'UDT_StringArray') assert.strictEqual(tvp.schema, null) - const SchemaAwareTVP = Object.create(tds.TYPES.TVP, { - declaration: { - value: function (parameter) { - const value = parameter.value - if (value && value.schema) { - return value.schema + '.' + value.name + ' readonly' - } - return value.name + ' readonly' - }, - writable: true, - configurable: true - } - }) - const req = new tds.Request('SELECT 1') - req.addParameter('InputList', SchemaAwareTVP, tvpValue) + req.addParameter('InputList', tds.TYPES.TVP, tvpValue) const paramsStr = req.makeParamsParameter(req.parameters) assert.strictEqual(paramsStr, '@InputList UDT_StringArray readonly') }) - - it('schema-aware TVP inherits generateTypeInfo from tedious TVP', () => { - const SchemaAwareTVP = Object.create(tds.TYPES.TVP, { - declaration: { - value: function (parameter) { - const value = parameter.value - if (value && value.schema) { - return value.schema + '.' + value.name + ' readonly' - } - return value.name + ' readonly' - }, - writable: true, - configurable: true - } - }) - - // Verify it inherits all other methods from tedious TVP - assert.strictEqual(SchemaAwareTVP.id, tds.TYPES.TVP.id) - assert.strictEqual(SchemaAwareTVP.type, tds.TYPES.TVP.type) - assert.strictEqual(SchemaAwareTVP.name, tds.TYPES.TVP.name) - assert.strictEqual(SchemaAwareTVP.generateTypeInfo, tds.TYPES.TVP.generateTypeInfo) - assert.strictEqual(SchemaAwareTVP.generateParameterLength, tds.TYPES.TVP.generateParameterLength) - assert.strictEqual(SchemaAwareTVP.generateParameterData, tds.TYPES.TVP.generateParameterData) - assert.strictEqual(SchemaAwareTVP.validate, tds.TYPES.TVP.validate) - // declaration is overridden - assert.notStrictEqual(SchemaAwareTVP.declaration, tds.TYPES.TVP.declaration) - }) }) describe('msnodesqlv8 TVP declaration', () => {