|
| 1 | +import { redisClient } from '../redis'; |
| 2 | +import { isDefined } from '../utils/helpers'; |
| 3 | + |
| 4 | +/** Style properties names that are likely to be unnecessary for banners are skipped */ |
| 5 | +export const stylePropsNames = [ |
| 6 | + 'align-content', |
| 7 | + 'align-items', |
| 8 | + 'align-self', |
| 9 | + 'alignment-baseline', |
| 10 | + 'aspect-ratio', |
| 11 | + 'background', |
| 12 | + 'border-radius', |
| 13 | + 'bottom', |
| 14 | + 'box-shadow', |
| 15 | + 'box-sizing', |
| 16 | + 'display', |
| 17 | + 'flex', |
| 18 | + 'flex-basis', |
| 19 | + 'flex-direction', |
| 20 | + 'flex-flow', |
| 21 | + 'flex-grow', |
| 22 | + 'flex-shrink', |
| 23 | + 'flex-wrap', |
| 24 | + 'float', |
| 25 | + 'height', |
| 26 | + 'justify-content', |
| 27 | + 'justify-items', |
| 28 | + 'justify-self', |
| 29 | + 'left', |
| 30 | + 'margin', |
| 31 | + 'margin-block', |
| 32 | + 'margin-block-end', |
| 33 | + 'margin-block-start', |
| 34 | + 'margin-bottom', |
| 35 | + 'margin-inline', |
| 36 | + 'margin-inline-end', |
| 37 | + 'margin-inline-start', |
| 38 | + 'margin-left', |
| 39 | + 'margin-right', |
| 40 | + 'margin-top', |
| 41 | + 'max-block-size', |
| 42 | + 'max-height', |
| 43 | + 'max-inline-size', |
| 44 | + 'max-width', |
| 45 | + 'min-block-size', |
| 46 | + 'min-height', |
| 47 | + 'min-inline-size', |
| 48 | + 'min-width', |
| 49 | + 'opacity', |
| 50 | + 'overflow', |
| 51 | + 'overflow-anchor', |
| 52 | + 'overflow-wrap', |
| 53 | + 'overflow-x', |
| 54 | + 'overflow-y', |
| 55 | + 'padding', |
| 56 | + 'padding-block', |
| 57 | + 'padding-block-end', |
| 58 | + 'padding-block-start', |
| 59 | + 'padding-bottom', |
| 60 | + 'padding-inline', |
| 61 | + 'padding-inline-end', |
| 62 | + 'padding-inline-start', |
| 63 | + 'padding-left', |
| 64 | + 'padding-right', |
| 65 | + 'padding-top', |
| 66 | + 'position', |
| 67 | + 'right', |
| 68 | + 'text-align', |
| 69 | + 'top', |
| 70 | + 'visibility', |
| 71 | + 'width', |
| 72 | + 'z-index' |
| 73 | +]; |
| 74 | +export type StylePropName = (typeof stylePropsNames)[number]; |
| 75 | + |
| 76 | +interface SliseAdStylesOverrides { |
| 77 | + parentDepth: number; |
| 78 | + style: Record<StylePropName, string>; |
| 79 | +} |
| 80 | + |
| 81 | +export interface SliseAdPlacesRule { |
| 82 | + urlRegexes: string[]; |
| 83 | + selector: { |
| 84 | + isMultiple: boolean; |
| 85 | + cssString: string; |
| 86 | + parentDepth: number; |
| 87 | + shouldUseDivWrapper: boolean; |
| 88 | + divWrapperStyle?: Record<StylePropName, string>; |
| 89 | + }; |
| 90 | + stylesOverrides?: SliseAdStylesOverrides[]; |
| 91 | +} |
| 92 | + |
| 93 | +export interface SliseAdProvidersByDomainRule { |
| 94 | + urlRegexes: string[]; |
| 95 | + providers: string[]; |
| 96 | +} |
| 97 | + |
| 98 | +const SLISE_AD_PLACES_RULES_KEY = 'slise_ad_places_rules'; |
| 99 | +const SLISE_AD_PROVIDERS_BY_SITES_KEY = 'slise_ad_providers_by_sites'; |
| 100 | +const SLISE_AD_PROVIDERS_ALL_SITES_KEY = 'slise_ad_providers_all_sites'; |
| 101 | +const SLISE_AD_PROVIDERS_LIST_KEY = 'slise_ad_providers_list'; |
| 102 | + |
| 103 | +const objectStorageMethodsFactory = <V>(storageKey: string, fallbackValue: V) => ({ |
| 104 | + getByKey: async (key: string): Promise<V> => { |
| 105 | + const value = await redisClient.hget(storageKey, key); |
| 106 | + |
| 107 | + return isDefined(value) ? JSON.parse(value) : fallbackValue; |
| 108 | + }, |
| 109 | + getAllValues: async (): Promise<Record<string, V>> => { |
| 110 | + const values = await redisClient.hgetall(storageKey); |
| 111 | + |
| 112 | + const parsedValues: Record<string, V> = {}; |
| 113 | + for (const key in values) { |
| 114 | + parsedValues[key] = JSON.parse(values[key]); |
| 115 | + } |
| 116 | + |
| 117 | + return parsedValues; |
| 118 | + }, |
| 119 | + upsertValues: (newValues: Record<string, V>) => |
| 120 | + redisClient.hmset( |
| 121 | + storageKey, |
| 122 | + Object.fromEntries(Object.entries(newValues).map(([domain, value]) => [domain, JSON.stringify(value)])) |
| 123 | + ), |
| 124 | + removeValues: (keys: string[]) => redisClient.hdel(storageKey, ...keys) |
| 125 | +}); |
| 126 | + |
| 127 | +export const { |
| 128 | + getByKey: getSliseAdPlacesRulesByDomain, |
| 129 | + getAllValues: getAllSliseAdPlacesRules, |
| 130 | + upsertValues: upsertSliseAdPlacesRules, |
| 131 | + removeValues: removeSliseAdPlacesRules |
| 132 | +} = objectStorageMethodsFactory<SliseAdPlacesRule[]>(SLISE_AD_PLACES_RULES_KEY, []); |
| 133 | + |
| 134 | +export const { |
| 135 | + getByKey: getSliseAdProvidersByDomain, |
| 136 | + getAllValues: getAllSliseAdProvidersBySites, |
| 137 | + upsertValues: upsertSliseAdProvidersBySites, |
| 138 | + removeValues: removeSliseAdProvidersBySites |
| 139 | +} = objectStorageMethodsFactory<SliseAdProvidersByDomainRule[]>(SLISE_AD_PROVIDERS_BY_SITES_KEY, []); |
| 140 | + |
| 141 | +export const { |
| 142 | + getByKey: getSelectorsByProviderId, |
| 143 | + getAllValues: getAllProviders, |
| 144 | + upsertValues: upsertProviders, |
| 145 | + removeValues: removeProviders |
| 146 | +} = objectStorageMethodsFactory<string[]>(SLISE_AD_PROVIDERS_LIST_KEY, []); |
| 147 | + |
| 148 | +export const getSliseAdProvidersForAllSites = async () => redisClient.smembers(SLISE_AD_PROVIDERS_ALL_SITES_KEY); |
| 149 | + |
| 150 | +export const addSliseAdProvidersForAllSites = async (providers: string[]) => |
| 151 | + redisClient.sadd(SLISE_AD_PROVIDERS_ALL_SITES_KEY, ...providers); |
| 152 | + |
| 153 | +export const removeSliseAdProvidersForAllSites = async (providers: string[]) => |
| 154 | + redisClient.srem(SLISE_AD_PROVIDERS_ALL_SITES_KEY, ...providers); |
0 commit comments