From d4de9d4395b758b068a48ee948f23cb05160796d Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Sun, 11 Jan 2026 14:09:46 +0200 Subject: [PATCH 1/7] In Taboola adapter, added support for native and adjusted the existing banner support. Added and updated tests. --- modules/taboolaBidAdapter.js | 46 +++-- test/spec/modules/taboolaBidAdapter_spec.js | 197 +++++++++++++++++++- 2 files changed, 224 insertions(+), 19 deletions(-) diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index 421ddbd256b..e13085d4a26 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -1,7 +1,7 @@ 'use strict'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import {BANNER, NATIVE} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; import {deepSetValue, getWindowSelf, replaceAuctionPrice, isArray, safeJSONParse, isPlainObject, getWinDimensions} from '../src/utils.js'; import {getStorageManager} from '../src/storageManager.js'; @@ -15,7 +15,8 @@ import {getBoundingClientRect} from '../libraries/boundingClientRect/boundingCli const BIDDER_CODE = 'taboola'; const GVLID = 42; const CURRENCY = 'USD'; -export const END_POINT_URL = 'https://display.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; +export const BANNER_ENDPOINT_URL = 'https://display.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; +export const NATIVE_ENDPOINT_URL = 'https://native.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; export const USER_SYNC_IMG_URL = 'https://trc.taboola.com/sg/prebidJS/1/cm'; export const USER_SYNC_IFRAME_URL = 'https://cdn.taboola.com/scripts/prebid_iframe_sync.html'; const USER_ID = 'user-id'; @@ -169,7 +170,6 @@ export function getElementSignals(adUnitCode) { const converter = ortbConverter({ context: { netRevenue: true, - mediaType: BANNER, ttl: 300 }, imp(buildImp, bidRequest, context) { @@ -183,12 +183,26 @@ const converter = ortbConverter({ return reqData; }, bidResponse(buildBidResponse, bid, context) { + const hasNative = !!context.bidRequest?.mediaTypes?.native; + const hasBanner = !!context.bidRequest?.mediaTypes?.banner; + context.mediaType = hasNative && !hasBanner ? NATIVE : BANNER; + + // Unwrap native response - server returns {native: {...}} but ortbConverter expects {...} + if (context.mediaType === NATIVE) { + const admObj = safeJSONParse(bid.adm); + if (admObj?.native) { + bid.adm = JSON.stringify(admObj.native); + } + } + const bidResponse = buildBidResponse(bid, context); bidResponse.nurl = bid.nurl; if (bid.burl) { bidResponse.burl = bid.burl; } - bidResponse.ad = replaceAuctionPrice(bid.adm, bid.price); + if (bidResponse.mediaType !== NATIVE) { + bidResponse.ad = replaceAuctionPrice(bid.adm, bid.price); + } if (bid.ext && bid.ext.dchain) { deepSetValue(bidResponse, 'meta.dchain', bid.ext.dchain); } @@ -197,14 +211,19 @@ const converter = ortbConverter({ }); export const spec = { - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, NATIVE], gvlid: GVLID, code: BIDDER_CODE, isBidRequestValid: (bidRequest) => { - return !!(bidRequest.sizes && - bidRequest.params && + const hasPublisherAndTag = !!(bidRequest.params && bidRequest.params.publisherId && bidRequest.params.tagId); + if (!hasPublisherAndTag) { + return false; + } + const hasBanner = !!bidRequest.mediaTypes?.banner; + const hasNative = !!bidRequest.mediaTypes?.native; + return hasBanner || hasNative; }, buildRequests: (validBidRequests, bidderRequest) => { const [bidRequest] = validBidRequests; @@ -215,7 +234,9 @@ export const spec = { context: { auctionId } }); const {publisherId} = bidRequest.params; - const url = END_POINT_URL + '?publisher=' + publisherId; + const isNative = !!bidRequest.mediaTypes?.native; + const baseUrl = isNative ? NATIVE_ENDPOINT_URL : BANNER_ENDPOINT_URL; + const url = baseUrl + '?publisher=' + publisherId; return { url, @@ -433,7 +454,10 @@ function fillTaboolaReqData(bidderRequest, bidRequest, data, context) { function fillTaboolaImpData(bid, imp) { const {tagId, position} = bid.params; - imp.banner = getBanners(bid, position); + const bannerSizes = bid.mediaTypes?.banner?.sizes; + if (bannerSizes) { + imp.banner = getBanners(bannerSizes, position); + } imp.tagid = tagId; if (typeof bid.getFloor === 'function') { @@ -476,9 +500,9 @@ function fillTaboolaImpData(bid, imp) { } } -function getBanners(bid, pos) { +function getBanners(sizes, pos) { return { - ...getSizes(bid.sizes), + ...getSizes(sizes), pos: pos } } diff --git a/test/spec/modules/taboolaBidAdapter_spec.js b/test/spec/modules/taboolaBidAdapter_spec.js index 8c23be4bcd0..1a31c94d7dd 100644 --- a/test/spec/modules/taboolaBidAdapter_spec.js +++ b/test/spec/modules/taboolaBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec, internal, END_POINT_URL, userData, EVENT_ENDPOINT, detectBot, getPageVisibility} from 'modules/taboolaBidAdapter.js'; +import {spec, internal, BANNER_ENDPOINT_URL, userData, EVENT_ENDPOINT, detectBot, getPageVisibility} from 'modules/taboolaBidAdapter.js'; import {config} from '../../../src/config.js' import * as utils from '../../../src/utils.js' import {server} from '../../mocks/xhr.js' @@ -33,7 +33,11 @@ describe('Taboola Adapter', function () { }) const displayBidRequestParams = { - sizes: [[300, 250], [300, 600]] + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + } } const createBidRequest = () => ({ @@ -270,18 +274,18 @@ describe('Taboola Adapter', function () { const expectedData = { 'imp': [{ 'id': res.data.imp[0].id, - 'secure': 1, 'banner': { format: [{ - w: displayBidRequestParams.sizes[0][0], - h: displayBidRequestParams.sizes[0][1] + w: displayBidRequestParams.mediaTypes.banner.sizes[0][0], + h: displayBidRequestParams.mediaTypes.banner.sizes[0][1] }, { - w: displayBidRequestParams.sizes[1][0], - h: displayBidRequestParams.sizes[1][1] + w: displayBidRequestParams.mediaTypes.banner.sizes[1][0], + h: displayBidRequestParams.mediaTypes.banner.sizes[1][1] } ] }, + 'secure': 1, 'tagid': commonBidRequest.params.tagId, 'bidfloor': null, 'bidfloorcur': 'USD', @@ -315,7 +319,7 @@ describe('Taboola Adapter', function () { 'ext': res.data.ext }; - expect(res.url).to.equal(`${END_POINT_URL}?publisher=${commonBidRequest.params.publisherId}`); + expect(res.url).to.equal(`${BANNER_ENDPOINT_URL}?publisher=${commonBidRequest.params.publisherId}`); expect(JSON.stringify(res.data)).to.deep.equal(JSON.stringify(expectedData)); expect(res.data.ext.prebid.version).to.equal('$prebid.version$'); }); @@ -1980,4 +1984,181 @@ describe('Taboola Adapter', function () { }); }); }) + + describe('native', function () { + const commonBidderRequest = { + bidderRequestId: 'mock-uuid', + refererInfo: { + page: 'https://example.com/ref', + ref: 'https://ref', + domain: 'example.com', + }, + ortb2: { + device: { + ua: navigator.userAgent, + }, + } + }; + + const nativeBidRequestParams = { + mediaTypes: { + native: { + title: {required: true, len: 150}, + image: {required: true, sizes: [300, 250]}, + sponsoredBy: {required: true} + } + } + }; + + describe('isBidRequestValid', function () { + it('should return true for valid native bid without sizes', function () { + const bid = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'native-placement' + }, + ...nativeBidRequestParams + }; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false for native bid without publisherId', function () { + const bid = { + bidder: 'taboola', + params: { + tagId: 'native-placement' + }, + ...nativeBidRequestParams + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false for native bid without tagId', function () { + const bid = { + bidder: 'taboola', + params: { + publisherId: 'publisherId' + }, + ...nativeBidRequestParams + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + it('should build native request without banner imp', function () { + const nativeBidRequest = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'native-placement' + }, + ...nativeBidRequestParams, + nativeOrtbRequest: { + ver: '1.2', + assets: [ + {id: 1, required: 1, title: {len: 150}}, + {id: 2, required: 1, img: {type: 3, w: 300, h: 250}}, + {id: 3, required: 1, data: {type: 1}} + ] + }, + bidId: utils.generateUUID(), + auctionId: utils.generateUUID(), + }; + + const res = spec.buildRequests([nativeBidRequest], commonBidderRequest); + + expect(res.data.imp[0]).to.not.have.property('banner'); + expect(res.data.imp[0]).to.have.property('native'); // TODO native isn't added! + expect(res.data.imp[0].tagid).to.equal('native-placement'); + }); + + it('should build banner request without native imp', function () { + const bannerBidRequest = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'banner-placement' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bidId: utils.generateUUID(), + auctionId: utils.generateUUID(), + }; + + const res = spec.buildRequests([bannerBidRequest], commonBidderRequest); + + expect(res.data.imp[0]).to.have.property('banner'); + expect(res.data.imp[0]).to.not.have.property('native'); + expect(res.data.imp[0]).to.not.have.property('native'); + }); + }); + + describe('interpretResponse', function () { + it('should interpret native response correctly', function () { + const nativeBidRequest = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'native-placement' + }, + ...nativeBidRequestParams, + nativeOrtbRequest: { + ver: '1.2', + assets: [ + {id: 1, required: 1, title: {len: 150}}, + {id: 2, required: 1, img: {type: 3, w: 300, h: 250}} + ] + }, + bidId: utils.generateUUID(), + auctionId: utils.generateUUID(), + }; + + const request = spec.buildRequests([nativeBidRequest], commonBidderRequest); + + const nativeAdm = { + ver: '1.2', + assets: [ + {id: 1, title: {text: 'Native Ad Title'}}, + {id: 2, img: {url: 'https://example.com/image.jpg', w: 300, h: 250}} + ], + link: { + url: 'https://example.com/click' + } + }; + + const serverResponse = { + body: { + id: 'response-id', + seatbid: [{ + bid: [{ + id: 'bid-id', + impid: request.data.imp[0].id, + price: 1.5, + adm: JSON.stringify(nativeAdm), + adomain: ['example.com'], + crid: 'creative-id', + exp: 300, + nurl: 'https://example.com/win' + }], + seat: 'taboola' + }], + cur: 'USD' + } + }; + + const res = spec.interpretResponse(serverResponse, request); + + expect(res).to.be.an('array').with.lengthOf(1); + expect(res[0].mediaType).to.equal('native'); + expect(res[0].native).to.exist; + expect(res[0].native.ortb).to.deep.equal(nativeAdm); + expect(res[0]).to.not.have.property('ad'); + }); + }); + }); }) From d7fae2386bc7f9f1c3fae3a603299e671074a854 Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Sun, 11 Jan 2026 14:05:39 +0200 Subject: [PATCH 2/7] In Taboola adapter, added support for native and adjusted the existing banner support. Added and updated tests. --- .../gpt/taboola_native_test.html | 164 ++++++++++++++++++ modules/taboolaBidAdapter.js | 1 - 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 integrationExamples/gpt/taboola_native_test.html diff --git a/integrationExamples/gpt/taboola_native_test.html b/integrationExamples/gpt/taboola_native_test.html new file mode 100644 index 00000000000..e8444d82ced --- /dev/null +++ b/integrationExamples/gpt/taboola_native_test.html @@ -0,0 +1,164 @@ + + + Taboola Native Prebid.js Example + + + + + + +

