Skip to content

Instantly share code, notes, and snippets.


Ian Langworth ☠ statico

Block or report user

Report or block statico

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
statico /
Last active Sep 26, 2019
Ian's Personal Short Link Bookmark Service
statico /
Last active Apr 17, 2019
Zelda BotW icon export for Slack emoji
  1. Go to and "Save as Web Page" with Chrome
  2. In a new folder, cp ../*/*BotW_*png .
  3. Use rename to rename all the files, hopefully keeping the larger version of all files: rename -f '$_=lc $_; s/botw\W//g; s/\d+px.//i; s/_Icon//i; s/_/-/g; s/^(botw-)?/botw-/; s/[^\w.-]+//g; s/-+\.png/.png/' *
  4. Resize to 128x128px max with ImageMagick: mogrify -resize '128x128>' *.png
  5. Upload with the neutral-face-emoji-tools Chrome extension, possibly merging in to rate limit uploads
statico / streaming-csv-writer.ts
Created Mar 8, 2019
Streaming CSV Writer / TypeScript
View streaming-csv-writer.ts
import * as stringify from 'csv-stringify/lib/sync'
import * as fs from 'fs-extra'
import { Writable } from 'stream'
import * as tempy from 'tempy'
// Stringifies and writes a row at a time to disk. Call close() when finished to
// get the path to a temporary file where the CSV was written. You are
// responsible for deleting that file when finished.
export class StreamingCSVWriter {
private count: number
statico / data.ts
Created Mar 8, 2019
Get a Google Sheet using NodeJS async and TypeScript and Service Account credentials
View data.ts
import * as fs from 'fs-extra'
import { google } from 'googleapis'
import * as pathlib from 'path'
const getSheet = async (
keyFile: string,
spreadsheetId: string,
range: string
): Promise<string[][]> => {
const auth = await google.auth.getClient({
statico / circleci.yml
Created Jan 21, 2019
Node.js 10 + PostgreSQL CircleCI config
View circleci.yml
version: 2
version: 2
- test
statico /
Last active Feb 7, 2019
Knex & TypeScript


  • Make all parts of Knex TypeScript-safe
statico /
Last active Feb 7, 2019
Top-level monorepo TypeScript/JavaScript style with tslint and Prettier


  • A single style for our projects and others
  • Minimize customization - Any decided-upon style is better than one we can bikeshed
  • Minimize friction - Instead of warnings, sources are formatted automatically on commit and on save inside your editor
  • Minimize files - These three or four files need only be at the top level of the monorepo... nothign in the subdirs

Why X?

  • Prettier, no semicolons - Because you don't need them and they add unnecessary visual clutter. Prettier will figure out when they're needed for you.
statico / gist.sql
Created Dec 17, 2018
PostgreSQL auto-slug / slugification field with trigger
View gist.sql
create or replace function update_slug_from_name()
returns trigger as $$
new.slug = regexp_replace(
'''', '', 'g'),
'[^a-z0-9+]+', '-', 'g'),
'^-+|-+$', '');
View permutations.test.ts
import permutations from '../permutations'
describe('the permutation function', () => {
it('should handle the empty array case', () => {
it('should handle the a single element', () => {
expect(Array.from(permutations([['a', 'b', 'c']]))).toEqual([['a'], ['b'], ['c']])
View waitable.ts
// A class which turns a callback into something we can await on.
class Waitable {
public promise: Promise<null>
public callback: (err: any) => void
private resolve: () => void
private reject: (err) => void
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
You can’t perform that action at this time.