Skip to content

Instantly share code, notes, and snippets.

View donaldpipowitch's full-sized avatar

Donald Pipowitch donaldpipowitch

View GitHub Profile
@donaldpipowitch
donaldpipowitch / README.md
Last active November 13, 2023 22:08
Rewrite relative import paths with a codemod

⚠️ This is for an internal project, but shared publicly as a reference for myself.

If you want to have a general introduction how to write such a codemod have a look at this Gist from me.

What to do?

Place the usage.js and prettiermod.js in the root of the project. Run:

$ pnpm add globby@^11.0.0 @babel/traverse
@donaldpipowitch
donaldpipowitch / README.md
Last active January 26, 2023 10:14
Create a codemod with Prettier and Babel

Every now and then I'd like to apply a so called codemod to my a codebase. A codemod is a piece of code which modifies other code. Very often this is done by running some transformation on the abstract syntax tree (AST).

Whenever I need to do this I look for "What is the best way to apply a codemod on my TS code base right now?", because when I only do this every couple of month I either have forgotten about how to do it or tools have changed and my old way stopped working... or both. Surprisingly every time I search for that I found the existing tools bloated or quirky or not matching my workflow.

As I already use Babel to compile our source code I would like to create a Babel plugin which transforms my code. Sadly Babel alone is not good in preserving whitespace and formatting. Thankfully I use Prettier for that and because Prettier uses Babel internally I can create a Babel visitor to transform my source code.

The actually easiest and _most r

@donaldpipowitch
donaldpipowitch / get-nice-upper-bound.ts
Created November 13, 2020 07:05
Nice upper bound (e.g. for charts, ticks, scales)
function getNiceUpperBound(value: number) {
const zeroCount = String(Math.round(value)).length - 1;
const factor = Math.pow(10, zeroCount);
return Math.ceil(value / factor) * factor;
}
const upperBound = getNiceUpperBound(3464634); // 4000000
@donaldpipowitch
donaldpipowitch / use-stable-memo.ts
Last active October 15, 2020 08:12
useStableMemo
import { DependencyList, useState, useEffect, useRef } from 'react';
// use this instead of useMemo of you need a stable value
// see https://twitter.com/0xca0a/status/1314326386555924480
export function useStableMemo<T>(factory: () => T, deps: DependencyList): T {
const [value, setValue] = useState<T>(factory);
const firstRun = useRef(true);
useEffect(
() => {
@donaldpipowitch
donaldpipowitch / use-location-state.ts
Created July 22, 2020 06:23
useLocationState: a glorified location.state for React Router as a hook
import { useState, useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { useSessionStorage } from './use-storage'; // see https://gist.github.com/donaldpipowitch/7310d7b9e4b6d467134c425e8732adc6
type UseLocationStateOptions<T> = {
defaultValue?: T;
scope?: string;
filter?: (value: T) => boolean;
};
@donaldpipowitch
donaldpipowitch / mocked-storage.tsx
Last active July 22, 2020 13:10
useSessionStorage and useLocalStorage for easy mocking - similar to MemoryRouter in react-router, but for storage
import React, { FC, useMemo } from 'react';
import {
LocalStorageProvider,
SessionStorageProvider,
} from './use-storage';
// this is just a dumb mock of the storage interface
class MemoryStorage implements Storage {
private data: Record<string, string> = {};
@donaldpipowitch
donaldpipowitch / index.js
Created July 7, 2020 07:38
ESLint rule to check for round brackets in Jest `test` names. (Doesn't play nicely with --testNamePattern without escaping.)
// @ts-check
/** @type {import("eslint").Rule.RuleModule} */
const rule = {
meta: {
docs: {
description: `If you use a Jest test name like "hello (world)" you can't run \`$ jest -t "hello (world)"\` to select this test.`,
},
fixable: 'code',
},
@donaldpipowitch
donaldpipowitch / index.js
Last active July 7, 2020 07:36
ESLint rule to check for duplicated exported names.
// @ts-check
/** @type {import("eslint").Rule.RuleModule} */
const rule = {
meta: {
docs: {
description: `You can export a type and a value with the same name in the same file, but that confuses refactoring tools.`,
},
},
create(context) {
@donaldpipowitch
donaldpipowitch / README.md
Created July 1, 2020 13:17
Cheat Sheet for various Brackets

Know your brackets!

  ( ) – parentheses, round brackets, first brackets
  { } – braces, curly brackets, second brackets, moustache brackets 👨🏻
  [ ] – square brackets, third brackets
  ⟨ ⟩ - angle brackets (aka. _not_ less-than/greater-than signs 👀)
  ‹ › - angle quotes (aka. _not_ less-than/greater-than signs 👀)
  < > - less-than/greater-than signs
@donaldpipowitch
donaldpipowitch / index.tsx
Created June 27, 2020 19:46
Example how to use 'amazon-cognito-identity-js'
import {
CognitoUserPool,
CognitoUserAttribute,
CognitoUser,
AuthenticationDetails,
CognitoUserSession,
CodeDeliveryDetails,
} from 'amazon-cognito-identity-js';
import React, { FC, useState } from 'react';