const fs = require('fs').promises; const path = require('path'); const bulkInsert = require('../src/utils/bulk-insert'); const affiliates = [ // vixen { id: '_vixen', network: 'vixen', url: 'http://join.vixen.com/track/MTA0MS43OC44LjQyLjAuMC4wLjAuMA', comment: 'per signup', }, { id: 'blacked', channel: 'blacked', url: 'https://join.blacked.com/track/MTA0MS43OC4zLjMuMC4wLjAuMC4w', comment: 'per signup', }, { id: 'blackedraw', channel: 'blackedraw', url: 'https://join.blackedraw.com/track/MTA0MS43OC45LjI4LjAuMC4wLjAuMA', comment: 'per signup', }, { id: 'deeper', channel: 'deeper', url: 'https://join.deeper.com/track/MTA0MS43OC4xMS4zNC4wLjAuMC4wLjA', comment: 'per signup', }, { id: 'milfy', channel: 'milfy', url: 'https://join.milfy.com/track/MTA0MS43OC4xNS41MS4wLjAuMC4wLjA', comment: 'per signup', }, { id: 'slayed', channel: 'slayed', url: 'https://join.slayed.com/track/MTA0MS43OC4xNC4zOS4wLjAuMC4wLjA', comment: 'per signup', }, { id: 'tushy', channel: 'tushy', url: 'https://join.tushy.com/track/MTA0MS43OC43LjIwLjAuMC4wLjAuMA', comment: 'per signup', }, { id: 'tushyraw', channel: 'tushyraw', url: 'https://join.tushyraw.com/track/MTA0MS43OC4xMC4zMS4wLjAuMC4wLjA', comment: 'per signup', }, { id: 'vixen', channel: 'vixen', url: 'https://join.vixen.com/track/MTA0MS43OC44LjIzLjAuMC4wLjAuMA', comment: 'per signup', }, { id: 'wifey', channel: 'wifey', url: 'https://join.wifey.com/track/MTA0MS43OC4xOC41Ni4wLjAuMC4wLjA', comment: 'per signup', }, // mike adriano { id: 'allanal', channel: 'allanal', url: 'https://access.allanal.com/track/OTczLjEuNS41LjAuMC4wLjAuMA', comment: '50% rev share', }, { id: 'analonly', channel: 'analonly', url: 'https://access.analonly.com/track/OTczLjEuNi4xMC4wLjAuMC4wLjA', comment: '50% rev share', }, { id: 'dirtyauditions', channel: 'dirtyauditions', url: 'https://access.dirtyauditions.com/track/OTczLjEuNy4xNC4wLjAuMC4wLjA', comment: '50% rev share', }, { id: 'nympho', channel: 'nympho', url: 'https://access.nympho.com/track/OTczLjEuNC40LjAuMC4wLjAuMA', comment: '50% rev share', }, { id: 'swallowed', channel: 'swallowed', url: 'https://access.swallowed.com/track/OTczLjEuMS4xLjAuMC4wLjAuMA', comment: '50% rev share', }, { id: 'trueanal', channel: 'trueanal', url: 'https://access.trueanal.com/track/OTczLjEuMy4zLjAuMC4wLjAuMA', comment: '50% rev share', }, { id: 'evilangel', network: 'evilangel', url: 'https://www.g2fame.com/evilangel/go.php?pr=8&su=2&si=128&ad=277470&pa=index&ar=&buffer=', parameters: 'nats=OTczLjEuMy4zLjAuMC4wLjAuMA', comment: '50% rev share', }, // kelly madison / 8k { id: '_kellymadison', network: 'kellymadison', url: 'https://www2.kellymadison.com/track/MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', parameters: 'nats=MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', comment: 'pay per sign-up', }, { id: 'kellymadison', channel: 'kellymadison', url: 'https://www2.kellymadison.com/track/MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', parameters: 'nats=MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', comment: 'pay per sign-up', }, { id: 'teenfidelity', channel: 'teenfidelity', url: 'https://www2.teenfidelity.com/track/MTAxOTE0LjYuNS42LjAuNjAwNTA0OC4wLjAuMA', parameters: 'nats=MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', comment: 'pay per sign-up', }, { id: 'pornfidelity', channel: 'pornfidelity', url: 'https://www2.pornfidelity.com/track/MTAxOTE0LjYuMy4zLjAuNjAwNDk3MS4wLjAuMA', parameters: 'nats=MTAxOTE0LjYuMS4xLjAuNjAwNDgxMS4wLjAuMA', comment: 'pay per sign-up', }, { id: '5kporn', channel: '5kporn', url: 'https://www2.5kporn.com/track/NzgwLjEuMS4xLjAuMC4wLjAuMA', parameters: 'nats=NzgwLjEuMS4xLjAuMC4wLjAuMA', comment: 'pay per sign-up', }, { id: '5kteens', channel: '5kteens', url: 'https://www2.5kteens.com/track/NzgwLjEuMi4yLjAuMC4wLjAuMA', parameters: 'nats=NzgwLjEuMi4yLjAuMC4wLjAuMA', comment: 'pay per sign-up', }, { id: '8kmilfs', channel: '8kmilfs', url: 'https://www2.8kmilfs.com/track/NzgwLjEuNC40LjAuMC4wLjAuMA', parameters: 'nats=NzgwLjEuNC40LjAuMC4wLjAuMA', comment: 'pay per sign-up', }, { id: '8kteens', channel: '8kteens', url: 'https://www2.8kteens.com/track/NzgwLjEuNS41LjAuMC4wLjAuMA', parameters: 'nats=NzgwLjEuNS41LjAuMC4wLjAuMA', comment: 'pay per sign-up', }, // jules jordan { id: 'julesjordan', network: 'julesjordan', url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA', comment: 'pay per sign-up', }, { id: 'manuelferrara', channel: 'manuelferrara', url: 'https://enter.manuelferrara.com/track/Mzk3MS4yLjcuMTYuMC4wLjAuMC4w', comment: 'pay per sign-up', }, { id: 'theassfactory', channel: 'theassfactory', url: 'https://enter.theassfactory.com/track/Mzk3MS4yLjEuMS4wLjAuMC4wLjA', comment: 'pay per sign-up', }, { id: 'spermswallowers', channel: 'spermswallowers', url: 'https://enter.spermswallowers.com/track/Mzk3MS4yLjUuMTMuMC4wLjAuMC4w', comment: '$30 per signup', }, // etc { id: 'naughtyamerica', network: 'naughtyamerica', url: 'https://natour.naughtyamerica.com/track/MTIzODIxLjEwMDI1LjguOC4wLjEwNzU2MTcuMC4wLjA', parameters: 'nats=MTIzODIxLjEwMDI1LjguOC4wLjEwNzU2MTcuMC4wLjA', comment: 'pay per sign-up', }, { id: 'archangel', channel: 'archangel', url: 'https://join.archangelvideo.com/track/MzQ3LjEuMS4xLjAuMC4wLjAuMA', comment: 'revshare', }, { id: 'kink', network: 'kink', parameters: 't=eyJhZmZpbGlhdGUiOiJEZWJhdWNoZXJ5TGliIiwiY2FtcGFpZ24iOiJkZWZhdWx0IiwiYWdldmVyaWZpZWQiOiJ5In0', comment: '50%', }, { id: 'bang', network: 'bang', parameters: 'aff=eyJ3IjoiMTQ1ODYiLCJsIjoiMzE2NDYiLCJ0IjoiNDU4NjEifQ==', // supported comment: '$25 per signup', }, ]; const bannerTags = { // 21sextury '21sextury_300_250_anal': ['anal', 'blonde'], '21sextury_770_76_gina_gerson_dp': ['dp', 'anal', 'mfm', 'blonde'], '21sextury_770_76_veronica_leal_dp': ['dp', 'anal', 'mfm', 'blowjob', 'blonde'], '21sextreme_300_250_cum': ['facial', 'cum-in-mouth'], '21naturals_315_300': ['brunette', 'natural-boobs'], '21naturals_315_300_1': ['blonde', 'natural-boobs'], '21naturals_315_300_gina_gerson': ['sex', 'blonde', 'natural-boobs'], '21naturals_315_300_ginebra_bellucci': ['sex', 'brunette', 'natural-boobs'], '21naturals_315_300_lana_roy_anal': ['anal', 'brunette', 'natural-boobs'], '21naturals_770_76_alexis_crystal': ['blowjob', 'blonde'], '21naturals_970_90': ['sex', 'brunette'], // archangel archangel_970_90_kendra_lust: ['dp', 'anal', 'sex', 'interracial', 'black'], // dogfart wefuckblackgirls_728_90_loss: ['mfm', 'threesome', 'anal', 'black', 'interracial'], dfxtra_900_250_mfm: ['mfm', 'threesome', 'black', 'interracial'], dfxtra_900_250_gay_anal: ['gay', 'anal', 'black', 'interracial'], dfxtra_300_250_mfm: ['mfm', 'threesome', 'black', 'interracial'], dfxtra_300_250_gay_bj: ['gay', 'blowjob', 'black', 'interracial'], blacksonblondes_900_250_mfm: ['mfm', 'threesome', 'black', 'interracial'], blacksonblondes_900_250_mfm_hj: ['mfm', 'threesome', 'handjob', 'black', 'interracial'], blacksonblondes_300_250_mfm: ['mfm', 'threesome', 'black', 'interracial'], blacksonblondes_300_250_mff_april: ['mff', 'threesome', 'black', 'interracial'], blacksonblondes_300_250_mff_april2: ['mff', 'threesome', 'black', 'interracial'], // evilangel evilangel_728_90_adriana_chechik_gangbang: ['gangbang', 'airtight', 'dp', 'dvp', 'facial', 'brunette'], evilangel_728_90_kenzie_reeves_lexi_lore: ['anal', 'mff', 'blowjob', 'blonde'], evilangel_970_90_one_dollar: ['sex', 'mff'], // julesjordan julesjordan_728_90_jill_kassidy: ['sex', 'blowjob', 'black-cock', 'brunette'], julesjordan_728_90_angela_white: ['sex', 'black-cock', 'brunette'], julesjordan_728_90_adriana_chechik: ['anal', 'black-cock', 'brunette'], julesjordan_728_90_autumn_falls: ['sex', 'big-boobs', 'brunette'], julesjordan_728_90_gabbie_carter: ['sex', 'blowjob', 'facefucking', 'big-boobs', 'brunette'], manuelferrara_728_90_asses: ['big-butt'], // kink boundgangbangs_305_99_moretta_11975_animated: ['gangbang', 'mfm', 'bdsm', 'blonde'], boundgangbangs_305_99_moretta_11975: ['blowbang', 'blowjob', 'bdsm', 'blonde'], boundgangbangs_315_300_lou_charmelle_12402_animated: ['gangbang', 'airtight', 'dp', 'bdsm', 'bondage'], boundgangbangs_315_300_lou_charmelle_12402: ['gangbang', 'mfm', 'bdsm', 'bondage'], boundgangbangs_770_76_amy_brooke_11965_animated: ['gangbang', 'airtight', 'mfm', 'bdsm', 'bondage'], boundgangbangs_770_76_anissa_kate_19662: ['gangbang', 'airtight', 'bdsm', 'bondage'], boundgangbangs_970_90_sasha_swift_18815: ['gangbang', 'blowbang', 'dp', 'blowjob', 'facefucking', 'facial', 'bdsm'], boundgangbangs_970_90_skylar_price_12403_animated: ['gangbang', 'mfm', 'blowbang', 'blowjob', 'blonde', 'bdsm'], hardcoregangbang_300_250_kira_noir_44157: ['blowbang', 'black', 'bdsm'], hardcoregangbang_305_99_kira_noir: ['blowbang', 'black', 'bdsm'], hardcoregangbang_900_250_gloves_blonde: ['blowbang', 'blonde', 'bdsm'], hardcoregangbang_1000_100: ['gangbang', 'mfm', 'bdsm'], // mike adriano allanal_1323_270_24: ['anal', 'mff', 'threesome'], allanal_300_250_14: ['anal', 'mff', 'threesome'], allanal_300_250_15: ['anal', 'mff', 'threesome'], allanal_315_300_3: ['anal'], allanal_728_90_23: ['anal', 'mff', 'threesome'], allanal_970_170_11: ['anal', 'mff', 'threesome'], allanal_970_90_12: ['anal', 'mff', 'threesome'], analonly_1200_90_26: ['anal'], analonly_1323_270_10: ['anal', 'gaping'], analonly_300_250_9: ['anal'], analonly_315_300_17: ['anal', 'gaping'], analonly_728_90_25: ['anal', 'gaping'], analonly_914_424_13: ['anal', 'gaping'], analonly_980_170_8: ['anal', 'gaping'], nympho_1024_280: ['sex'], nympho_285_165: ['sex'], nympho_299_243: ['pussy-eating'], nympho_300_250: ['sex'], nympho_488_300: ['sex'], nympho_640_100: ['sex', 'ass-eating'], nympho_668_80: ['sex', 'blowjob', 'pussy-eating'], nympho_685_75: ['sex', 'blowjob', 'pussy-eating'], nympho_770_76: ['sex', 'blowjob', 'ass-eating', 'pussy-eating'], nympho_935_250: ['sex', 'blowjob', 'ass-eating'], nympho_960_75: ['sex', 'blowjob', 'ass-eating', 'pussy-eating'], swallowed_1323_270: ['blowjob'], swallowed_285_165: ['blowjob'], swallowed_300_250_4: ['blowjob'], swallowed_488_300: ['blowjob'], swallowed_728_90_03: ['blowjob'], swallowed_770_76: ['blowjob'], swallowed_850_80: ['blowjob'], swallowed_980_170: ['blowjob'], trueanal_300_100_2: ['anal'], trueanal_300_250: ['anal', 'gaping'], trueanal_315_300: ['anal', 'gaping'], trueanal_685_75: ['anal', 'gaping'], trueanal_728_90: ['anal'], trueanal_850_80: ['anal', 'gaping'], trueanal_970_170: ['anal', 'gaping'], trueanal_970_90_2: ['anal', 'gaping'], // aylo aylo_728_90_gay: ['gay'], // kelly madison kellymadison_300_250_bed: ['milf', 'big-boobs', 'lingerie', 'stockings'], kellymadison_760_430_bed: ['milf', 'big-boobs'], kellymadison_1700_400_lying: ['milf', 'big-boobs'], kellymadison_1700_400_redwhiteblack: ['milf', 'big-boobs'], pornfidelity_300_250_cg: ['sex', 'cowgirl', 'brunette'], pornfidelity_300_250_cherry_kiss: ['blonde', 'stockings'], pornfidelity_300_250_standing: ['brunette'], pornfidelity_760_430_bj: ['brunette', 'blowjob'], pornfidelity_760_430_cg_sfa: ['brunette', 'sex', 'cowgirl'], pornfidelity_760_430_dbj: ['blowjob', 'threesome', 'mff'], pornfidelity_760_430_miss_sofa: ['sex', 'brunette'], pornfidelity_880_440_cg_sofa: ['sex', 'cowgirl', 'brunette'], pornfidelity_880_440_mff: ['threesome', 'handjob', 'mff'], pornfidelity_880_440_miss_chair: ['sex', 'brunette'], pornfidelity_880_440_miss_sofa: ['sex', 'brunette'], teenfidelity_1323_270_bj: ['teen', 'blowjob', 'brunette'], teenfidelity_1323_270_doggy: ['teen', 'sex', 'brunette', 'doggy-style'], teenfidelity_1323_270_miss: ['teen', 'blonde', 'sex'], teenfidelity_315_271_bj: ['teen', 'brunette', 'blowjob'], teenfidelity_315_271_finger: ['teen'], teenfidelity_315_271_sex: ['teen', 'brunette', 'sex', 'reverse-cowgirl'], // 8k/5k '5kporn_1200_150': ['blonde'], '5kporn_300_100': ['brunette'], '5kporn_300_250': ['brunette'], '5kporn_315_271': ['brunette'], '5kporn_400_100': ['brunette'], '5kporn_468_60': ['brunette'], '5kporn_600_150': ['brunette'], '5kporn_600_500': ['brunette'], '5kporn_728_100': ['brunette'], '5kteens_300_250': ['teen', 'blonde'], '5kteens_315_271': ['teen', 'blonde'], '5kteens_400_100': ['teen', 'blonde'], '5kteens_600_150': ['teen', 'brunette'], '8kteens_300_250_bj': ['teen', 'blowjob', 'brunette'], '8kteens_300_250_hj': ['teen', 'redhead', 'handjob'], '8kteens_300_250': ['teen', 'brunette'], '8kteens_315_271_bj': ['teen', 'blowjob', 'brunette'], '8kteens_315_271': ['teen', 'brunette'], '8kteens_315_271_panties': ['teen', 'brunette'], '8kteens_600_500_split': ['teen', 'blonde', 'redhead'], '8kteens_728_90_bj': ['teen', 'brunette', 'blowjob'], '8kteens_728_90_hj': ['teen', 'handjob', 'blonde'], '8kteens_728_90': ['teen', 'sex', 'missionary', 'blonde'], '8kteens_970_250': ['teen', 'sex', 'missionary', 'brunette'], '8kmilfs_300_250_bj_close': ['blowjob', 'blonde', 'milf'], '8kmilfs_300_250_bj': ['blowjob', 'blonde', 'milf'], '8kmilfs_300_250_busty': ['brunette', 'milf'], '8kmilfs_300_250_payton_preslee': ['sex', 'brunette', 'milf'], '8kmilfs_300_250_ravyn_alexa': ['sex', 'tattoos', 'brunette', 'milf'], '8kmilfs_300_250_sex': ['sex', 'brunette', 'milf'], '8kmilfs_728_90_bj': ['blowjob', 'blonde', 'milf'], '8kmilfs_728_90_payton_preslee': ['sex', 'brunette', 'milf'], '8kmilfs_728_90_sex': ['sex', 'blonde', 'milf'], '8kmilfs_970_250': ['brunette', 'milf'], '8kmilfs_970_250_payton_preslee': ['brunette', 'milf'], '8kmilfs_970_250_sex': ['sex', 'blonde', 'milf'], // teenmegaworld analangels_468_80_animated: ['anal'], analangels_300_250_animated: ['anal'], analbeauty_468_80_animated: ['anal'], analbeauty_300_250_animated: ['anal'], analbeauty_300_250_tail_animated: ['anal', 'bondage', 'bdsm'], beautyangels_468_80_animated: ['solo'], beautyangels_300_250_69_animated: ['lesbian', '69'], beautyangels_300_250_lesbian_animated: ['lesbian'], teenmegaworld_300_250_animated: ['solo'], tmwvrnet_468_80_animated: ['vr'], // legalporno/analvids/pornworld pornworld_600_120_1: ['anal', 'brunette'], pornworld_600_120_2: ['mfm', 'sex', 'brunette'], // xempire hardx_770_76_anal: ['anal', 'blonde'], hardx_770_76_esperanza_anal: ['anal', 'brunette'], hardx_770_76_zoey_monroe_mff: ['sex', 'mff', 'blonde'], xempire_315_300: ['blowbang', 'sex', 'black-cock', 'brunette'], xempire_970_90_mff: ['mff', '69', 'brunette'], // vixen blacked_300_250_cherry_kiss_dp: ['dp', 'anal', 'black-cock'], blacked_300_250_cherry_kiss_anal_mfm: ['anal', 'black-cock'], tushy_970_70_alexa_flexy_dp: ['dp', 'anal'], tushy_776_70_gianna_dior_anal: ['anal'], // naughty america naughtyamerica_250_250_jenna_star: ['sex', 'doggy-style', 'blonde'], naughtyamerica_250_250_payton_preslee: ['titty-fucking', 'big-boobs', 'brunette'], naughtyamerica_250_250_wov: ['threesome', 'mff', 'big-boobs', 'brunette', 'blonde'], naughtyamerica_300_250_holly_day: ['sex', 'cowgirl', 'brunette', 'pov', 'vr'], naughtyamerica_300_250_kylie_page: ['sex', 'cowgirl', 'blonde', 'pov', 'vr'], naughtyamerica_300_250_melissa_stratton: ['sex', 'cowgirl', 'brunette', 'pov', 'vr'], naughtyamerica_728_90_holly_day: ['sex', 'blowjob', 'brunette', 'reverse-cowgirl'], naughtyamerica_728_90_kylie_page: ['titty-fucking', 'sex', 'doggy-style', 'blonde'], tonightsgirlfriend_300_250_jill_kassidy: ['sex', 'missionary', 'bbc', 'interracial', 'fishnet', 'fishnet-stockings', 'blonde'], tonightsgirlfriend_300_250_paisley_porter: ['sex', 'cowgirl', 'stockings', 'blonde'], tonightsgirlfriend_728_90_charli_phoenix: ['sex', 'blowjob', 'doggy-style', 'blonde'], tonightsgirlfriend_728_90_jill_kassidy: ['sex', 'blowjob', 'cowgirl', 'blonde'], tonightsgirlfriend_728_90_paisley_porter: ['sex', 'blowjob', 'missionary', 'stockings', 'blonde'], }; /* const bannerActors = { // 21sextury '21sextury_770_76_gina_gerson_dp': ['gina-gerson'], '21sextury_770_76_veronica_leal_dp': ['veronica-leal'], '21naturals_315_300_gina_gerson': ['gina-gerson'], '21naturals_315_300_ginebra_bellucci': ['ginebra-bellucci'], '21naturals_315_300_lana_roy_anal': ['lana-roy'], '21naturals_770_76_alexis_crystal': ['alexis-crystal'], // archangel archangel_970_90_kendra_lust: ['kendra-lust'], // evilangel evilangel_728_90_adriana_chechik_gangbang: ['adriana-chechik'], evilangel_728_90_kenzie_reeves_lexi_lore: ['kenzie-reeves', 'lexi-lore'], // julesjordan julesjordan_728_90_jill_kassidy: ['jill-kassidy'], julesjordan_728_90_angela_white: ['angela-white'], julesjordan_728_90_adriana_chechik: ['adriana-chechik'], julesjordan_728_90_autumn_falls: ['autumn-falls'], julesjordan_728_90_gabbie_carter: ['gabbie-carter'], // kink boundgangbangs_305_99_moretta_11975_animated: ['moretta'], boundgangbangs_305_99_moretta_11975: ['moretta'], boundgangbangs_315_300_lou_charmelle_12402_animated: ['lou-charmelle'], boundgangbangs_315_300_lou_charmelle_12402: ['lou-charmelle'], boundgangbangs_770_76_amy_brooke_11965_animated: ['amy-brooke'], boundgangbangs_770_76_anissa_kate_19662: ['anissa-kate'], boundgangbangs_970_90_sasha_swift_18815: ['sasha-swift'], boundgangbangs_970_90_skylar_price_12403_animated: ['skylar-price'], hardcoregangbang_300_250_kira_noir_44157: ['kira-noir'], hardcoregangbang_305_99_kira_noir: ['kira-noir'], // xempire hardx_770_76_esperanza_anal: ['esperanza-del-horno'], hardx_770_76_zoey_monroe_mff: ['zoey-monroe'], // vixen blacked_300_250_cherry_kiss_dp: ['cherry-kiss'], blacked_300_250_cherry_kiss_anal_mfm: ['cherry-kiss'], tushy_970_70_alexa_flexy_dp: ['alexa-flexy'], tushy_776_70_gianna_dior_anal: ['gianna-dior'], }; */ const campaigns = []; async function scan(dir) { const items = await fs.readdir(dir); const files = await Promise.all(items.map(async (item) => { const itemPath = path.join(dir, item); if ((await fs.stat(itemPath)).isDirectory()) { if (itemPath.includes('_')) { return []; } return scan(itemPath); } return itemPath; })); return files.flat(); } exports.seed = async (knex) => { const files = await scan('./public/banners'); const banners = files.map((file) => { const [network, channel, banner, type] = file.match(/(\w+)\/(\w+)\/(\w+)\.(\w+)$/).slice(1); const [affiliateId, width, height] = banner.match(/([a-z0-9]+)_(\d{2,4})_(\d{2,4})/).slice(1); const tags = bannerTags[banner] || []; const affiliate = affiliates.find((aff) => aff.id === affiliateId) || affiliates.find((aff) => aff.channel === channel) || affiliates.find((aff) => aff.network === network); if (!affiliate) { console.warn('UNMATCHED AFFILIATE', file); } return { file, network: network === 'banners' ? channel : network, channel: network === 'banners' ? null : channel, affiliateId, affiliate: affiliate?.id, banner, width: Number(width), height: Number(height), type, tags, }; }).filter((banner) => !!banner.affiliate); await Promise.all([ knex('campaigns').delete(), knex('banners_tags').delete(), ]); await Promise.all([ knex('affiliates').delete(), knex('banners').delete(), ]); const [networks, channels, tags] = await Promise.all([ knex('entities') .where('type', 'network') .whereIn('slug', [...affiliates, ...campaigns, ...banners].map((link) => link.network).filter(Boolean)), knex('entities') .where('type', 'channel') .whereIn('slug', [...affiliates, ...campaigns, ...banners].map((link) => link.channel).filter(Boolean)), knex('tags') .whereIn('slug', banners.flatMap((banner) => banner.tags || [])), /* knex('actors') .whereIn('slug', banners.flatMap((banner) => banner.tags || [])), */ ]); const networksBySlug = networks.reduce((acc, network) => ({ ...acc, [network.slug]: network }), {}); const channelsBySlug = channels.reduce((acc, channel) => ({ ...acc, [channel.slug]: channel }), {}); const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {}); const affiliatesWithEntityId = affiliates.map((affiliate) => ({ id: affiliate.id, entity_id: networksBySlug[affiliate.network]?.id || channelsBySlug[affiliate.channel]?.id || null, url: affiliate.url, parameters: affiliate.parameters, comment: affiliate.comment, })); const bannersWithEntityId = banners.map((banner) => ({ id: banner.id || banner.banner, width: banner.width, height: banner.height, type: banner.type || (banner.id.includes('animated') ? 'gif' : 'jpg'), entity_id: channelsBySlug[banner.channel]?.id || networksBySlug[banner.network]?.id || null, })); banners.map((banner) => { return { ...banner, entity: channelsBySlug[banner.channel] || networksBySlug[banner.network] || null, }; }); const bannerTagEntries = banners.flatMap((banner) => banner.tags?.map((tag) => ({ banner_id: banner.id || banner.banner, tag_id: tagsBySlug[tag].id, })) || []); const campaignsWithEntityIdAndAffiliateId = [...campaigns, ...banners].map((campaign) => ({ // entity_id: networksBySlug[campaign.network]?.id || channelsBySlug[campaign.channel]?.id, entity_id: channelsBySlug[campaign.channel]?.id || networksBySlug[campaign.network]?.id, url: campaign.url, affiliate_id: campaign.affiliate, banner_id: campaign.banner, })).filter((link) => link.entity_id && (link.url || link.affiliate_id || link.banner_id)); await knex('affiliates').insert(affiliatesWithEntityId); await bulkInsert('banners', bannersWithEntityId, false); await bulkInsert('banners_tags', bannerTagEntries, false); await bulkInsert('campaigns', campaignsWithEntityIdAndAffiliateId, false); };