Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature tags #1

Closed
wants to merge 3 commits into from
Closed
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
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ module.exports = {
globals: {
'$$PREBID_GLOBAL$$': false,
'BROWSERSTACK_USERNAME': false,
'BROWSERSTACK_KEY': false
'BROWSERSTACK_KEY': false,
'FEATURES': 'readonly',
},
// use babel as parser for fancy syntax
parser: '@babel/eslint-parser',
Expand Down
10 changes: 7 additions & 3 deletions babelConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ function useLocal(module) {
})
}

module.exports = function (test = false) {
module.exports = function (options = {}) {
const {globalVarName, disableFeatures} = options;
return {
'presets': [
[
Expand All @@ -18,12 +19,15 @@ module.exports = function (test = false) {
'useBuiltIns': 'entry',
'corejs': '3.13.0',
// a lot of tests use sinon.stub & others that stopped working on ES6 modules with webpack 5
'modules': test ? 'commonjs' : 'auto',
'modules': options.test ? 'commonjs' : 'auto',
}
]
],
'plugins': [
path.resolve(__dirname, './plugins/pbjsGlobals.js'),
[
path.resolve(__dirname, './plugins/pbjsGlobals.js'),
{globalVarName, disableFeatures}
],
useLocal('babel-plugin-transform-object-assign'),
],
}
Expand Down
3 changes: 3 additions & 0 deletions features.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"NATIVE"
]
8 changes: 7 additions & 1 deletion gulpHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,11 @@ module.exports = {
}

return options;
}
},
getDisabledFeatures() {
return (argv.disable || '')
.split(',')
.map((s) => s.trim())
.filter((s) => s);
},
};
52 changes: 38 additions & 14 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var port = 9999;
const FAKE_SERVER_HOST = argv.host ? argv.host : 'localhost';
const FAKE_SERVER_PORT = 4444;
const { spawn } = require('child_process');
const TerserPlugin = require('terser-webpack-plugin');

// these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules
var explicitModules = [
Expand Down Expand Up @@ -132,20 +133,22 @@ function makeDevpackPkg() {
.pipe(connect.reload());
}

function makeWebpackPkg() {
var cloned = _.cloneDeep(webpackConfig);
function makeWebpackPkg(extraConfig = {}) {
var cloned = _.merge(_.cloneDeep(webpackConfig), (extraConfig || {}));
delete cloned.devtool;

var externalModules = helpers.getArgModules();
return function buildBundle() {
var externalModules = helpers.getArgModules();

const analyticsSources = helpers.getAnalyticsSources();
const moduleSources = helpers.getModulePaths(externalModules);
const analyticsSources = helpers.getAnalyticsSources();
const moduleSources = helpers.getModulePaths(externalModules);

return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
.pipe(helpers.nameModules(externalModules))
.pipe(webpackStream(cloned, webpack))
.pipe(gulpif(file => file.basename === 'prebid-core.js', header(banner, { prebid: prebid })))
.pipe(gulp.dest('build/dist'));
return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
.pipe(helpers.nameModules(externalModules))
.pipe(webpackStream(cloned, webpack))
.pipe(gulpif(file => file.basename === 'prebid-core.js', header(banner, {prebid: prebid})))
.pipe(gulp.dest('build/dist'));
}
}

function getModulesListToAddInBanner(modules) {
Expand Down Expand Up @@ -227,6 +230,8 @@ function testTaskMaker(options = {}) {
options[opt] = options[opt] || argv[opt];
})

options.disableFeatures = options.disableFeatures || helpers.getDisabledFeatures();

return function test(done) {
if (options.notest) {
done();
Expand Down Expand Up @@ -270,7 +275,7 @@ function testTaskMaker(options = {}) {
process.exit(1);
});
} else {
var karmaConf = karmaConfMaker(false, options.browserstack, options.watch, options.file);
var karmaConf = karmaConfMaker(false, options.browserstack, options.watch, options.file, options.disableFeatures);

var browserOverride = helpers.parseBrowserArgs(argv);
if (browserOverride.length > 0) {
Expand Down Expand Up @@ -398,11 +403,30 @@ gulp.task(clean);
gulp.task(escapePostbidConfig);

gulp.task('build-bundle-dev', gulp.series(makeDevpackPkg, gulpBundle.bind(null, true)));
gulp.task('build-bundle-prod', gulp.series(makeWebpackPkg, gulpBundle.bind(null, false)));
gulp.task('build-bundle-prod', gulp.series(makeWebpackPkg(), gulpBundle.bind(null, false)));
// build-bundle-verbose - prod bundle except names and comments are preserved. Use this to see the effects
// of dead code elimination.
gulp.task('build-bundle-verbose', gulp.series(makeWebpackPkg({
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
mangle: false,
format: {
comments: 'all'
}
},
extractComments: false,
}),
],
}
})), gulpBundle.bind(null, false))

