Scripts

This is a listing of all the scripts I use with Script Kit.

aws-cost.js

// Menu: View AWS Cost of time period
// Description: Warning: This will cost $0.01 per run
let start = await arg('Enter start date (YYYY-MM-DD)')
let end = await arg('Enter end date (YYYY-MM-DD)')
let {stdout} = exec(`aws ce get-cost-and-usage --time-period Start=${start},End=${end} --granularity MONTHLY --metrics "BlendedCost"`)
let data = JSON.parse(stdout)
let monthCost = data.ResultsByTime[0].Total.BlendedCost
let { say } = await kit('speech')
await say(`Your AWS bill is $${Number(monthCost.Amount).toFixed(2)}`)

build-portfolio.js

// Menu: Build Portfolio
// Description: Runs a github actions workflow to build my site and deploy it to Netlify
// Author: Benjamin Lannon
// Twitter: @lannonbr
// Shortcut: opt b
const workflowID = 50890;
await arg(
"are you sure you want to build the site? Press enter to continue..."
);
// triggers a workflow_dispatch event to my workflow
const { stderr, stdout } = exec(
`/usr/local/bin/gh workflow run ${workflowID} --repo lannonbr/Portfolio`
);
console.log(stderr, stdout);

github-discussions.js

// Menu: GitHub Discussions
// Description: Open the Discussions pane of a GitHub repo
// Author: Benjamin Lannon
// Twitter: @lannonbr
let repo = await arg("Enter repo (ex: johnlindquist/kit):");
exec(`open https://github.com/${repo}/discussions`);

github-trending-puller.js

// Description: Pulls down trending repos from github and save to database
// Schedule: 0 */4 * * *
// Exclude: true
/** @type typeof import('playwright') */
const playwright = await npm("playwright");
let dbDefaults = {};
const langs = ["rust", "javascript", "typescript", "go", "python", "ruby"];
for (const lang of langs) {
dbDefaults[lang] = [];
}
const trendingDB = await db("github-trending", dbDefaults);
const browser = await playwright.chromium.launch();
for (const lang of langs) {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(`https://github.com/trending/${lang}`);
const repos = await page.evaluate(() => {
const repos = document.querySelectorAll(".Box-row");
const results = [];
for (let repo of repos) {
const repoName = repo.querySelector("h1 a").getAttribute("href").slice(1);
let description = repo.querySelector("p")?.textContent.trim();
const starCount = repo
.querySelector("div span.d-inline-block.float-sm-right")
?.textContent.trim();
if (!description) {
description = starCount;
} else {
description = `${starCount} | ${description}`;
}
results.push({
name: repoName,
value: `https://github.com/${repoName}`,
description,
});
}
return results;
});
trendingDB[lang] = repos;
await trendingDB.write();
}
await browser.close();

github-trending.js

// Menu: GitHub Trending
// Description: Show today's Trending GitHub Repos for various languages
const trendingDB = await db("github-trending");
const langs = ["rust", "javascript", "typescript", "go", "python", "ruby"];
for (const lang of langs) {
onTab(lang, async () => {
const repo = await arg("Select a repo to open it", trendingDB[lang]);
exec(`open ${repo}`);
});
}

lannonbr-garden.js

// Menu: Lannonbr.com Garden
// Description: Search posts on lannonbr.com
// Author: Benjamin Lannon
// Twitter: @lannonbr
let resp = await get("https://lannonbr.com/posts.json");
let post = await arg("What post do you want to read", resp.data.items);
exec(`open ${post}`)
copy(post);

learn-with-jason-search.js

// Menu: Learn with Jason Search
// Description: Browse Learn With Jason Episodes
// Author: Benjamin Lannon
// Twitter: @lannonbr
let episode = await arg(
`Search for an episode of Learn with Jason`,
async () => {
const resp = await get("https://www.learnwithjason.dev/episodes.json");
console.log(JSON.stringify(resp.data.episodes[0], null, 2));
return resp.data.episodes.map((episode) => {
return {
value: episode.slug.current,
name: episode.title,
};
});
}
);
let url = `https://www.learnwithjason.dev/${episode}`;
exec(`open ${url}`);

list-keyboard-shortcuts.js

// Menu: List Keyboard Shortcuts
// Description: List out all scripts with keyboard shortcuts
// Shortcut: opt s
// Author: Benjamin Lannon
// Twitter: @lannonbr
let { buildMenu } = await cli("fns");
let scriptMetadata = await buildMenu();
console.log(scriptMetadata)
let opts = [];
for (let script of scriptMetadata) {
if (script.shortcut) {
opts.push({
name: `${script.command}: ${script.shortcut}`,
});
}
}
console.log(opts)
await arg("Current shortcuts", opts);

