Skip to content

Instantly share code, notes, and snippets.

View alexanderson1993's full-sized avatar
🚀
Spaceshippin...

Alex Anderson alexanderson1993

🚀
Spaceshippin...
View GitHub Profile
@alexanderson1993
alexanderson1993 / makeEmailSender.ts
Created April 8, 2024 14:16
Fetch-based email sending using SES - perfect for Cloudflare and other non-Node.js runtimes
import { AwsClient } from "aws4fetch";
const sesEndpoint = "email.us-east-1.amazonaws.com";
export function makeEmailSender({
accessKeyId,
secretAccessKey,
defaultFromAddress,
}: {
accessKeyId: string;
@alexanderson1993
alexanderson1993 / createR2UploadHandler.ts
Created April 5, 2024 15:22
A Remix upload handler for R2 buckets
import type { UploadHandlerPart } from "@remix-run/cloudflare";
export class MaxPartSizeExceededError extends Error {
constructor(public field: string, public maxBytes: number) {
super(`Field "${field}" exceeded upload size of ${maxBytes} bytes.`);
}
}
export function createR2UploadHandler({
bucket,
@alexanderson1993
alexanderson1993 / README.md
Last active April 28, 2024 11:07
Prisma D1 Migration CLI
migrate.mov

A handy CLI for working with the new Cloudflare D1/Prisma integration. You can read about that here: https://blog.cloudflare.com/prisma-orm-and-d1

Getting Started

  • Install wrangler, Prisma, and the other dependencies
npm install prisma@latest @prisma/client@latest @prisma/adapter-d1
@alexanderson1993
alexanderson1993 / README.md
Last active April 2, 2024 04:52
Prisma-like Migrations and type safety with Kysely
@alexanderson1993
alexanderson1993 / AlertDialogProvider.tsx
Created April 2, 2023 19:07
A multi-purpose alert/confirm/prompt replacement built with shadcn/ui AlertDialog components.
"use client";
import * as React from "react";
import { Input } from "@/components/ui/Input";
import { Button } from "@/components/ui/Button";
import {
AlertDialog,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription,
@alexanderson1993
alexanderson1993 / CurrencyInput.tsx
Created July 29, 2022 13:12
A currency input field built with Chakra-UI
function CurrencyInput({
value,
onChange,
max,
}: {
value: number;
max: number;
onChange: (val: number) => void;
}) {
const [error, setError] = useState('');
@alexanderson1993
alexanderson1993 / countLines.ts
Created July 15, 2022 15:03
A tool for recursively counting the number of lines in each file in a directory
import fs from 'fs/promises';
console.time('Get file sizes');
const items = await fs.readdir('.');
const ignore = [
'_templates',
'.git',
'.github',
// This is a React component that loads and inlines an SVG image, making it easier to style
// with CSS. It renders an <img> first, and then renders the inline SVG once it's been loaded.
import {useState, useEffect, memo, ComponentPropsWithoutRef} from "react";
export const SVGImageLoader: React.FC<
{url: string} & ComponentPropsWithoutRef<"img">
> = memo(({url, alt, ...props}) => {
const [data, setData] = useState<string | null>(null);
useEffect(() => {
@alexanderson1993
alexanderson1993 / copyToClipboard.ts
Created January 28, 2021 21:43
A component that copies some text to the clipboard when it is clicked.
import * as React from "react";
const CopyToClipboard:React.FC<{text:string} & React.HTMLAttributes<HTMLButtonElement>> = ({text, ...props}) => {
const copyToClipboard = (event:React.MouseEvent<HTMLButtonElement>, str:string) => {
const el = Object.assign(document.createElement('textarea'),{value:str});
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
@alexanderson1993
alexanderson1993 / correct.ts
Created August 17, 2020 14:40
What not to do with proxies.
// Create a symbol for our proxy
let isProxy = Symbol("isProxy");
const handler = {
get(target, key) {
// Override access if we are checking if the object is already a proxy
if (key === isProxy) return true;
if (
// Don't wrap it again if the object is already a proxy