Taboola Native Prebid.js Example

+
Native Ad Container
+
+

Loading native ad...

+
+ + diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index e13085d4a26..d6da9f3fc50 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -187,7 +187,6 @@ const converter = ortbConverter({ const hasBanner = !!context.bidRequest?.mediaTypes?.banner; context.mediaType = hasNative && !hasBanner ? NATIVE : BANNER; - // Unwrap native response - server returns {native: {...}} but ortbConverter expects {...} if (context.mediaType === NATIVE) { const admObj = safeJSONParse(bid.adm); if (admObj?.native) { From 53fe2c5767939a8b7f7ba09a5335d581536aa470 Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Sun, 11 Jan 2026 14:37:25 +0200 Subject: [PATCH 3/7] removed test page pushed accidentally --- .../gpt/taboola_native_test.html | 164 ------------------ 1 file changed, 164 deletions(-) delete mode 100644 integrationExamples/gpt/taboola_native_test.html diff --git a/integrationExamples/gpt/taboola_native_test.html b/integrationExamples/gpt/taboola_native_test.html deleted file mode 100644 index e8444d82ced..00000000000 --- a/integrationExamples/gpt/taboola_native_test.html +++ /dev/null @@ -1,164 +0,0 @@ - - - Taboola Native Prebid.js Example - - - - - - -

Taboola Native Prebid.js Example

-
Native Ad Container
-
-

Loading native ad...

-
- - From a9754e9d53999f7241dd59b0bf4fa1c36f13bd50 Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Sun, 11 Jan 2026 16:27:30 +0200 Subject: [PATCH 4/7] Wrapped native tests with NATIVE feature check --- test/spec/modules/taboolaBidAdapter_spec.js | 162 ++++++++++---------- 1 file changed, 83 insertions(+), 79 deletions(-) diff --git a/test/spec/modules/taboolaBidAdapter_spec.js b/test/spec/modules/taboolaBidAdapter_spec.js index 1a31c94d7dd..e488ffacef2 100644 --- a/test/spec/modules/taboolaBidAdapter_spec.js +++ b/test/spec/modules/taboolaBidAdapter_spec.js @@ -2047,32 +2047,34 @@ describe('Taboola Adapter', function () { }); describe('buildRequests', function () { - it('should build native request without banner imp', function () { - const nativeBidRequest = { - bidder: 'taboola', - params: { - publisherId: 'publisherId', - tagId: 'native-placement' - }, - ...nativeBidRequestParams, - nativeOrtbRequest: { - ver: '1.2', - assets: [ - {id: 1, required: 1, title: {len: 150}}, - {id: 2, required: 1, img: {type: 3, w: 300, h: 250}}, - {id: 3, required: 1, data: {type: 1}} - ] - }, - bidId: utils.generateUUID(), - auctionId: utils.generateUUID(), - }; + if (FEATURES.NATIVE) { + it('should build native request without banner imp', function () { + const nativeBidRequest = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'native-placement' + }, + ...nativeBidRequestParams, + nativeOrtbRequest: { + ver: '1.2', + assets: [ + {id: 1, required: 1, title: {len: 150}}, + {id: 2, required: 1, img: {type: 3, w: 300, h: 250}}, + {id: 3, required: 1, data: {type: 1}} + ] + }, + bidId: utils.generateUUID(), + auctionId: utils.generateUUID(), + }; - const res = spec.buildRequests([nativeBidRequest], commonBidderRequest); + const res = spec.buildRequests([nativeBidRequest], commonBidderRequest); - expect(res.data.imp[0]).to.not.have.property('banner'); - expect(res.data.imp[0]).to.have.property('native'); // TODO native isn't added! - expect(res.data.imp[0].tagid).to.equal('native-placement'); - }); + expect(res.data.imp[0]).to.not.have.property('banner'); + expect(res.data.imp[0]).to.have.property('native'); + expect(res.data.imp[0].tagid).to.equal('native-placement'); + }); + } it('should build banner request without native imp', function () { const bannerBidRequest = { @@ -2099,66 +2101,68 @@ describe('Taboola Adapter', function () { }); describe('interpretResponse', function () { - it('should interpret native response correctly', function () { - const nativeBidRequest = { - bidder: 'taboola', - params: { - publisherId: 'publisherId', - tagId: 'native-placement' - }, - ...nativeBidRequestParams, - nativeOrtbRequest: { - ver: '1.2', - assets: [ - {id: 1, required: 1, title: {len: 150}}, - {id: 2, required: 1, img: {type: 3, w: 300, h: 250}} - ] - }, - bidId: utils.generateUUID(), - auctionId: utils.generateUUID(), - }; + if (FEATURES.NATIVE) { + it('should interpret native response correctly', function () { + const nativeBidRequest = { + bidder: 'taboola', + params: { + publisherId: 'publisherId', + tagId: 'native-placement' + }, + ...nativeBidRequestParams, + nativeOrtbRequest: { + ver: '1.2', + assets: [ + {id: 1, required: 1, title: {len: 150}}, + {id: 2, required: 1, img: {type: 3, w: 300, h: 250}} + ] + }, + bidId: utils.generateUUID(), + auctionId: utils.generateUUID(), + }; - const request = spec.buildRequests([nativeBidRequest], commonBidderRequest); + const request = spec.buildRequests([nativeBidRequest], commonBidderRequest); - const nativeAdm = { - ver: '1.2', - assets: [ - {id: 1, title: {text: 'Native Ad Title'}}, - {id: 2, img: {url: 'https://example.com/image.jpg', w: 300, h: 250}} - ], - link: { - url: 'https://example.com/click' - } - }; - - const serverResponse = { - body: { - id: 'response-id', - seatbid: [{ - bid: [{ - id: 'bid-id', - impid: request.data.imp[0].id, - price: 1.5, - adm: JSON.stringify(nativeAdm), - adomain: ['example.com'], - crid: 'creative-id', - exp: 300, - nurl: 'https://example.com/win' + const nativeAdm = { + ver: '1.2', + assets: [ + {id: 1, title: {text: 'Native Ad Title'}}, + {id: 2, img: {url: 'https://example.com/image.jpg', w: 300, h: 250}} + ], + link: { + url: 'https://example.com/click' + } + }; + + const serverResponse = { + body: { + id: 'response-id', + seatbid: [{ + bid: [{ + id: 'bid-id', + impid: request.data.imp[0].id, + price: 1.5, + adm: JSON.stringify(nativeAdm), + adomain: ['example.com'], + crid: 'creative-id', + exp: 300, + nurl: 'https://example.com/win' + }], + seat: 'taboola' }], - seat: 'taboola' - }], - cur: 'USD' - } - }; + cur: 'USD' + } + }; - const res = spec.interpretResponse(serverResponse, request); + const res = spec.interpretResponse(serverResponse, request); - expect(res).to.be.an('array').with.lengthOf(1); - expect(res[0].mediaType).to.equal('native'); - expect(res[0].native).to.exist; - expect(res[0].native.ortb).to.deep.equal(nativeAdm); - expect(res[0]).to.not.have.property('ad'); - }); + expect(res).to.be.an('array').with.lengthOf(1); + expect(res[0].mediaType).to.equal('native'); + expect(res[0].native).to.exist; + expect(res[0].native.ortb).to.deep.equal(nativeAdm); + expect(res[0]).to.not.have.property('ad'); + }); + } }); }); }) From 3f7d7aeb4d1abf7c6a95f8b4f8b8cb58c37b0d13 Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Wed, 14 Jan 2026 15:57:32 +0200 Subject: [PATCH 5/7] updated media type checks --- modules/taboolaBidAdapter.js | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index d6da9f3fc50..d76b366c5e7 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -183,9 +183,8 @@ const converter = ortbConverter({ return reqData; }, bidResponse(buildBidResponse, bid, context) { - const hasNative = !!context.bidRequest?.mediaTypes?.native; - const hasBanner = !!context.bidRequest?.mediaTypes?.banner; - context.mediaType = hasNative && !hasBanner ? NATIVE : BANNER; + const { mediaType } = getMediaType(context.bidRequest); + context.mediaType = mediaType; if (context.mediaType === NATIVE) { const admObj = safeJSONParse(bid.adm); @@ -220,8 +219,7 @@ export const spec = { if (!hasPublisherAndTag) { return false; } - const hasBanner = !!bidRequest.mediaTypes?.banner; - const hasNative = !!bidRequest.mediaTypes?.native; + const { hasBanner, hasNative } = getMediaType(bidRequest); return hasBanner || hasNative; }, buildRequests: (validBidRequests, bidderRequest) => { @@ -233,8 +231,8 @@ export const spec = { context: { auctionId } }); const {publisherId} = bidRequest.params; - const isNative = !!bidRequest.mediaTypes?.native; - const baseUrl = isNative ? NATIVE_ENDPOINT_URL : BANNER_ENDPOINT_URL; + const { mediaType } = getMediaType(bidRequest); + const baseUrl = mediaType === NATIVE ? NATIVE_ENDPOINT_URL : BANNER_ENDPOINT_URL; const url = baseUrl + '?publisher=' + publisherId; return { @@ -453,15 +451,16 @@ function fillTaboolaReqData(bidderRequest, bidRequest, data, context) { function fillTaboolaImpData(bid, imp) { const {tagId, position} = bid.params; - const bannerSizes = bid.mediaTypes?.banner?.sizes; - if (bannerSizes) { - imp.banner = getBanners(bannerSizes, position); + const { mediaType, hasBanner } = getMediaType(bid); + if (hasBanner) { + imp.banner = getBanners(bid.mediaTypes.banner.sizes, position); } - imp.tagid = tagId; + imp.tagid = tagId; if (typeof bid.getFloor === 'function') { const floorInfo = bid.getFloor({ currency: CURRENCY, + mediaType: mediaType, size: '*' }); if (isPlainObject(floorInfo) && floorInfo.currency === CURRENCY && !isNaN(parseFloat(floorInfo.floor))) { @@ -517,4 +516,14 @@ function getSizes(sizes) { } } +function getMediaType(bidRequest) { + const hasBanner = !!bidRequest?.mediaTypes?.banner?.sizes; + const hasNative = !!bidRequest?.mediaTypes?.native; + return { + hasBanner, + hasNative, + mediaType: hasNative && !hasBanner ? NATIVE : BANNER + }; +} + registerBidder(spec); From 15ad62f187fdb72d5d2494c104e28431f1d9279f Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Wed, 14 Jan 2026 16:08:24 +0200 Subject: [PATCH 6/7] added missing tab --- .github/workflows/jscpd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jscpd.yml b/.github/workflows/jscpd.yml index c3021b2ced7..774493a7d04 100644 --- a/.github/workflows/jscpd.yml +++ b/.github/workflows/jscpd.yml @@ -36,7 +36,7 @@ jobs: ], "output": "./", "pattern": "**/*.js", - "ignore": ["**/*spec.js"] + "ignore": ["**/*spec.js"] }' > .jscpd.json - name: Run jscpd on entire codebase From 4cad25d142d6b7e4d51be82335b31a180ad24189 Mon Sep 17 00:00:00 2001 From: Roni Shefi Date: Mon, 2 Feb 2026 15:40:17 +0200 Subject: [PATCH 7/7] removed tab --- .github/workflows/jscpd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jscpd.yml b/.github/workflows/jscpd.yml index 774493a7d04..c3021b2ced7 100644 --- a/.github/workflows/jscpd.yml +++ b/.github/workflows/jscpd.yml @@ -36,7 +36,7 @@ jobs: ], "output": "./", "pattern": "**/*.js", - "ignore": ["**/*spec.js"] + "ignore": ["**/*spec.js"] }' > .jscpd.json - name: Run jscpd on entire codebase