// public tasks (dependencies are needed for each task since they can be ran on their own)
gulp.task('test-only', test);
gulp.task('test', gulp.series(clean, lint, 'test-only'));
gulp.task('test-all-features-disabled', testTaskMaker({browserstack: false, disableFeatures: require('./features.json')}))
gulp.task('test', gulp.series(clean, lint, 'test-all-features-disabled', 'test-only'));

gulp.task('test-coverage', gulp.series(clean, testCoverage));
gulp.task(viewCoverage);
Expand All @@ -417,7 +441,7 @@ gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', wat
gulp.task('serve-and-test', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast, testTaskMaker({watch: true}))));
gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer));

gulp.task('default', gulp.series(clean, makeWebpackPkg));
gulp.task('default', gulp.series(clean, makeWebpackPkg()));

gulp.task('e2e-test', gulp.series(clean, setupE2e, gulp.parallel('build-bundle-prod', watch), injectFakeServerEndpoint, test));
// other tasks
Expand Down
8 changes: 4 additions & 4 deletions karma.conf.maker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var _ = require('lodash');
var webpackConf = require('./webpack.conf.js');
var karmaConstants = require('karma').constants;

function newWebpackConfig(codeCoverage) {
function newWebpackConfig(codeCoverage, disableFeatures) {
// Make a clone here because we plan on mutating this object, and don't want parallel tasks to trample each other.
var webpackConfig = _.cloneDeep(webpackConf);

Expand All @@ -22,7 +22,7 @@ function newWebpackConfig(codeCoverage) {
.flatMap((r) => r.use)
.filter((use) => use.loader === 'babel-loader')
.forEach((use) => {
use.options = babelConfig(true);
use.options = babelConfig({test: true, disableFeatures: disableFeatures});
});

if (codeCoverage) {
Expand Down Expand Up @@ -117,8 +117,8 @@ function setBrowsers(karmaConf, browserstack) {
}
}

module.exports = function(codeCoverage, browserstack, watchMode, file) {
var webpackConfig = newWebpackConfig(codeCoverage);
module.exports = function(codeCoverage, browserstack, watchMode, file, disableFeatures) {
var webpackConfig = newWebpackConfig(codeCoverage, disableFeatures);
var plugins = newPluginsArray(browserstack);

var files = file ? ['test/test_deps.js', file] : ['test/test_index.js'];
Expand Down
149 changes: 76 additions & 73 deletions modules/prebidServerBidAdapter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,18 +417,19 @@ let nativeEventTrackerMethodMap = {
js: 2
};

// enable reverse lookup
[
nativeDataIdMap,
nativeImgIdMap,
nativeEventTrackerEventMap,
nativeEventTrackerMethodMap
].forEach(map => {
Object.keys(map).forEach(key => {
map[map[key]] = key;
if (FEATURES.NATIVE) {
// enable reverse lookup
[
nativeDataIdMap,
nativeImgIdMap,
nativeEventTrackerEventMap,
nativeEventTrackerMethodMap
].forEach(map => {
Object.keys(map).forEach(key => {
map[map[key]] = key;
});
});
});

}
/*
* Protocol spec for OpenRTB endpoint
* e.g., https://<prebid-server-url>/v1/openrtb2/auction
Expand Down Expand Up @@ -510,74 +511,76 @@ const OPEN_RTB_PROTOCOL = {
impressionId = `${adUnit.code}-${i}`;
}
impIds.add(impressionId);

const nativeParams = processNativeAdUnitParams(deepAccess(adUnit, 'mediaTypes.native'));
let nativeAssets;
if (nativeParams) {
try {
nativeAssets = nativeAssetCache[impressionId] = Object.keys(nativeParams).reduce((assets, type) => {
let params = nativeParams[type];

function newAsset(obj) {
return Object.assign({
required: params.required ? 1 : 0
}, obj ? cleanObj(obj) : {});
}
if (FEATURES.NATIVE) {
const nativeParams = processNativeAdUnitParams(deepAccess(adUnit, 'mediaTypes.native'));
if (nativeParams) {
try {
nativeAssets = nativeAssetCache[impressionId] = Object.keys(nativeParams).reduce((assets, type) => {
let params = nativeParams[type];

function newAsset(obj) {
return Object.assign({
required: params.required ? 1 : 0
}, obj ? cleanObj(obj) : {});
}

switch (type) {
case 'image':
case 'icon':
let imgTypeId = nativeImgIdMap[type];
let asset = cleanObj({
type: imgTypeId,
w: deepAccess(params, 'sizes.0'),
h: deepAccess(params, 'sizes.1'),
wmin: deepAccess(params, 'aspect_ratios.0.min_width'),
hmin: deepAccess(params, 'aspect_ratios.0.min_height')
});
if (!((asset.w && asset.h) || (asset.hmin && asset.wmin))) {
throw 'invalid img sizes (must provide sizes or min_height & min_width if using aspect_ratios)';
}
if (Array.isArray(params.aspect_ratios)) {
// pass aspect_ratios as ext data I guess?
const aspectRatios = params.aspect_ratios
.filter((ar) => ar.ratio_width && ar.ratio_height)
.map(ratio => `${ratio.ratio_width}:${ratio.ratio_height}`);
if (aspectRatios.length > 0) {
asset.ext = {
aspectratios: aspectRatios
switch (type) {
case 'image':
case 'icon':
let imgTypeId = nativeImgIdMap[type];
let asset = cleanObj({
type: imgTypeId,
w: deepAccess(params, 'sizes.0'),
h: deepAccess(params, 'sizes.1'),
wmin: deepAccess(params, 'aspect_ratios.0.min_width'),
hmin: deepAccess(params, 'aspect_ratios.0.min_height')
});
if (!((asset.w && asset.h) || (asset.hmin && asset.wmin))) {
throw 'invalid img sizes (must provide sizes or min_height & min_width if using aspect_ratios)';
}
if (Array.isArray(params.aspect_ratios)) {
// pass aspect_ratios as ext data I guess?
const aspectRatios = params.aspect_ratios
.filter((ar) => ar.ratio_width && ar.ratio_height)
.map(ratio => `${ratio.ratio_width}:${ratio.ratio_height}`);
if (aspectRatios.length > 0) {
asset.ext = {
aspectratios: aspectRatios
}
}
}
}
assets.push(newAsset({
img: asset
}));
break;
case 'title':
if (!params.len) {
throw 'invalid title.len';
}
assets.push(newAsset({
title: {
len: params.len
assets.push(newAsset({
img: asset
}));
break;
case 'title':
if (!params.len) {
throw 'invalid title.len';
}
}));
break;
default:
let dataAssetTypeId = nativeDataIdMap[type];
if (dataAssetTypeId) {
assets.push(newAsset({
data: {
type: dataAssetTypeId,
title: {
len: params.len
}
}))
}
}
return assets;
}, []);
} catch (e) {
logError('error creating native request: ' + String(e))
}));
break;
default:
let dataAssetTypeId = nativeDataIdMap[type];
if (dataAssetTypeId) {
assets.push(newAsset({
data: {
type: dataAssetTypeId,
len: params.len
}
}))
}
}
return assets;
}, []);
} catch (e) {
logError('error creating native request: ' + String(e))
}
}
}
const videoParams = deepAccess(adUnit, 'mediaTypes.video');
Expand Down Expand Up @@ -637,7 +640,7 @@ const OPEN_RTB_PROTOCOL = {
}
}

if (nativeAssets) {
if (FEATURES.NATIVE && nativeAssets) {
try {
mediaTypes['native'] = {
request: JSON.stringify({
Expand Down Expand Up @@ -938,7 +941,7 @@ const OPEN_RTB_PROTOCOL = {

if (bid.adm) { bidObject.vastXml = bid.adm; }
if (!bidObject.vastUrl && bid.nurl) { bidObject.vastUrl = bid.nurl; }
} else if (deepAccess(bid, 'ext.prebid.type') === NATIVE) {
} else if (FEATURES.NATIVE && deepAccess(bid, 'ext.prebid.type') === NATIVE) {
bidObject.mediaType = NATIVE;
let adm;
if (typeof bid.adm === 'string') {
Expand Down Expand Up @@ -1081,7 +1084,7 @@ export function PrebidServer() {

// at this point ad units should have a size array either directly or mapped so filter for that
const validAdUnits = adUnits.filter(unit =>
unit.mediaTypes && (unit.mediaTypes.native || (unit.mediaTypes.banner && unit.mediaTypes.banner.sizes) || (unit.mediaTypes.video && unit.mediaTypes.video.playerSize))
unit.mediaTypes && ((FEATURES.NATIVE && unit.mediaTypes.native) || (unit.mediaTypes.banner && unit.mediaTypes.banner.sizes) || (unit.mediaTypes.video && unit.mediaTypes.video.playerSize))
);

// in case config.bidders contains invalid bidders, we only process those we sent requests for
Expand Down
Loading