Now pulls all parts from set as parts list

master
Edward Peterson 3 years ago
parent 3a03df9c01
commit 873c82afdc

@ -0,0 +1,29 @@
module.exports = class {
constructor(sellerUsername, minBuy, lots) {
this.sellerUsername = sellerUsername;
this.minBuy = minBuy;
this.lots = lots || [];
}
addToCart(lot) {
this.lots.push(lot);
}
removeFromCart(partNumber, colorId){
this.lots = this.lots.filter(lot => lot.legoPartNumber !== partNumber && lot.colorId !== colorId)
}
removeListingIdFromCart(listingId) {
if(this.hasListingId(listingId))
this.lots.splice(this.lots.findIndex((lot) => lot.listingId === listingId), 1);
}
getPrice(){
return this.lots.reduce((totalPrice, lot) => totalPrice + lot.getPrice(lot.quantity), 0);
}
toString() {
return `Store: ${this.sellerUsername}
Price: ${this.getPrice()}
${this.lots.map(lot => '\t' + lot.toString() + '\n').join('')}`
}
hasListingId(id) {
return this.lots.findIndex((lot) => lot.listingId === id) !== -1;
}
}

@ -12,6 +12,9 @@ module.exports = class {
this.sellerUsername = listing.strSellerUsername; this.sellerUsername = listing.strSellerUsername;
this.sellerStoreName = listing.strStorename; this.sellerStoreName = listing.strStorename;
this.instantCheckout = listing.instantCheckout; this.instantCheckout = listing.instantCheckout;
this.legoPartNumber = null;
this.blPartNumber = null;
this.calculatedPrice = 0
this.prices = [ this.prices = [
{ {
quantity: 1, quantity: 1,
@ -44,7 +47,6 @@ module.exports = class {
getPrice(quantity) { getPrice(quantity) {
for(var i = this.prices.length - 1;i >= 0;i--){ for(var i = this.prices.length - 1;i >= 0;i--){
const price = this.prices[i]; const price = this.prices[i];
console.log(price, quantity, i)
if(quantity >= price.quantity){ if(quantity >= price.quantity){
return price.value * quantity return price.value * quantity
@ -52,6 +54,9 @@ module.exports = class {
} }
return null; return null;
} }
toString(){
return `${this.legoPartNumber} (${this.quantity}) -${this.colorId}- @ $${this.getPrice(this.quantity)}`
}
} }
const priceRegex = /US \$(?<price>\d+\.\d+)/; const priceRegex = /US \$(?<price>\d+\.\d+)/;
@ -65,6 +70,6 @@ function parseDollars(val) {
if(!stringPrice){ if(!stringPrice){
return 999999999; return 999999999;
} else { } else {
return parseFloat(stringPrice); return parseFloat(stringPrice) === 0 ? 0.01 : parseFloat(stringPrice);
} }
} }

@ -1,32 +1,41 @@
const superagent = require('superagent'); const superagent = require('superagent');
const LotListing = require('./LotListing') const LotListing = require('./LotListing')
const brickLinkAgent = superagent.agent(); const brickLinkAgent = superagent.agent();
const htmlParser = require('node-html-parser');
module.exports = { module.exports = {
getInternalPartId(legoPartNumber) { getInternalPartId(legoPartNumber) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://www.bricklink.com/v2/catalog/catalogitem.page?P=${legoPartNumber}`) brickLinkAgent.get(`https://www.bricklink.com/v2/catalog/catalogitem.page?P=${legoPartNumber}`)
// .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0') // .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0')
.then((response => { .then((response => {
if(response.statusCode !== 200) throw response.statusCode
const partIdRegex = /idItem:\s+(?<idItem>\d+)/gm; const partIdRegex = /idItem:\s+(?<idItem>\d+)/gm;
const matches = partIdRegex.exec(response.text); const matches = partIdRegex.exec(response.text);
resolve(matches.groups?.idItem) resolve(matches.groups?.idItem)
})).catch(error => { })).catch(error => {
console.error('HTTP error from internalPartId', error);
reject(error); reject(error);
}) })
}) })
}, },
getListings(internalPartId) { getListings(internalPartId, colorId) {
return new Promise((resolve, reject) => { return new Promise(async (resolve, reject) => {
brickLinkAgent.get(`https://www.bricklink.com/ajax/clone/catalogifs.ajax`) await new Promise((resolve) => setTimeout(resolve, Math.random() * 500 + 100));
.query({ var query = {
itemid: internalPartId, itemid: internalPartId,
loc: 'US' loc: 'US',
}) rpp: 100
// cond: 'U'
}
if(colorId){
query.color = colorId
}
brickLinkAgent.get(`https://www.bricklink.com/ajax/clone/catalogifs.ajax`)
.query(query)
// .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0') // .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0')
.set('Accept', 'application/json').then(response => { .set('Accept', 'application/json').then(response => {
if(!response.body.list) { if(!response.body.list) {
console.log(response.body, query)
return reject('no list found'); return reject('no list found');
} }
resolve(response.body.list.map(l => new LotListing(l))); resolve(response.body.list.map(l => new LotListing(l)));
@ -37,6 +46,14 @@ module.exports = {
}) })
}, },
getListingsByLegoPartNumber(legoPartNumber, colorId){
return module.exports.getInternalPartId(legoPartNumber).then((blPartNumber) => module.exports.getListings(blPartNumber, colorId)).then(listings => {
return listings.map(listing => {
listing.legoPartNumber = legoPartNumber
return listing;
})
})
},
getStoreId(sellerUsername) { getStoreId(sellerUsername) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://store.bricklink.com/${sellerUsername}`) brickLinkAgent.get(`https://store.bricklink.com/${sellerUsername}`)
@ -49,6 +66,40 @@ module.exports = {
reject(error); reject(error);
}) })
})
},
getSetInventory(setId) {
return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://www.bricklink.com/catalogItemInv.asp`)
.query({
S: setId
})
.then((response => {
var root = htmlParser.parse(response.text);
const rows = root.querySelectorAll('.IV_ITEM')
const parsed = rows.map(row => {
const partRegex = /\/v2\/catalog\/catalogitem.page\?P=(?<legoPartNumber>.+)&idColor=(?<colorId>\d+)/gm;
const quantityRegex = /<TD ALIGN="RIGHT">\&nbsp;(?<quantity>\d+)/gm
const matches = partRegex.exec(row.innerHTML);
const quantityMatches = quantityRegex.exec(row.innerHTML);
if(!matches) return null;
return {
partNumber: matches.groups?.legoPartNumber,
colorId: parseInt(matches.groups?.colorId),
quantity: parseInt(quantityMatches.groups?.quantity)
}
}).filter(r => r !== null);
resolve(parsed)
})).catch(error => {
console.error('HTTP error from getStoreId', error)
reject(error);
})
}) })
} }
} }

