Skip to content

Commit 8f706e6

Browse files
authored
TW-1442: Add API for sites blacklist for replacing ads (#156)
* TW-1442 Add API for sites blacklist for replacing ads * TW-1442 Change response types for URLs blacklist
1 parent 6923fb0 commit 8f706e6

File tree

10 files changed

+294
-47
lines changed

10 files changed

+294
-47
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"@types/express": "^4.17.17",
5454
"@types/express-jwt": "^7.4.2",
5555
"@types/express-unless": "^2.0.1",
56+
"@types/lodash": "^4.17.0",
5657
"@types/memoizee": "^0.4.5",
5758
"@types/node": "^18.14.6",
5859
"@types/pino": "^6.3.8",

src/advertising/external-ads.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ interface AdStylesOverrides {
8484
style: Record<StylePropName, string>;
8585
}
8686

87-
interface ExtVersionConstraints {
87+
export interface ExtVersionConstraints {
8888
extVersion: string;
8989
}
9090

@@ -138,12 +138,17 @@ export interface AdProviderForAllSitesRule extends ExtVersionConstraints {
138138
providers: string[];
139139
}
140140

141+
export interface ReplaceAdsUrlsBlacklistEntry extends ExtVersionConstraints {
142+
regexes: string[];
143+
}
144+
141145
const AD_PLACES_RULES_KEY = 'ad_places_rules';
142146
const AD_PROVIDERS_BY_SITES_KEY = 'ad_providers_by_sites';
143147
const AD_PROVIDERS_ALL_SITES_KEY = 'ad_providers_all_sites';
144148
const AD_PROVIDERS_LIST_KEY = 'ad_providers_list';
145149
const PERMANENT_AD_PLACES_RULES_KEY = 'permanent_ad_places_rules';
146150
const PERMANENT_NATIVE_AD_PLACES_RULES_KEY = 'permanent_native_ad_places_rules';
151+
const REPLACE_ADS_URLS_BLACKLIST_KEY = 'replace_ads_urls_blacklist';
147152

148153
export const adPlacesRulesMethods = objectStorageMethodsFactory<AdPlacesRule[]>(AD_PLACES_RULES_KEY, []);
149154

@@ -164,6 +169,11 @@ export const permanentNativeAdPlacesMethods = objectStorageMethodsFactory<Perman
164169
[]
165170
);
166171

172+
export const replaceAdsUrlsBlacklistMethods = objectStorageMethodsFactory<ReplaceAdsUrlsBlacklistEntry[]>(
173+
REPLACE_ADS_URLS_BLACKLIST_KEY,
174+
[]
175+
);
176+
167177
export const getAdProvidersForAllSites = async () => redisClient.smembers(AD_PROVIDERS_ALL_SITES_KEY);
168178

169179
export const addAdProvidersForAllSites = async (providers: string[]) =>

src/routers/slise-ad-rules/ad-places.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
1-
import { Router } from 'express';
1+
import { Request, Router } from 'express';
22

33
import {
44
filterByVersion,
55
permanentNativeAdPlacesMethods,
66
permanentAdPlacesMethods,
7-
adPlacesRulesMethods
7+
adPlacesRulesMethods,
8+
PermanentAdPlacesRule,
9+
AdPlacesRule,
10+
ExtVersionConstraints
811
} from '../../advertising/external-ads';
912
import { addObjectStorageMethodsToRouter } from '../../utils/express-helpers';
13+
import { transformValues } from '../../utils/helpers';
1014
import {
1115
hostnamesListSchema,
1216
permanentAdPlacesRulesDictionarySchema,
1317
adPlacesRulesDictionarySchema
1418
} from '../../utils/schemas';
1519

20+
const transformAdPlaces = <T extends ExtVersionConstraints>(value: T[], req: Request) =>
21+
filterByVersion(value, req.query.extVersion as string | undefined);
22+
const transformAdPlacesDictionary = <T extends ExtVersionConstraints>(rules: Record<string, T[]>, req: Request) =>
23+
transformValues(rules, value => transformAdPlaces(value, req));
24+
1625
/**
1726
* @swagger
1827
* tags:
@@ -68,13 +77,14 @@ import {
6877
* type: string
6978
* ExtVersionConstraints:
7079
* type: object
80+
* required:
81+
* - extVersion
7182
* properties:
7283
* extVersion:
7384
* type: string
7485
* description: >
7586
* A range of versions where the rule is applicable. If not specified, the rule is applicable
7687
* for all versions. See the [ranges format](https://www.npmjs.com/package/semver#ranges)
77-
* default: '*'
7888
* AdPlacesRule:
7989
* allOf:
8090
* - $ref: '#/components/schemas/ExtVersionConstraints'
@@ -420,14 +430,15 @@ export const adPlacesRulesRouter = Router();
420430
* '500':
421431
* $ref: '#/components/responses/ErrorResponse'
422432
*/
423-
addObjectStorageMethodsToRouter(adPlacesRulesRouter, {
433+
addObjectStorageMethodsToRouter<PermanentAdPlacesRule[]>(adPlacesRulesRouter, {
424434
path: '/permanent-native',
425435
methods: permanentNativeAdPlacesMethods,
426436
keyName: 'domain',
427437
objectValidationSchema: permanentAdPlacesRulesDictionarySchema,
428438
keysArrayValidationSchema: hostnamesListSchema,
429439
successfulRemovalMessage: entriesCount => `${entriesCount} entries have been removed`,
430-
transformGotValueFn: (value, req) => filterByVersion(value, req.query.extVersion as string | undefined)
440+
valueTransformFn: transformAdPlaces,
441+
objectTransformFn: transformAdPlacesDictionary
431442
});
432443

433444
/**
@@ -569,14 +580,15 @@ addObjectStorageMethodsToRouter(adPlacesRulesRouter, {
569580
* '500':
570581
* $ref: '#/components/responses/ErrorResponse'
571582
*/
572-
addObjectStorageMethodsToRouter(adPlacesRulesRouter, {
583+
addObjectStorageMethodsToRouter<PermanentAdPlacesRule[]>(adPlacesRulesRouter, {
573584
path: '/permanent',
574585
methods: permanentAdPlacesMethods,
575586
keyName: 'domain',
576587
objectValidationSchema: permanentAdPlacesRulesDictionarySchema,
577588
keysArrayValidationSchema: hostnamesListSchema,
578589
successfulRemovalMessage: entriesCount => `${entriesCount} entries have been removed`,
579-
transformGotValueFn: (value, req) => filterByVersion(value, req.query.extVersion as string | undefined)
590+
valueTransformFn: transformAdPlaces,
591+
objectTransformFn: transformAdPlacesDictionary
580592
});
581593

582594
/**
@@ -718,12 +730,13 @@ addObjectStorageMethodsToRouter(adPlacesRulesRouter, {
718730
* '500':
719731
* $ref: '#/components/responses/ErrorResponse'
720732
*/
721-
addObjectStorageMethodsToRouter(adPlacesRulesRouter, {
733+
addObjectStorageMethodsToRouter<AdPlacesRule[]>(adPlacesRulesRouter, {
722734
path: '/',
723735
methods: adPlacesRulesMethods,
724736
keyName: 'domain',
725737
objectValidationSchema: adPlacesRulesDictionarySchema,
726738
keysArrayValidationSchema: hostnamesListSchema,
727739
successfulRemovalMessage: entriesCount => `${entriesCount} entries have been removed`,
728-
transformGotValueFn: (value, req) => filterByVersion(value, req.query.extVersion as string | undefined)
740+
valueTransformFn: transformAdPlaces,
741+
objectTransformFn: transformAdPlacesDictionary
729742
});

src/routers/slise-ad-rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Router } from 'express';
22

33
import { adPlacesRulesRouter } from './ad-places';
44
import { adProvidersRouter } from './providers';
5+
import { replaceUrlsBlacklistRouter } from './replace-urls-blacklist';
56

67
/**
78
* @swagger
@@ -41,3 +42,4 @@ export const adRulesRouter = Router();
4142

4243
adRulesRouter.use('/ad-places', adPlacesRulesRouter);
4344
adRulesRouter.use('/providers', adProvidersRouter);
45+
adRulesRouter.use('/replace-urls-blacklist', replaceUrlsBlacklistRouter);

src/routers/slise-ad-rules/providers.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Router } from 'express';
1+
import { Request, Router } from 'express';
2+
import { identity } from 'lodash';
23

34
import {
45
addAdProvidersForAllSites,
@@ -7,12 +8,14 @@ import {
78
adProvidersMethods,
89
adProvidersByDomainRulesMethods,
910
AdProviderSelectorsRule,
10-
filterByVersion
11+
filterByVersion,
12+
AdProvidersByDomainRule
1113
} from '../../advertising/external-ads';
1214
import { basicAuth } from '../../middlewares/basic-auth.middleware';
1315
import { addObjectStorageMethodsToRouter, withBodyValidation, withExceptionHandler } from '../../utils/express-helpers';
16+
import { transformValues } from '../../utils/helpers';
1417
import {
15-
adTypesListSchema,
18+
nonEmptyStringsListSchema,
1619
hostnamesListSchema,
1720
adProvidersByDomainsRulesDictionarySchema,
1821
adProvidersDictionarySchema
@@ -178,7 +181,7 @@ adProvidersRouter
178181
.post(
179182
basicAuth,
180183
withExceptionHandler(
181-
withBodyValidation(adTypesListSchema, async (req, res) => {
184+
withBodyValidation(nonEmptyStringsListSchema, async (req, res) => {
182185
const providersAddedCount = await addAdProvidersForAllSites(req.body);
183186

184187
res.status(200).send({ message: `${providersAddedCount} providers have been added` });
@@ -188,7 +191,7 @@ adProvidersRouter
188191
.delete(
189192
basicAuth,
190193
withExceptionHandler(
191-
withBodyValidation(adTypesListSchema, async (req, res) => {
194+
withBodyValidation(nonEmptyStringsListSchema, async (req, res) => {
192195
const providersRemovedCount = await removeAdProvidersForAllSites(req.body);
193196

194197
res.status(200).send({ message: `${providersRemovedCount} providers have been removed` });
@@ -287,13 +290,15 @@ adProvidersRouter
287290
* '500':
288291
* $ref: '#/components/responses/ErrorResponse'
289292
*/
290-
addObjectStorageMethodsToRouter(adProvidersRouter, {
293+
addObjectStorageMethodsToRouter<AdProvidersByDomainRule[]>(adProvidersRouter, {
291294
path: '/by-sites',
292295
methods: adProvidersByDomainRulesMethods,
293296
keyName: 'domain',
294297
objectValidationSchema: adProvidersByDomainsRulesDictionarySchema,
295298
keysArrayValidationSchema: hostnamesListSchema,
296-
successfulRemovalMessage: entriesCount => `${entriesCount} entries have been removed`
299+
successfulRemovalMessage: entriesCount => `${entriesCount} entries have been removed`,
300+
valueTransformFn: identity,
301+
objectTransformFn: identity
297302
});
298303

299304
/**
@@ -437,19 +442,22 @@ addObjectStorageMethodsToRouter(adProvidersRouter, {
437442
* '500':
438443
* $ref: '#/components/responses/ErrorResponse'
439444
*/
440-
addObjectStorageMethodsToRouter<AdProviderSelectorsRule[], string[]>(adProvidersRouter, {
445+
const transformAdProviderSelectorsRules = (rules: AdProviderSelectorsRule[], req: Request) =>
446+
Array.from(
447+
new Set(
448+
filterByVersion(rules, req.query.extVersion as string | undefined)
449+
.map(({ selectors }) => selectors)
450+
.flat()
451+
)
452+
);
453+
454+
addObjectStorageMethodsToRouter<AdProviderSelectorsRule[], Record<string, string[]>, string[]>(adProvidersRouter, {
441455
path: '/',
442456
methods: adProvidersMethods,
443457
keyName: 'providerId',
444458
objectValidationSchema: adProvidersDictionarySchema,
445-
keysArrayValidationSchema: adTypesListSchema,
459+
keysArrayValidationSchema: nonEmptyStringsListSchema,
446460
successfulRemovalMessage: entriesCount => `${entriesCount} providers have been removed`,
447-
transformGotValueFn: (rules, req) =>
448-
Array.from(
449-
new Set(
450-
filterByVersion(rules, req.query.extVersion as string | undefined)
451-
.map(({ selectors }) => selectors)
452-
.flat()
453-
)
454-
)
461+
valueTransformFn: transformAdProviderSelectorsRules,
462+
objectTransformFn: (rules, req) => transformValues(rules, value => transformAdProviderSelectorsRules(value, req))
455463
});

0 commit comments

Comments
 (0)