nodejs-available-versions.js

// Menu: Available Node versions
// Description: View all supported versions of NodeJS
// Author: Benjamin Lannon
// Twitter: @lannonbr
let resp = await get(
"https://raw.githubusercontent.com/nodejs/Release/main/schedule.json"
);
const data = Object.entries(resp.data);
/** @type typeof import('dayjs') */
let dayjs = await npm("dayjs");
let opts = [];
for (let [version, info] of data) {
let isSupported =
dayjs(info.start).diff(dayjs(), "days") < 0 &&
dayjs(info.end).diff(dayjs(), "days") > 0;
if (isSupported) {
opts.push({
name: `Node ${version}`,
description: `Maintainence ends on ${dayjs(info.end).format(
"MMMM DD, YYYY"
)}`,
endDate: info.end,
});
}
}
opts = opts.sort((a, b) => {
return dayjs(a.endDate).unix() - dayjs(b.endDate).unix();
});
await arg("These versions of NodeJS are currently maintained", opts);

sleep-mac.js

// Menu: Sleep
// Description: Put Mac into sleep mode
applescript('tell application "Finder" to sleep')

stock-price.js

// Shortcut: opt shift s
const { getCurrentPrice } = await npm("yahoo-stock-prices");
let { say } = await kit("speech");
let ticker = await arg("What stock do you want to check");
const price = await getCurrentPrice(ticker.toUpperCase());
say(`${ticker.toUpperCase()} is trading at $${price}`);

sync-scripts.js

// Menu: Sync Scripts
// Description: Pull from backup scripts git repo & create shell scripts for ones that don't have one yet
// Author: Benjamin Lannon
// Twitter: @lannonbr
exec('cd ~/.kenv/scripts && git pull origin main')
await cli('create-all-bins')

tailwind-colors.js

let color = await arg(`Choose a color`, [
"gray",
"red",
"yellow",
"green",
"blue",
"indigo",
"purple",
"pink",
]);
let mult = await arg(
`Choose a multiple of 100`,
`
<div class="flex justify-center">
<div class="w-10 h-10 text-${color}-100 flex items-center justify-center">100</div>
<div class="w-10 h-10 text-${color}-200 flex items-center justify-center">200</div>
<div class="w-10 h-10 text-${color}-300 flex items-center justify-center">300</div>
<div class="w-10 h-10 text-${color}-400 flex items-center justify-center">400</div>
<div class="w-10 h-10 text-${color}-500 flex items-center justify-center">500</div>
<div class="w-10 h-10 text-${color}-600 flex items-center justify-center">600</div>
<div class="w-10 h-10 text-${color}-700 flex items-center justify-center">700</div>
<div class="w-10 h-10 text-${color}-800 flex items-center justify-center">800</div>
<div class="w-10 h-10 text-${color}-900 flex items-center justify-center">900</div>
</div>
`
);
let place = await arg("What are we styling", [
{ name: "border", value: "border" },
{ name: "text-color", value: "text" },
{ name: "background", value: "bg" },
]);
copy(`${place}-${color}-${mult}`);

todoist-tasks.js

// Menu: Todoist Tasks
// Description: View this week's tasks from Todoist
// Author: Benjamin Lannon
// Twitter: @lannonbr
// Shortcut: opt t
/** @type typeof import('todoist') */
const todoistPackage = await npm("todoist");
/** @type typeof import('dayjs') */
const dayjs = await npm("dayjs");
// API Token can be found here: https://todoist.com/prefs/integrations
const token = await env("TODOIST_TOKEN");
const client = todoistPackage.v8(token);
await client.sync();
let items = client.items.get();
items = items.filter((item) => {
let dueDate = dayjs(item.due.date);
return dueDate.diff(dayjs(), "day") <= 7;
}).sort((a, b) => {
return dayjs(a.due.date).diff(dayjs(b.due.date));
});
await arg(
"View this week's tasks",
items.map((item) => {
return {
name: item.content,
description: `Due: ${item.due.date}`,
};
})
);

twitter-validator.js

// Menu: Twitter Validator
// Description: Open Twitter Opengraph image validator in default browser
// Shortcut: opt shift t
exec("open https://cards-dev.twitter.com/validator");

unix-timestamp.js

// Menu: Unix Timestamp
// Description: Copy current unix timestamp (in seconds) to clipboard
// Shortcut: alt shift u
/** @type typeof import('dayjs') */
const dayjs = await npm('dayjs')
await copy(dayjs().unix().toString())

uuid.js

// Menu: UUID
// Description: Generate a v4 UUID and copy to clipboard
// Shortcut: opt u
// Author: Benjamin Lannon
// Twitter: @lannonbr
copy(uuid())