@ -0,0 +1,203 @@
var _varColorList = [];
_varColorList.push( { idColor: 0, strColorName: '(Not Applicable)', group: 0, rgb: '' } );
_varColorList.push( { idColor: 41, strColorName: 'Aqua', group: 1, rgb: 'BCE5DC' } );
_varColorList.push( { idColor: 11, strColorName: 'Black', group: 1, rgb: '212121' } );
_varColorList.push( { idColor: 7, strColorName: 'Blue', group: 1, rgb: '0057A6' } );
_varColorList.push( { idColor: 97, strColorName: 'Blue-Violet', group: 1, rgb: '506CEF' } );
_varColorList.push( { idColor: 36, strColorName: 'Bright Green', group: 1, rgb: '10CB31' } );
_varColorList.push( { idColor: 105, strColorName: 'Bright Light Blue', group: 1, rgb: 'BCD1ED' } );
_varColorList.push( { idColor: 110, strColorName: 'Bright Light Orange', group: 1, rgb: 'FFC700' } );
_varColorList.push( { idColor: 103, strColorName: 'Bright Light Yellow', group: 1, rgb: 'FFF08C' } );
_varColorList.push( { idColor: 104, strColorName: 'Bright Pink', group: 1, rgb: 'F7BCDA' } );
_varColorList.push( { idColor: 8, strColorName: 'Brown', group: 1, rgb: '6B3F22' } );
_varColorList.push( { idColor: 227, strColorName: 'Clikits Lavender', group: 1, rgb: 'E0AAD9' } );
_varColorList.push( { idColor: 220, strColorName: 'Coral', group: 1, rgb: 'FF8172' } );
_varColorList.push( { idColor: 153, strColorName: 'Dark Azure', group: 1, rgb: '009FE0' } );
_varColorList.push( { idColor: 63, strColorName: 'Dark Blue', group: 1, rgb: '243757' } );
_varColorList.push( { idColor: 109, strColorName: 'Dark Blue-Violet', group: 1, rgb: '2032B0' } );
_varColorList.push( { idColor: 85, strColorName: 'Dark Bluish Gray', group: 1, rgb: '595D60' } );
_varColorList.push( { idColor: 120, strColorName: 'Dark Brown', group: 1, rgb: '50372F' } );
_varColorList.push( { idColor: 10, strColorName: 'Dark Gray', group: 1, rgb: '6B5A5A' } );
_varColorList.push( { idColor: 80, strColorName: 'Dark Green', group: 1, rgb: '2E5543' } );
_varColorList.push( { idColor: 225, strColorName: 'Dark Nougat', group: 1, rgb: 'CE7942' } );
_varColorList.push( { idColor: 242, strColorName: 'Dark Olive Green', group: 1, rgb: '76753F' } );
_varColorList.push( { idColor: 68, strColorName: 'Dark Orange', group: 1, rgb: 'B35408' } );
_varColorList.push( { idColor: 47, strColorName: 'Dark Pink', group: 1, rgb: 'EF5BB3' } );
_varColorList.push( { idColor: 89, strColorName: 'Dark Purple', group: 1, rgb: '5F2683' } );
_varColorList.push( { idColor: 59, strColorName: 'Dark Red', group: 1, rgb: '6A0E15' } );
_varColorList.push( { idColor: 231, strColorName: 'Dark Salmon', group: 1, rgb: 'FF6326' } );
_varColorList.push( { idColor: 69, strColorName: 'Dark Tan', group: 1, rgb: 'B89869' } );
_varColorList.push( { idColor: 39, strColorName: 'Dark Turquoise', group: 1, rgb: '00A29F' } );
_varColorList.push( { idColor: 161, strColorName: 'Dark Yellow', group: 1, rgb: 'DD982E' } );
_varColorList.push( { idColor: 29, strColorName: 'Earth Orange', group: 1, rgb: 'E6881D' } );
_varColorList.push( { idColor: 106, strColorName: 'Fabuland Brown', group: 1, rgb: 'B3694E' } );
_varColorList.push( { idColor: 248, strColorName: 'Fabuland Lime', group: 1, rgb: 'ADD237' } );
_varColorList.push( { idColor: 160, strColorName: 'Fabuland Orange', group: 1, rgb: 'EF9121' } );
_varColorList.push( { idColor: 6, strColorName: 'Green', group: 1, rgb: '00923D' } );
_varColorList.push( { idColor: 154, strColorName: 'Lavender', group: 1, rgb: 'D3BDE3' } );
_varColorList.push( { idColor: 152, strColorName: 'Light Aqua', group: 1, rgb: 'CFEFEA' } );
_varColorList.push( { idColor: 62, strColorName: 'Light Blue', group: 1, rgb: 'C8D9E1' } );
_varColorList.push( { idColor: 86, strColorName: 'Light Bluish Gray', group: 1, rgb: 'AFB5C7' } );
_varColorList.push( { idColor: 91, strColorName: 'Light Brown', group: 1, rgb: '99663E' } );
_varColorList.push( { idColor: 9, strColorName: 'Light Gray', group: 1, rgb: '9C9C9C' } );
_varColorList.push( { idColor: 38, strColorName: 'Light Green', group: 1, rgb: 'D7EED1' } );
_varColorList.push( { idColor: 246, strColorName: 'Light Lilac', group: 1, rgb: 'CDCCEE' } );
_varColorList.push( { idColor: 35, strColorName: 'Light Lime', group: 1, rgb: 'ECEEBD' } );
_varColorList.push( { idColor: 90, strColorName: 'Light Nougat', group: 1, rgb: 'FECCB0' } );
_varColorList.push( { idColor: 32, strColorName: 'Light Orange', group: 1, rgb: 'FFBC36' } );
_varColorList.push( { idColor: 56, strColorName: 'Light Pink', group: 1, rgb: 'F2D3D1' } );
_varColorList.push( { idColor: 93, strColorName: 'Light Purple', group: 1, rgb: 'AF3195' } );
_varColorList.push( { idColor: 26, strColorName: 'Light Salmon', group: 1, rgb: 'FCC7B7' } );
_varColorList.push( { idColor: 40, strColorName: 'Light Turquoise', group: 1, rgb: '00C5BC' } );
_varColorList.push( { idColor: 44, strColorName: 'Light Violet', group: 1, rgb: 'C9CAE2' } );
_varColorList.push( { idColor: 33, strColorName: 'Light Yellow', group: 1, rgb: 'FEE89F' } );
_varColorList.push( { idColor: 245, strColorName: 'Lilac', group: 1, rgb: '7862CE' } );
_varColorList.push( { idColor: 34, strColorName: 'Lime', group: 1, rgb: 'C4E000' } );
_varColorList.push( { idColor: 247, strColorName: 'Little Robots Blue', group: 1, rgb: '5DBFE4' } );
_varColorList.push( { idColor: 72, strColorName: 'Maersk Blue', group: 1, rgb: '7DC1D8' } );
_varColorList.push( { idColor: 71, strColorName: 'Magenta', group: 1, rgb: 'B72276' } );
_varColorList.push( { idColor: 156, strColorName: 'Medium Azure', group: 1, rgb: '6ACEE0' } );
_varColorList.push( { idColor: 42, strColorName: 'Medium Blue', group: 1, rgb: '82ADD8' } );
_varColorList.push( { idColor: 240, strColorName: 'Medium Brown', group: 1, rgb: 'A16C42' } );
_varColorList.push( { idColor: 94, strColorName: 'Medium Dark Pink', group: 1, rgb: 'F785B1' } );
_varColorList.push( { idColor: 37, strColorName: 'Medium Green', group: 1, rgb: '91DF8C' } );
_varColorList.push( { idColor: 157, strColorName: 'Medium Lavender', group: 1, rgb: 'C689D9' } );
_varColorList.push( { idColor: 76, strColorName: 'Medium Lime', group: 1, rgb: 'DFE000' } );
_varColorList.push( { idColor: 150, strColorName: 'Medium Nougat', group: 1, rgb: 'E3A05B' } );
_varColorList.push( { idColor: 31, strColorName: 'Medium Orange', group: 1, rgb: 'FFA531' } );
_varColorList.push( { idColor: 241, strColorName: 'Medium Tan', group: 1, rgb: 'D9C594' } );
_varColorList.push( { idColor: 73, strColorName: 'Medium Violet', group: 1, rgb: '9391E4' } );
_varColorList.push( { idColor: 166, strColorName: 'Neon Green', group: 1, rgb: 'DBF355' } );
_varColorList.push( { idColor: 165, strColorName: 'Neon Orange', group: 1, rgb: 'FA5947' } );
_varColorList.push( { idColor: 236, strColorName: 'Neon Yellow', group: 1, rgb: 'FFFC00' } );
_varColorList.push( { idColor: 28, strColorName: 'Nougat', group: 1, rgb: 'FFAF7D' } );
_varColorList.push( { idColor: 155, strColorName: 'Olive Green', group: 1, rgb: 'ABA953' } );
_varColorList.push( { idColor: 4, strColorName: 'Orange', group: 1, rgb: 'FF7E14' } );
_varColorList.push( { idColor: 23, strColorName: 'Pink', group: 1, rgb: 'F5CDD6' } );
_varColorList.push( { idColor: 24, strColorName: 'Purple', group: 1, rgb: '7A238D' } );
_varColorList.push( { idColor: 5, strColorName: 'Red', group: 1, rgb: 'B30006' } );
_varColorList.push( { idColor: 88, strColorName: 'Reddish Brown', group: 1, rgb: '82422A' } );
_varColorList.push( { idColor: 27, strColorName: 'Rust', group: 1, rgb: 'B24817' } );
_varColorList.push( { idColor: 25, strColorName: 'Salmon', group: 1, rgb: 'FF7D5D' } );
_varColorList.push( { idColor: 55, strColorName: 'Sand Blue', group: 1, rgb: '8899AB' } );
_varColorList.push( { idColor: 48, strColorName: 'Sand Green', group: 1, rgb: 'A2BFA3' } );
_varColorList.push( { idColor: 54, strColorName: 'Sand Purple', group: 1, rgb: 'B57DA5' } );
_varColorList.push( { idColor: 58, strColorName: 'Sand Red', group: 1, rgb: 'C58D80' } );
_varColorList.push( { idColor: 87, strColorName: 'Sky Blue', group: 1, rgb: '8AD4E1' } );
_varColorList.push( { idColor: 2, strColorName: 'Tan', group: 1, rgb: 'EED9A4' } );
_varColorList.push( { idColor: 99, strColorName: 'Very Light Bluish Gray', group: 1, rgb: 'E4E8E8' } );
_varColorList.push( { idColor: 49, strColorName: 'Very Light Gray', group: 1, rgb: 'E8E8E8' } );
_varColorList.push( { idColor: 96, strColorName: 'Very Light Orange', group: 1, rgb: 'FFDCA4' } );
_varColorList.push( { idColor: 43, strColorName: 'Violet', group: 1, rgb: '3448A4' } );
_varColorList.push( { idColor: 1, strColorName: 'White', group: 1, rgb: 'FFFFFF' } );
_varColorList.push( { idColor: 3, strColorName: 'Yellow', group: 1, rgb: 'FFE001' } );
_varColorList.push( { idColor: 158, strColorName: 'Yellowish Green', group: 1, rgb: 'E7F2A7' } );
_varColorList.push( { idColor: 113, strColorName: 'Trans-Aqua', group: 2, rgb: 'B7C8BF' } );
_varColorList.push( { idColor: 13, strColorName: 'Trans-Black', group: 2, rgb: '939484' } );
_varColorList.push( { idColor: 108, strColorName: 'Trans-Bright Green', group: 2, rgb: '10Cb31' } );
_varColorList.push( { idColor: 12, strColorName: 'Trans-Clear', group: 2, rgb: 'EEEEEE' } );
_varColorList.push( { idColor: 14, strColorName: 'Trans-Dark Blue', group: 2, rgb: '00296B' } );
_varColorList.push( { idColor: 50, strColorName: 'Trans-Dark Pink', group: 2, rgb: 'CE1d9b' } );
_varColorList.push( { idColor: 20, strColorName: 'Trans-Green', group: 2, rgb: '217625' } );
_varColorList.push( { idColor: 15, strColorName: 'Trans-Light Blue', group: 2, rgb: '68BCC5' } );
_varColorList.push( { idColor: 226, strColorName: 'Trans-Light Bright Green', group: 2, rgb: '71EB54' } );
_varColorList.push( { idColor: 221, strColorName: 'Trans-Light Green', group: 2, rgb: '94E5AB' } );
_varColorList.push( { idColor: 164, strColorName: 'Trans-Light Orange', group: 2, rgb: 'E99A3A' } );
_varColorList.push( { idColor: 114, strColorName: 'Trans-Light Purple', group: 2, rgb: 'B97AB1' } );
_varColorList.push( { idColor: 74, strColorName: 'Trans-Medium Blue', group: 2, rgb: '76A3C8' } );
_varColorList.push( { idColor: 234, strColorName: 'Trans-Medium Purple', group: 2, rgb: '9C41B6' } );
_varColorList.push( { idColor: 16, strColorName: 'Trans-Neon Green', group: 2, rgb: 'C0F500' } );
_varColorList.push( { idColor: 18, strColorName: 'Trans-Neon Orange', group: 2, rgb: 'FF4231' } );
_varColorList.push( { idColor: 121, strColorName: 'Trans-Neon Yellow', group: 2, rgb: 'FFD700' } );
_varColorList.push( { idColor: 98, strColorName: 'Trans-Orange', group: 2, rgb: 'E96F01' } );
_varColorList.push( { idColor: 107, strColorName: 'Trans-Pink', group: 2, rgb: 'FF8298' } );
_varColorList.push( { idColor: 51, strColorName: 'Trans-Purple', group: 2, rgb: '5525B7' } );
_varColorList.push( { idColor: 17, strColorName: 'Trans-Red', group: 2, rgb: '9C0010' } );
_varColorList.push( { idColor: 19, strColorName: 'Trans-Yellow', group: 2, rgb: 'EBF72D' } );
_varColorList.push( { idColor: 57, strColorName: 'Chrome Antique Brass', group: 3, rgb: '645a4c' } );
_varColorList.push( { idColor: 122, strColorName: 'Chrome Black', group: 3, rgb: '544E4F' } );
_varColorList.push( { idColor: 52, strColorName: 'Chrome Blue', group: 3, rgb: '5C66A4' } );
_varColorList.push( { idColor: 21, strColorName: 'Chrome Gold', group: 3, rgb: 'f1f2e1' } );
_varColorList.push( { idColor: 64, strColorName: 'Chrome Green', group: 3, rgb: '3CB371' } );
_varColorList.push( { idColor: 82, strColorName: 'Chrome Pink', group: 3, rgb: 'aa4d8e' } );
_varColorList.push( { idColor: 22, strColorName: 'Chrome Silver', group: 3, rgb: 'DCDCDC' } );
_varColorList.push( { idColor: 237, strColorName: 'Bionicle Copper', group: 4, rgb: '985750' } );
_varColorList.push( { idColor: 238, strColorName: 'Bionicle Gold', group: 4, rgb: 'B9752F' } );
_varColorList.push( { idColor: 239, strColorName: 'Bionicle Silver', group: 4, rgb: 'A59287' } );
_varColorList.push( { idColor: 84, strColorName: 'Copper', group: 4, rgb: 'AC6D52' } );
_varColorList.push( { idColor: 81, strColorName: 'Flat Dark Gold', group: 4, rgb: 'AD7118' } );
_varColorList.push( { idColor: 95, strColorName: 'Flat Silver', group: 4, rgb: '8D949C' } );
_varColorList.push( { idColor: 244, strColorName: 'Pearl Black', group: 4, rgb: '282725' } );
_varColorList.push( { idColor: 77, strColorName: 'Pearl Dark Gray', group: 4, rgb: '666660' } );
_varColorList.push( { idColor: 115, strColorName: 'Pearl Gold', group: 4, rgb: 'E79E1D' } );
_varColorList.push( { idColor: 61, strColorName: 'Pearl Light Gold', group: 4, rgb: 'E7AE5A' } );
_varColorList.push( { idColor: 66, strColorName: 'Pearl Light Gray', group: 4, rgb: 'ACB7C0' } );
_varColorList.push( { idColor: 78, strColorName: 'Pearl Sand Blue', group: 4, rgb: '868FAA' } );
_varColorList.push( { idColor: 243, strColorName: 'Pearl Sand Purple', group: 4, rgb: 'B5A1BA' } );
_varColorList.push( { idColor: 119, strColorName: 'Pearl Very Light Gray', group: 4, rgb: 'D4D2CD' } );
_varColorList.push( { idColor: 83, strColorName: 'Pearl White', group: 4, rgb: 'FFFFFF' } );
_varColorList.push( { idColor: 249, strColorName: 'Reddish Copper', group: 4, rgb: 'D06926' } );
_varColorList.push( { idColor: 235, strColorName: 'Reddish Gold', group: 4, rgb: 'E7891B' } );
_varColorList.push( { idColor: 229, strColorName: 'Satin Trans-Black', group: 5, rgb: '939484' } );
_varColorList.push( { idColor: 233, strColorName: 'Satin Trans-Bright Green', group: 5, rgb: '7fe15b' } );
_varColorList.push( { idColor: 228, strColorName: 'Satin Trans-Clear', group: 5, rgb: 'FFFFFF' } );
_varColorList.push( { idColor: 232, strColorName: 'Satin Trans-Dark Blue', group: 5, rgb: '1552e2' } );
_varColorList.push( { idColor: 224, strColorName: 'Satin Trans-Dark Pink', group: 5, rgb: 'CE1d9b' } );
_varColorList.push( { idColor: 223, strColorName: 'Satin Trans-Light Blue', group: 5, rgb: '68BCC5' } );
_varColorList.push( { idColor: 230, strColorName: 'Satin Trans-Purple', group: 5, rgb: '8320B7' } );
_varColorList.push( { idColor: 250, strColorName: 'Metallic Copper', group: 6, rgb: 'C58259' } );
_varColorList.push( { idColor: 65, strColorName: 'Metallic Gold', group: 6, rgb: 'B8860B' } );
_varColorList.push( { idColor: 70, strColorName: 'Metallic Green', group: 6, rgb: 'bdb573' } );
_varColorList.push( { idColor: 67, strColorName: 'Metallic Silver', group: 6, rgb: 'C0C0C0' } );
_varColorList.push( { idColor: 46, strColorName: 'Glow In Dark Opaque', group: 7, rgb: 'd4d5c9' } );
_varColorList.push( { idColor: 118, strColorName: 'Glow In Dark Trans', group: 7, rgb: 'bdc6ad' } );
_varColorList.push( { idColor: 159, strColorName: 'Glow In Dark White', group: 7, rgb: 'd9d9d9' } );
_varColorList.push( { idColor: 60, strColorName: 'Milky White', group: 7, rgb: 'd4d3dd' } );
_varColorList.push( { idColor: 101, strColorName: 'Glitter Trans-Clear', group: 8, rgb: 'b2adaa' } );
_varColorList.push( { idColor: 100, strColorName: 'Glitter Trans-Dark Pink', group: 8, rgb: 'CE1d9b' } );
_varColorList.push( { idColor: 162, strColorName: 'Glitter Trans-Light Blue', group: 8, rgb: '68BCC5' } );
_varColorList.push( { idColor: 163, strColorName: 'Glitter Trans-Neon Green', group: 8, rgb: 'C0F500' } );
_varColorList.push( { idColor: 222, strColorName: 'Glitter Trans-Orange', group: 8, rgb: 'D04010' } );
_varColorList.push( { idColor: 102, strColorName: 'Glitter Trans-Purple', group: 8, rgb: '3A2B82' } );
_varColorList.push( { idColor: 116, strColorName: 'Speckle Black-Copper', group: 9, rgb: '5F4E47' } );
_varColorList.push( { idColor: 151, strColorName: 'Speckle Black-Gold', group: 9, rgb: 'AB9421' } );
_varColorList.push( { idColor: 111, strColorName: 'Speckle Black-Silver', group: 9, rgb: '7C7E7C' } );
_varColorList.push( { idColor: 117, strColorName: 'Speckle DBGray-Silver', group: 9, rgb: '4A6363' } );
_varColorList.push( { idColor: 142, strColorName: 'Mx Aqua Green', group: 10, rgb: '27867E' } );
_varColorList.push( { idColor: 128, strColorName: 'Mx Black', group: 10, rgb: '000000' } );
_varColorList.push( { idColor: 132, strColorName: 'Mx Brown', group: 10, rgb: '907450' } );
_varColorList.push( { idColor: 133, strColorName: 'Mx Buff', group: 10, rgb: 'DEC69C' } );
_varColorList.push( { idColor: 126, strColorName: 'Mx Charcoal Gray', group: 10, rgb: '595D60' } );
_varColorList.push( { idColor: 149, strColorName: 'Mx Clear', group: 10, rgb: 'FFFFFF' } );
_varColorList.push( { idColor: 214, strColorName: 'Mx Foil Dark Blue', group: 10, rgb: '0057A6' } );
_varColorList.push( { idColor: 210, strColorName: 'Mx Foil Dark Gray', group: 10, rgb: '595D60' } );
_varColorList.push( { idColor: 212, strColorName: 'Mx Foil Dark Green', group: 10, rgb: '006400' } );
_varColorList.push( { idColor: 215, strColorName: 'Mx Foil Light Blue', group: 10, rgb: '68AECE' } );
_varColorList.push( { idColor: 211, strColorName: 'Mx Foil Light Gray', group: 10, rgb: '9C9C9C' } );
_varColorList.push( { idColor: 213, strColorName: 'Mx Foil Light Green', group: 10, rgb: '7DB538' } );
_varColorList.push( { idColor: 219, strColorName: 'Mx Foil Orange', group: 10, rgb: 'F7AD63' } );
_varColorList.push( { idColor: 217, strColorName: 'Mx Foil Red', group: 10, rgb: '8B0000' } );
_varColorList.push( { idColor: 216, strColorName: 'Mx Foil Violet', group: 10, rgb: '4B0082' } );
_varColorList.push( { idColor: 218, strColorName: 'Mx Foil Yellow', group: 10, rgb: 'FED557' } );
_varColorList.push( { idColor: 139, strColorName: 'Mx Lemon', group: 10, rgb: 'BDC618' } );
_varColorList.push( { idColor: 124, strColorName: 'Mx Light Bluish Gray', group: 10, rgb: 'AfB5C7' } );
_varColorList.push( { idColor: 125, strColorName: 'Mx Light Gray', group: 10, rgb: '9C9C9C' } );
_varColorList.push( { idColor: 136, strColorName: 'Mx Light Orange', group: 10, rgb: 'F7AD63' } );
_varColorList.push( { idColor: 137, strColorName: 'Mx Light Yellow', group: 10, rgb: 'FFE371' } );
_varColorList.push( { idColor: 144, strColorName: 'Mx Medium Blue', group: 10, rgb: '61AFFF' } );
_varColorList.push( { idColor: 138, strColorName: 'Mx Ochre Yellow', group: 10, rgb: 'FED557' } );
_varColorList.push( { idColor: 140, strColorName: 'Mx Olive Green', group: 10, rgb: '7C9051' } );
_varColorList.push( { idColor: 135, strColorName: 'Mx Orange', group: 10, rgb: 'F47B30' } );
_varColorList.push( { idColor: 145, strColorName: 'Mx Pastel Blue', group: 10, rgb: '68AECE' } );
_varColorList.push( { idColor: 141, strColorName: 'Mx Pastel Green', group: 10, rgb: '7DB538' } );
_varColorList.push( { idColor: 148, strColorName: 'Mx Pink', group: 10, rgb: 'F785B1' } );
_varColorList.push( { idColor: 130, strColorName: 'Mx Pink Red', group: 10, rgb: 'F45C40' } );
_varColorList.push( { idColor: 129, strColorName: 'Mx Red', group: 10, rgb: 'B52C20' } );
_varColorList.push( { idColor: 146, strColorName: 'Mx Teal Blue', group: 10, rgb: '467083' } );
_varColorList.push( { idColor: 134, strColorName: 'Mx Terracotta', group: 10, rgb: '5C5030' } );
_varColorList.push( { idColor: 143, strColorName: 'Mx Tile Blue', group: 10, rgb: '0057A6' } );
_varColorList.push( { idColor: 131, strColorName: 'Mx Tile Brown', group: 10, rgb: '330000' } );
_varColorList.push( { idColor: 127, strColorName: 'Mx Tile Gray', group: 10, rgb: '6B5A5A' } );
_varColorList.push( { idColor: 147, strColorName: 'Mx Violet', group: 10, rgb: 'BD7D85' } );
_varColorList.push( { idColor: 123, strColorName: 'Mx White', group: 10, rgb: 'FFFFFF' } );
module.exports = _varColorList;

