feat(docs): add mkdocs

This commit is contained in:
Jef LeCompte
2020-12-07 00:18:43 -05:00
parent bc2272e59a
commit 243109a4ff
53 changed files with 1112 additions and 644 deletions
+2 -1
View File
@@ -232,7 +232,8 @@ const notifications = {
['tmobile', 'tmomail.net'],
['verizon', 'vtext.com'],
['virgin', 'vmobl.com'],
['virgin-ca', 'vmobile.ca']
['virgin-ca', 'vmobile.ca'],
['visible', 'vtext.com']
]),
carrier: envOrArray(process.env.PHONE_CARRIER),
number: envOrArray(process.env.PHONE_NUMBER)
+11 -4
View File
@@ -20,7 +20,9 @@ const prettyJson = winston.format.printf((info) => {
export const logger = winston.createLogger({
format: winston.format.combine(
winston.format.colorize(),
winston.format.metadata({fillExcept: ['level', 'message', 'timestamp']}),
winston.format.metadata({
fillExcept: ['level', 'message', 'timestamp']
}),
prettyJson
),
level: config.logLevel,
@@ -129,7 +131,9 @@ export const Print = {
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow(`PRICE ${link.price ?? ''} EXCEEDS LIMIT ${maxPrice}`)
chalk.yellow(
`PRICE ${link.price ?? ''} EXCEEDS LIMIT ${maxPrice}`
)
);
}
@@ -180,7 +184,8 @@ export const Print = {
},
productInStock(link: Link): string {
let productString = `Product Page: ${link.url}`;
if (link.cartUrl) productString += `\nAdd To Cart Link: ${link.cartUrl}`;
if (link.cartUrl)
productString += `\nAdd To Cart Link: ${link.cartUrl}`;
return productString;
},
@@ -204,7 +209,9 @@ function buildSetupString(
color?: boolean
): string {
if (color) {
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`);
return (
chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`)
);
}
return `[${store.name}] [setup (${topic})]`;
+4 -2
View File
@@ -31,7 +31,7 @@ export function sendDiscordMessage(link: Link, store: Store) {
'> provided by [streetmerchant](https://github.com/jef/streetmerchant) with :heart:'
)
.setThumbnail(
'https://raw.githubusercontent.com/jef/streetmerchant/main/media/streetmerchant-square.png'
'https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-square.png'
)
.setColor('#52b788')
.setTimestamp();
@@ -57,7 +57,9 @@ export function sendDiscordMessage(link: Link, store: Store) {
});
}
(await Promise.all(promises)).forEach(({client}) => client.destroy());
(await Promise.all(promises)).forEach(({client}) =>
client.destroy()
);
logger.info('✔ discord message sent');
} catch (error: unknown) {
+23 -11
View File
@@ -45,13 +45,14 @@ const adjustLightsWithAPI = (hueBridge: Api) => {
const arrayOfIDs = lightIds.split(',');
arrayOfIDs.forEach((light) => {
logger.debug('adjusting all hue lights');
(hueBridge.lights.setLightState(light, lightState) as Promise<any>).catch(
(error: Error) => {
logger.error('Failed to adjust all lights.');
logger.error(error);
throw error;
}
);
(hueBridge.lights.setLightState(
light,
lightState
) as Promise<any>).catch((error: Error) => {
logger.error('Failed to adjust all lights.');
logger.error(error);
throw error;
});
});
} else {
// Adjust all light IDs
@@ -102,15 +103,26 @@ export function adjustPhilipsHueLights() {
} else if (hue.apiKey && hue.clientId && hue.clientSecret) {
logger.info('↗ adjusting Philips Hue lights over cloud');
(async () => {
logger.debug('Attempting to connect to Philips Hue bridge over cloud');
const remoteBootstrap = hueAPI.api.createRemote(clientId, clientSecret);
logger.debug(
'Attempting to connect to Philips Hue bridge over cloud'
);
const remoteBootstrap = hueAPI.api.createRemote(
clientId,
clientSecret
);
if (hue.accessToken && hue.refreshToken) {
remoteBootstrap
.connectWithTokens(accessToken, refreshToken, remoteApiUsername)
.connectWithTokens(
accessToken,
refreshToken,
remoteApiUsername
)
.then(
(hueBridge) => {
adjustLightsWithAPI(hueBridge);
logger.info('✔ adjusted Philips Hue lights over cloud');
logger.info(
'✔ adjusted Philips Hue lights over cloud'
);
},
(error: Error) => {
logger.error(
+1 -1
View File
@@ -4,7 +4,7 @@ import {WebClient} from '@slack/web-api';
import {config} from '../config';
const slack = config.notifications.slack;
const channel = slack.channel;
const channel = slack.channel.replace('#', '');
const token = slack.token;
const web = new WebClient(token);
+17 -11
View File
@@ -20,19 +20,25 @@ export function playSound() {
if (config.notifications.playSound && player.player !== null) {
logger.debug('↗ playing sound');
fs.access(config.notifications.playSound, fs.constants.F_OK, (error) => {
if (error) {
logger.error(`✖ error opening sound file: ${error.message}`);
return;
}
player.play(config.notifications.playSound, (error: Error) => {
fs.access(
config.notifications.playSound,
fs.constants.F_OK,
(error) => {
if (error) {
logger.error("✖ couldn't play sound", error);
logger.error(
`✖ error opening sound file: ${error.message}`
);
return;
}
logger.info('✔ played sound');
});
});
player.play(config.notifications.playSound, (error: Error) => {
if (error) {
logger.error("✖ couldn't play sound", error);
}
logger.info('✔ played sound');
});
}
);
}
}
+6 -2
View File
@@ -39,7 +39,9 @@ const chatClient: ChatClient = new ChatClient(
{
accessToken,
expiryTimestamp:
expiryDate === null ? null : expiryDate.getTime(),
expiryDate === null
? null
: expiryDate.getTime(),
refreshToken
},
null,
@@ -90,7 +92,9 @@ export function sendTwitchMessage(link: Link, store: Store) {
logger.debug('↗ sending twitch message');
messages.push(
`${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`
`${Print.inStock(link, store)}\n${
link.cartUrl ? link.cartUrl : link.url
}`
);
if (!alreadySaying) {
+19 -5
View File
@@ -7,7 +7,9 @@ import {usingResponse} from '../util';
function addNewLinks(store: Store, links: Link[], series: Series) {
if (links.length === 0) {
logger.debug(Print.message('NO STORE LINKS FOUND', series, store, true));
logger.debug(
Print.message('NO STORE LINKS FOUND', series, store, true)
);
return;
}
@@ -20,7 +22,12 @@ function addNewLinks(store: Store, links: Link[], series: Series) {
}
logger.debug(
Print.message(`FOUND ${newLinks.length} STORE LINKS`, series, store, true)
Print.message(
`FOUND ${newLinks.length} STORE LINKS`,
series,
store,
true
)
);
logger.debug(JSON.stringify(newLinks, null, 2));
@@ -39,7 +46,9 @@ export async function fetchLinks(store: Store, browser: Browser) {
continue;
}
logger.debug(Print.message('DETECTING STORE LINKS', series, store, true));
logger.debug(
Print.message('DETECTING STORE LINKS', series, store, true)
);
if (!Array.isArray(url)) {
url = [url];
@@ -51,12 +60,17 @@ export async function fetchLinks(store: Store, browser: Browser) {
const text = await response?.text();
if (!text) {
logger.error(Print.message('NO RESPONSE', series, store, true));
logger.error(
Print.message('NO RESPONSE', series, store, true)
);
return;
}
const docElement = cheerio.load(text).root();
const links = store.linksBuilder!.builder(docElement, series);
const links = store.linksBuilder!.builder(
docElement,
series
);
addNewLinks(store, links, series);
})
+4 -1
View File
@@ -29,7 +29,10 @@ function filterModel(model: Link['model'], series: Link['series']): boolean {
const sanitizedSeries = series.replace(/\s/g, '');
for (const configModelEntry of config.store.showOnlyModels) {
const sanitizedConfigModel = configModelEntry.name.replace(/\s/g, '');
const sanitizedConfigSeries = configModelEntry.series.replace(/\s/g, '');
const sanitizedConfigSeries = configModelEntry.series.replace(
/\s/g,
''
);
if (sanitizedConfigSeries) {
if (
sanitizedSeries === sanitizedConfigSeries &&
+19 -8
View File
@@ -152,7 +152,8 @@ async function lookup(browser: Browser, store: Store) {
const proxy = nextProxy(store);
const useAdBlock = !config.browser.lowBandwidth && !store.disableAdBlocker;
const useAdBlock =
!config.browser.lowBandwidth && !store.disableAdBlocker;
const customContext = config.browser.isIncognito;
const context = customContext
@@ -212,9 +213,9 @@ async function lookup(browser: Browser, store: Store) {
statusCode = await lookupCard(browser, store, page, link);
} catch (error: unknown) {
logger.error(
`✖ [${store.name}] ${link.brand} ${link.series} ${link.model} - ${
(error as Error).message
}`
`✖ [${store.name}] ${link.brand} ${link.series} ${
link.model
} - ${(error as Error).message}`
);
const client = await page.target().createCDPSession();
await client.send('Network.clearBrowserCookies');
@@ -266,7 +267,9 @@ async function lookupCard(
if (await lookupCardInStock(store, page, link)) {
const givenUrl =
link.cartUrl && config.store.autoAddToCart ? link.cartUrl : link.url;
link.cartUrl && config.store.autoAddToCart
? link.cartUrl
: link.url;
logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
if (config.browser.open) {
@@ -313,7 +316,11 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
if (store.labels.bannedSeller) {
if (
await pageIncludesLabels(page, store.labels.bannedSeller, baseOptions)
await pageIncludesLabels(
page,
store.labels.bannedSeller,
baseOptions
)
) {
logger.warn(Print.bannedSeller(link, store, true));
return false;
@@ -367,7 +374,9 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
}
if (store.labels.outOfStock) {
if (await pageIncludesLabels(page, store.labels.outOfStock, baseOptions)) {
if (
await pageIncludesLabels(page, store.labels.outOfStock, baseOptions)
) {
logger.info(Print.outOfStock(link, store, true));
return false;
}
@@ -378,7 +387,9 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
export async function tryLookupAndLoop(browser: Browser, store: Store) {
if (!browser.isConnected()) {
logger.debug(`[${store.name}] Ending this loop as browser is disposed...`);
logger.debug(
`[${store.name}] Ending this loop as browser is disposed...`
);
return;
}
+3 -1
View File
@@ -26,7 +26,9 @@ export const AmazonNl: Store = {
},
{
container: '#outOfStock',
text: ['we weten niet of en wanneer dit item weer op voorraad is']
text: [
'we weten niet of en wanneer dit item weer op voorraad is'
]
}
]
},
+4 -2
View File
@@ -55,13 +55,15 @@ export const Asus: Store = {
],
name: 'asus',
realTimeInventoryLookup: async (itemNumber: string) => {
const request_url = 'https://store.asus.com/us/category/get_real_time_data';
const request_url =
'https://store.asus.com/us/category/get_real_time_data';
const response = await fetch(request_url, {
body: 'sm_seq_list%5B%5D=' + itemNumber,
headers: {
'accept-language': 'en-US,en;q=0.9',
'cache-control': 'no-cache',
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
'content-type':
'application/x-www-form-urlencoded; charset=UTF-8'
},
method: 'POST'
});
+2 -1
View File
@@ -3,7 +3,8 @@ import {Store} from './store';
export const BestBuy: Store = {
labels: {
inStock: {
container: '[data-sticky-media-gallery] .fulfillment-add-to-cart-button',
container:
'[data-sticky-media-gallery] .fulfillment-add-to-cart-button',
text: ['add to cart']
},
maxPrice: {
+4 -2
View File
@@ -59,7 +59,8 @@ export const Computeruniverse: Store = {
brand: 'evga',
model: 'xc3 black',
series: '3070',
url: 'https://www.computeruniverse.net/de/evga-geforce-rtx3070-xc3-black'
url:
'https://www.computeruniverse.net/de/evga-geforce-rtx3070-xc3-black'
},
{
brand: 'gainward',
@@ -142,7 +143,8 @@ export const Computeruniverse: Store = {
brand: 'pny',
model: 'dual fan',
series: '3070',
url: 'https://www.computeruniverse.net/de/pny-geforce-rtx3070-m-dual-8-gb'
url:
'https://www.computeruniverse.net/de/pny-geforce-rtx3070-m-dual-8-gb'
},
{
brand: 'pny',
+2 -1
View File
@@ -8,7 +8,8 @@ export const Currys: Store = {
text: ['add to basket']
},
maxPrice: {
container: '#product-actions span[class*="ProductPriceBlock__Price"]',
container:
'#product-actions span[class*="ProductPriceBlock__Price"]',
euroFormat: false // Note: Currys uses non-euroFromat as price seperator
},
outOfStock: {
+2 -1
View File
@@ -28,7 +28,8 @@ export const Ebuyer: Store = {
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.ebuyer.com/1125329-sony-playstation-5-console-cfi-1015a'
url:
'https://www.ebuyer.com/1125329-sony-playstation-5-console-cfi-1015a'
},
{
brand: 'sony',
+2 -1
View File
@@ -12,7 +12,8 @@ export const Elcorteingles: Store = {
// },
inStock: [
{
container: '.product_detail-purchase.mb-2.c12 .js-add-cart-text',
container:
'.product_detail-purchase.mb-2.c12 .js-add-cart-text',
text: ['a la cesta']
}
],
+4 -2
View File
@@ -10,7 +10,8 @@ export const Expert: Store = {
}
],
maxPrice: {
container: '.widget-Container-subContent .widget-ArticlePrice-price',
container:
'.widget-Container-subContent .widget-ArticlePrice-price',
euroFormat: false
},
outOfStock: [
@@ -30,7 +31,8 @@ export const Expert: Store = {
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.expert.de/shop/11364114744-ps4-pro-1tb-jet-black.html'
url:
'https://www.expert.de/shop/11364114744-ps4-pro-1tb-jet-black.html'
},
{
brand: 'sony',
+2 -1
View File
@@ -33,7 +33,8 @@ export const Game: Store = {
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.game.co.uk/en/playstation-5-digital-edition-2826341'
url:
'https://www.game.co.uk/en/playstation-5-digital-edition-2826341'
}
],
name: 'game'
+4 -1
View File
@@ -38,7 +38,10 @@ export async function processBackoffDelay(
if (!isBackoff) {
if (backoff.count > 0) {
backoff.count--;
backoff.time = Math.max(backoff.time / 2, config.browser.minBackoff);
backoff.time = Math.max(
backoff.time / 2,
config.browser.minBackoff
);
}
return -1;
+3 -1
View File
@@ -23,7 +23,9 @@ export function getProductLinksBuilder(options: LinksBuilderOptions) {
const links: Link[] = [];
for (let i = 0; i < productElements.length; i++) {
const productElement = productElements.eq(i);
const titleElement = productElement.find(options.titleSelector).first();
const titleElement = productElement
.find(options.titleSelector)
.first();
const title = options.titleAttribute
? titleElement.attr()?.[options.titleAttribute]
+14 -5
View File
@@ -62,7 +62,9 @@ export class NvidiaCart {
public async addToCard(productId: number, name: string): Promise<string> {
let cartUrl: string | undefined;
logger.info(`🚀🚀🚀 [nvidia] ${name}, starting auto add to cart 🚀🚀🚀`);
logger.info(
`🚀🚀🚀 [nvidia] ${name}, starting auto add to cart 🚀🚀🚀`
);
try {
logger.info(`🚀🚀🚀 [nvidia] ${name}, adding to cart 🚀🚀🚀`);
let lastError: Error | string | undefined;
@@ -70,7 +72,9 @@ export class NvidiaCart {
/* eslint-disable no-await-in-loop */
for (let i = 0; i < config.nvidia.addToCardAttempts; i++) {
try {
cartUrl = await this.addToCartAndGetLocationRedirect(productId);
cartUrl = await this.addToCartAndGetLocationRedirect(
productId
);
break;
} catch (error: unknown) {
@@ -92,7 +96,9 @@ export class NvidiaCart {
throw lastError;
}
logger.info(`🚀🚀🚀 [nvidia] ${name}, opening checkout page 🚀🚀🚀`);
logger.info(
`🚀🚀🚀 [nvidia] ${name}, opening checkout page 🚀🚀🚀`
);
logger.info(cartUrl);
await open(cartUrl);
@@ -129,7 +135,9 @@ export class NvidiaCart {
this.browser,
this.sessionUrl,
async (response) => {
return response?.json() as NvidiaSessionTokenJSON | undefined;
return response?.json() as
| NvidiaSessionTokenJSON
| undefined;
}
);
if (
@@ -154,7 +162,8 @@ export class NvidiaCart {
protected async addToCartAndGetLocationRedirect(
productId: number
): Promise<string> {
const url = 'https://api-prod.nvidia.com/direct-sales-shop/DR/add-to-cart';
const url =
'https://api-prod.nvidia.com/direct-sales-shop/DR/add-to-cart';
const sessionToken = await this.getSessionToken();
logger.info(` [nvidia] session_token=${sessionToken}`);
+4 -1
View File
@@ -67,7 +67,10 @@ export function generateLinks(): Link[] {
links.push({
brand: 'test:brand',
model: 'test:model',
openCartAction: generateOpenCartAction(fe2060SuperId, 'TEST CARD debug'),
openCartAction: generateOpenCartAction(
fe2060SuperId,
'TEST CARD debug'
),
series: 'test:series',
url: nvidiaStockUrl(fe2060SuperId, drLocale, currency)
});
+6 -2
View File
@@ -208,7 +208,9 @@ function printConfig() {
}
if (config.store.showOnlyBrands.length > 0) {
logger.info(` selected brands: ${config.store.showOnlyBrands.join(', ')}`);
logger.info(
` selected brands: ${config.store.showOnlyBrands.join(', ')}`
);
}
if (config.store.showOnlyModels.length > 0) {
@@ -224,7 +226,9 @@ function printConfig() {
}
if (config.store.showOnlySeries.length > 0) {
logger.info(` selected series: ${config.store.showOnlySeries.join(', ')}`);
logger.info(
` selected series: ${config.store.showOnlySeries.join(', ')}`
);
}
}
+2 -1
View File
@@ -12,7 +12,8 @@ export const NeweggCa: Store = {
text: ['add to cart']
},
maxPrice: {
container: 'div#app div.product-price > ul > li.price-current > strong',
container:
'div#app div.product-price > ul > li.price-current > strong',
euroFormat: false
}
},
+2 -1
View File
@@ -271,7 +271,8 @@ export const Notebooksbilliger: Store = {
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.notebooksbilliger.de/amd+ryzen+ryzen+7+5800x+cpu+684018'
url:
'https://www.notebooksbilliger.de/amd+ryzen+ryzen+7+5800x+cpu+684018'
},
{
brand: 'amd',
+2 -1
View File
@@ -28,7 +28,8 @@ export const Nvidia: Store = {
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.nvidia.com/en-us/geforce/graphics-cards/rtx-2060-super/'
url:
'https://www.nvidia.com/en-us/geforce/graphics-cards/rtx-2060-super/'
},
{
brand: 'nvidia',
+3 -1
View File
@@ -15,7 +15,9 @@ export const Otto: Store = {
},
outOfStock: {
container: 'div.p_message.p_message--hint > strong',
text: ['Deinen gewünschten Artikel können wir leider nicht mehr liefern']
text: [
'Deinen gewünschten Artikel können wir leider nicht mehr liefern'
]
}
},
links: [
+4 -2
View File
@@ -41,7 +41,8 @@ export const PCComponentes: Store = {
brand: 'asus',
model: 'tuf',
series: '3080',
url: 'https://www.pccomponentes.com/asus-tuf-geforce-rtx-3080-10gb-gddr6x'
url:
'https://www.pccomponentes.com/asus-tuf-geforce-rtx-3080-10gb-gddr6x'
},
{
brand: 'gigabyte',
@@ -246,7 +247,8 @@ export const PCComponentes: Store = {
brand: 'asus',
model: 'dual',
series: '3070',
url: 'https://www.pccomponentes.com/asus-geforce-rtx-3070-dual-8gb-gddr6'
url:
'https://www.pccomponentes.com/asus-geforce-rtx-3070-dual-8gb-gddr6'
},
{
brand: 'asus',
+6 -2
View File
@@ -32,13 +32,17 @@ export const Very: Store = {
const links: Link[] = [];
for (let i = 0; i < productElements.length; i++) {
const productElement = productElements.eq(i);
const titleElement = productElement.find('.productTitle').first();
const titleElement = productElement
.find('.productTitle')
.first();
const title = titleElement.text()?.replace(/\n/g, ' ').trim();
if (
!title ||
['RTX', series]
.map((x) => title.toLowerCase().includes(x.toLowerCase()))
.map((x) =>
title.toLowerCase().includes(x.toLowerCase())
)
.filter((x) => !x).length > 0
) {
continue;
+8 -4
View File
@@ -23,25 +23,29 @@ export const VsGamers: Store = {
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.vsgamers.es/product/procesador-amd-ryzen-5-5600x-37-ghz'
url:
'https://www.vsgamers.es/product/procesador-amd-ryzen-5-5600x-37-ghz'
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.vsgamers.es/product/procesador-amd-ryzen-7-5800x-38-ghz'
url:
'https://www.vsgamers.es/product/procesador-amd-ryzen-7-5800x-38-ghz'
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.vsgamers.es/product/procesador-amd-ryzen-9-5900x-37-ghz'
url:
'https://www.vsgamers.es/product/procesador-amd-ryzen-9-5900x-37-ghz'
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.vsgamers.es/product/procesador-amd-ryzen-9-5950x-34-ghz'
url:
'https://www.vsgamers.es/product/procesador-amd-ryzen-9-5950x-34-ghz'
},
{
brand: 'zotac',
+2 -1
View File
@@ -3,7 +3,8 @@ import {Store} from './store';
export const Walmart: Store = {
labels: {
inStock: {
container: '.button.spin-button.prod-ProductCTA--primary.button--primary',
container:
'.button.spin-button.prod-ProductCTA--primary.button--primary',
text: ['add to cart']
},
maxPrice: {
+2 -1
View File
@@ -20,7 +20,8 @@ export const Wipoid: Store = {
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.wipoid.com/pny-geforce-rtx-1650-dual-fan-4gb-gddr6.html'
url:
'https://www.wipoid.com/pny-geforce-rtx-1650-dual-fan-4gb-gddr6.html'
},
{
brand: 'gigabyte',
+4 -1
View File
@@ -9,7 +9,10 @@ declare module 'play-sound' {
export interface PlaySound {
player: string;
play: ((file: string, callback: (error: Error) => void) => PlayerProcess) &
play: ((
file: string,
callback: (error: Error) => void
) => PlayerProcess) &
((
file: string,
options: PlayOptions,
+20 -5
View File
@@ -18,7 +18,10 @@ declare module '@jef/pushbullet' {
export interface PushBulletStream {
connect: () => void;
close: () => void;
on: ((event: 'connect' | 'close' | 'nop', callback: () => void) => void) &
on: ((
event: 'connect' | 'close' | 'nop',
callback: () => void
) => void) &
((event: 'error', callback: (error: any) => void) => void) &
((event: 'message', callback: (message: any) => void) => void) &
((event: 'tickle', callback: (tickle: any) => void) => void) &
@@ -30,7 +33,10 @@ declare module '@jef/pushbullet' {
me(callback: PushBulletCallback);
devices(options: ListOptions, callback: PushBulletCallback);
devices(callback: PushBulletCallback);
createDevice(options: Record<string, any>, callback: PushBulletCallback);
createDevice(
options: Record<string, any>,
callback: PushBulletCallback
);
updateDevice(
deviceIden: string,
deviceOptions: Record<string, any>,
@@ -65,8 +71,14 @@ declare module '@jef/pushbullet' {
subscriptions(callback: PushBulletCallback);
subscribe(channelTag: string, callback: PushBulletCallback);
unsubscribe(subscriptionIden: string, callback: PushBulletCallback);
muteSubscription(subscriptionIden: string, callback: PushBulletCallback);
unmuteSubscription(subscriptionIden: string, callback: PushBulletCallback);
muteSubscription(
subscriptionIden: string,
callback: PushBulletCallback
);
unmuteSubscription(
subscriptionIden: string,
callback: PushBulletCallback
);
channelInfo(channelTag: string, callback: PushBulletCallback);
chats(options: ListOptions, callback: PushBulletCallback);
chats(callback: PushBulletCallback);
@@ -75,7 +87,10 @@ declare module '@jef/pushbullet' {
muteChat(chatIden: string, callback: PushBulletCallback);
unmuteChat(chatIden: string, callback: PushBulletCallback);
sendSMS(options: Record<string, any>, callback: PushBulletCallback);
sendClipboard(options: Record<string, any>, callback: PushBulletCallback);
sendClipboard(
options: Record<string, any>,
callback: PushBulletCallback
);
dismissEphemeral(
options: Record<string, any>,
callback: PushBulletCallback
+3 -1
View File
@@ -6,7 +6,9 @@ import {logger} from './logger';
export function getSleepTime(store: Store) {
const minSleep = store.minPageSleep as number;
return minSleep + Math.random() * ((store.maxPageSleep as number) - minSleep);
return (
minSleep + Math.random() * ((store.maxPageSleep as number) - minSleep)
);
}
export async function delay(ms: number) {