Skip to content

Instantly share code, notes, and snippets.

View JamesBliss's full-sized avatar

James Bliss JamesBliss

View GitHub Profile
@JamesBliss
JamesBliss / stytch-next-auth.md
Last active March 7, 2025 14:27
The "I Really Don't Want to Pull My Hair Out" Guide to OIDC with Stytch + next-auth

Because I've done the hair pulling already (This is not bulletproof)

What Are We Doing Here?

Welcome to the frustrating world of authentication! This guide will walk you through implementing OpenID Connect (OIDC) authentication with Stytch and next-auth in your Next.js application.

Prerequisites:

  • "next-auth": "^5.0.0-beta.25" (Because living on the beta edge is how we roll)
  • "next": "15.2.0" (Might work earlier but I'm not testing that 🤷‍♂️)
@JamesBliss
JamesBliss / useFetch.ts
Created January 30, 2024 14:19 — forked from KristofferEriksson/useFetch.ts
A generic React fetch hook for API calls with caching, error handling, and refetch capability
import { useCallback, useEffect, useState } from "react";
type FetchState<T> = {
data: T | null;
isLoading: boolean;
error: Error | null;
isCached: boolean;
refetch: () => void;
};
@JamesBliss
JamesBliss / useCookie.ts
Created January 29, 2024 17:43 — forked from KristofferEriksson/useCookie.ts
A hook to easily read and update browser cookies. Plus, it auto-updates your component when cookie values change
import { useEffect, useState } from "react";
type UseCookieReturnType = {
cookie: string | undefined;
setCookie: (value: string, days?: number) => void;
};
const useCookie = (cookieName: string): UseCookieReturnType => {
const getCookie = (name: string): string | undefined => {
const value = `; ${document.cookie}`;
@JamesBliss
JamesBliss / gsap-eases.css
Created August 28, 2023 17:21 — forked from jh3y/gsap-eases.css
GreenSock eases with CSS linear()
:root {
--linear-in: linear(0, 1);
--linear-out: linear(0, 1);
--linear-in-out: linear(0, 1);
--power0-in: linear(0, 1);
--power0-out: linear(0, 1);
--power0-in-out: linear(0, 1);
--quad-in: linear( 0, 0.0039, 0.0156, 0.0352, 0.0625, 0.0977, 0.1407, 0.1914, 0.2499, 0.3164, 0.3906 62.5%, 0.5625, 0.7656, 1 );
--quad-out: linear( 0, 0.2342, 0.4374, 0.6093 37.49%, 0.6835, 0.7499, 0.8086, 0.8593, 0.9023, 0.9375, 0.9648, 0.9844, 0.9961, 1 );
--quad-in-out: linear( 0, 0.0027, 0.0106 7.29%, 0.0425, 0.0957, 0.1701 29.16%, 0.2477, 0.3401 41.23%, 0.5982 55.18%, 0.7044 61.56%, 0.7987, 0.875 75%, 0.9297, 0.9687, 0.9922, 1 );
@JamesBliss
JamesBliss / zod-optional-null.ts
Created August 11, 2023 08:22 — forked from ciiqr/zod-optional-null.ts
zod optional/nullable/nullish differences
// zod schema
z.object({
// valid if string or:
optional: z.string().optional(), // field not provided, or explicitly `undefined`
nullable: z.string().nullable(), // field explicitly `null`
nullish: z.string().nullish(), // field not provided, explicitly `null`, or explicitly `undefined`
});
// type
{
@JamesBliss
JamesBliss / safeParse.ts
Created August 7, 2023 12:47 — forked from gimenete/safeParse.ts
A wrapper around the fetch function that validates the response body against a Zod schema
import z from "zod";
export async function safeFetch<T>(
schema: z.Schema<T>,
input: RequestInfo,
init?: RequestInit
): Promise<T> {
const response = await fetch(input, init);
if (!response.ok) {
@JamesBliss
JamesBliss / collectionUpdate.ts
Created May 11, 2023 12:32 — forked from snorrees/collectionUpdate.ts
Sanity Connect custom handler. See requirements.md
import type {SanityClient} from '@sanity/client'
import {v5 as uuidv5} from 'uuid'
import {buildCollectionDocumentId, commitCollectionDocument} from './sanityOps'
import type {ShopifyDocumentCollection} from './storageTypes'
import {SHOPIFY_COLLECTION_DOCUMENT_TYPE, UUID_NAMESPACE_COLLECTIONS} from './constants'
import {DataSinkCollection} from './requestTypes'
import {idFromGid} from './requestHelpers'
@JamesBliss
JamesBliss / readme.md
Created February 8, 2022 12:02 — forked from benstr/readme.md
Gist Markdown Cheatsheet

#Heading 1 ##Heading 2 ###Heading 3 ####Heading 4 #####Heading 5 ######Heading 6


Paragraph

@JamesBliss
JamesBliss / memoizedHandlers.js
Created December 15, 2021 14:18 — forked from kyleshevlin/memoizedHandlers.js
Using React.useMemo to create a `handlers` object
// One of my new favorite React Hook patternms is to create handler
// functions for a custom hook using `React.useMemo` instead of
// `React.useCallback`, like so:
function useBool(initialState = false) {
const [state, setState] = React.useState(initialState)
// Instead of individual React.useCallbacks gathered into an object
// Let's memoize the whole object. Then, we can destructure the
// methods we need in our consuming component.
@JamesBliss
JamesBliss / linear-interpolation-functions.md
Created November 16, 2020 09:59
Linear Interpolation Functions

Linear Interpolation Functions

const lerp = (x, y, a) => x * (1 - a) + y * a;
const clamp = (a, min = 0, max = 1) => Math.min(max, Math.max(min, a));
const invlerp = (x, y, a) => clamp((a - x) / (y - x));
const range = (x1, y1, x2, y2, a) => lerp(x2, y2, invlerp(x1, y1, a));