@ -1,100 +1,189 @@
const brickLinkAPI = require('./bricklink'); const brickLinkAPI = require('./bricklink');
const _ = require('lodash'); const _ = require('lodash');
const cart = [ const util = require('util');
{ const Cart = require('./Cart');
partNumber: '4592c01',
quantity: 2
},
{
partNumber: '3962b',
quantity: 1
},
{
partNumber: '3022',
quantity: 1
},
{
partNumber: '4081b',
quantity: 4
},
{
partNumber: '4740',
quantity: 1
},
{
partNumber: '3031',
quantity: 1
},
{
partNumber: '30303',
quantity: 1
},
{
partNumber: '3049b',
quantity: 1
},
{
partNumber: '3069bpc1',
quantity: 1
},
{
partNumber: '3004',
quantity: 1
},
{
partNumber: '2342',
quantity: 1
},
]
Promise.each = async function(arr, fn) { // take an array and a function
const results = [];
for(const item of arr) results.push(await item);
return results;
}
function getRandomizedDelay(){
return Math.random() * 500 + 500;
}
Promise.each(cart.map(lot => { async function getListings(order) {
return new Promise((resolve, reject) => { const results = []
brickLinkAPI.getInternalPartId(lot.partNumber).then((blId) => { for (var i = 0; i < order.length; i++) {
brickLinkAPI.getListings(blId).then(listings => { const lot = order[i];
console.log(listings.length + 'Listings found'); try {
var listings = await brickLinkAPI.getListingsByLegoPartNumber(lot.partNumber, lot.colorId);
console.log(listings.length + 'Listings found for', lot.partNumber, `(#${lot.colorId}#)`);
const lotsWithEnoughItems = listings.filter(l => l.quantity >= lot.quantity); const lotsWithEnoughItems = listings.filter(l => l.quantity >= lot.quantity);
// const lotsWithEnoughItemsAndAboveMinBuy = lotsWithEnoughItems.filter(lotf => lotf.minBuy === 'None' || (lotf.getPrice(lot.quantity) > lotf.minBuy)).map(lotf => { results.push(lotsWithEnoughItems.map(lota => {
// lotf.calculatedPrice = lotf.getPrice(lot.quantity); //update the quantity to only what we need
// return lotf; lota.quantity = lot.quantity;
// }) return lota;
setTimeout(() => { }));
resolve(lotsWithEnoughItems); //Wait added to not cause a 403. dont want to dos bricklink
await new Promise(resolve => setTimeout(resolve, getRandomizedDelay()));
}, 1000) } catch (error) {
}).catch(error => { console.error('Unable to source: ', lot.partNumber, error)
console.error('Failed to fetch listings', error); }
reject(error);
}) }
}).catch(error => { return results;
console.error('Failed to fetch internal id', error); }
reject(error); brickLinkAPI.getSetInventory('4990-1').then((inventory) => {
}) getListings(inventory).then(parts => {
}); var carts = [];
})).then(parts => {
var groupedLots = [];
const possibleLots = _.flatten(parts); const possibleLots = _.flatten(parts);
possibleLots.forEach(lot => { possibleLots.forEach(lot => {
const group = _.findIndex(groupedLots, l => l.sellerUsername === lot.sellerUsername); const group = _.findIndex(carts, l => l.sellerUsername === lot.sellerUsername);
if (group === -1) { if (group === -1) {
const newGroup = { const newGroup = new Cart(lot.sellerUsername, lot.minBuy, [lot]);
sellerUsername: lot.sellerUsername,
minBuy: lot.minBuy, carts.push(newGroup);
lots: [lot]
}
groupedLots.push(newGroup);
} else { } else {
groupedLots[group].lots.push(lot); carts[group].addToCart(lot);
}
})
//sometimes sellers make multiple listings of the same part in the same color. filter for the cheapest
carts = carts.map(cart => {
const groupedLots = _.groupBy(cart.lots, (lot) => `${lot.legoPartNumber}-${lot.colorId}`);
const listingsToRemove = [];
_.keys(groupedLots).forEach((partType) => {
if (groupedLots[partType].length <= 1) return;
const pricesPerLot = groupedLots[partType].map((lot) => lot.getPrice(lot.quantity));
const minPrice = Math.min(...pricesPerLot);
const lotsAtMinPrice = groupedLots[partType].filter((lot) => lot.getPrice(lot.quantity) === minPrice);
if (lotsAtMinPrice.length === 1) {
listingsToRemove.push(..._.difference(groupedLots[partType], ...lotsAtMinPrice))
return;
} }
//Just keep the first one at this point. they're the same price.
listingsToRemove.push(...groupedLots[partType].slice(1));
}) })
if(listingsToRemove.length > 0) console.log(`Removing ${listingsToRemove.length} listings for duplication from seller ${cart.sellerUsername}....`);
console.log(groupedLots.filter(gl => gl.lots.length > 1)); return new Cart(
cart.sellerUsername,
cart.minBuy,
_.differenceBy(cart.lots, listingsToRemove, (a) => a.listingId))
}) })
//throw out any carts that won't meet min buy
var aboveMinBuy = carts.filter((cart) => cart.getPrice() >= cart.minBuy);
console.log(`Found ${aboveMinBuy.length} possible carts`);
//brute force things here for now
//generage every possible order combo
//for every cart, see if we have everything.
var currentlyUnsourcedParts = inventory;
var calculatedCarts = [];
while (currentlyUnsourcedParts.length > 0) {
console.log(`Searching for parts to cover ${currentlyUnsourcedParts.length} lots...`, currentlyUnsourcedParts)
const bestAddition = getCartWithBestCoverage(aboveMinBuy, currentlyUnsourcedParts);
calculatedCarts.push(bestAddition);
console.log(`Added new cart to cover ${bestAddition.lots.length} lots.`, bestAddition);
//check for duplicated lots across carts and keep the lowest price one, so long as it doesn't push us below min buy
const lotsFromAllCarts = calculatedCarts.reduce((acc, cart) => { acc.push(...cart.lots); return acc; }, [])
const groupedLots = _.groupBy(lotsFromAllCarts, (lot) => `${lot.legoPartNumber}-${lot.colorId}`);
const listingsToRemove = [];
_.keys(groupedLots).forEach((partType) => {
const legoPartNumber = partType.split('-')[0];
const colorId = partType.split('-')[1];
if (groupedLots[partType].length <= 1) return;
const pricesPerLot = groupedLots[partType].map((lot) => lot.getPrice(lot.quantity));
const minPrice = Math.min(...pricesPerLot);
const lotsAtMinPrice = groupedLots[partType].filter((lot) => lot.getPrice(lot.quantity) === minPrice);
if (lotsAtMinPrice.length === 1) {
//TODO possibly perform check to see if we're gonna push the others below min buy
listingsToRemove.push(...(_.difference(groupedLots[partType], lotsAtMinPrice).map(i => i.listingId)))
return;
}
//everything is the same price here, lets just keep the one in the largest lot
const cartSizesPerLot = lotsAtMinPrice.map(lot => {
//what cart do I belong to?
const parentCart = calculatedCarts.find((cart) => cart.hasListingId(lot.listingId));
return parentCart.lots.length;
});
const largestCartSize = Math.max(...cartSizesPerLot);
const cartsAtLargestSize = calculatedCarts.filter(cart => cart.lots.length === largestCartSize);
if (cartsAtLargestSize.length === 1) {
//keep this cart, remove the item from the others.
//get the listing in this cart
const cart = cartsAtLargestSize[0];
const keepingLot = cart.lots.find((lot) => lot.legoPartNumber == legoPartNumber && lot.colorId == colorId);
listingsToRemove.push(...(groupedLots[partType].filter(lot => lot.listingId !== keepingLot.listingId).map(i => i.listingId)))
return;
}
//at this point, they're same price, and same cart sizes. Just pick the first one
listingsToRemove.push(...groupedLots[partType].slice(1).map(i => i.listingId));
})
calculatedCarts.forEach(cart => {
listingsToRemove.forEach(listingId => cart.removeListingIdFromCart(listingId))
});
currentlyUnsourcedParts = getUnsourcedParts(calculatedCarts, currentlyUnsourcedParts);
}
// console.log('Final cart', util.inspect(calculatedCarts, false, null, true));
console.log('Total price without shipping: ', calculatedCarts.reduce((acc, cart) => acc + cart.getPrice(), 0), 'across', calculatedCarts.length, 'stores');
calculatedCarts.forEach((cart) => console.log(cart.toString()));
})
})
function getCartWithBestCoverage(carts, partsList) {
var coverages = carts.map(cart => {
const itemsNotInThisCart = partsList.filter(item => {
return _.findIndex(cart.lots, lot => lot.legoPartNumber === item.partNumber && lot.colorId === item.colorId) === -1;
})
if (itemsNotInThisCart.length === 0) {
//ONE STORE SOLUTION FOUND, NICE!
// console.log('Coverage found: ', cart);
return 0;
}
return itemsNotInThisCart.length;
})
if (coverages.reduce((acc, val) => acc + val, 0) === 0) {
}
const bestCoverage = Math.min(...coverages);
const coverageOptions = carts.filter((value, index, array) => {
return coverages[index] === bestCoverage
}).sort((a, b) => a.getPrice() - b.getPrice());
if(bestCoverage === partsList.length){
//no carts are providing coverage.
throw new Error('Cannot fulfill order, lacking coverage');
}
// if(Math.min(...coverages)) === )
// const bestCoverageIndex = coverages.indexOf();
return coverageOptions[0];
}
function getUnsourcedParts(carts, partsList) {
const allLotsFromAllCarts = _.uniqBy(carts.reduce((acc, cart) => { acc.push(...cart.lots); return acc; }, []), (lot) => `${lot.legoPartNumber}_${lot.colorId}`);
return partsList.filter((part) => {
return allLotsFromAllCarts.findIndex((lot) => lot.legoPartNumber === part.partNumber && lot.colorId === part.colorId) === -1
})
}

82
package-lock.json generated

@ -14,6 +14,11 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
}, },
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"call-bind": { "call-bind": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@ -41,6 +46,23 @@
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
"integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ=="
}, },
"css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
}
},
"css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -63,6 +85,44 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
},
"entities": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
},
"fast-safe-stringify": { "fast-safe-stringify": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
@ -117,6 +177,11 @@
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}, },
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
"hexoid": { "hexoid": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
@ -163,6 +228,23 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node-html-parser": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.4.tgz",
"integrity": "sha512-3muP9Uy/Pz7bQa9TNYVQzWJhNZMqyCx7xJle8kz2/y1UgzAUyXXShc1IcPaJy6u07CE3K5rQcRwlvHzmlySRjg==",
"requires": {
"css-select": "^5.1.0",
"he": "1.2.0"
}
},
"nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"requires": {
"boolbase": "^1.0.0"
}
},
"object-inspect": { "object-inspect": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",

@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"lodash": "^4.17.21", "lodash": "^4.17.21",
"node-html-parser": "^6.1.4",
"superagent": "^8.0.6" "superagent": "^8.0.6"
} }
} }

Loading…
Cancel
Save