Cloudflare is a better and free ngrok. With a domain that uses it, set it up like this
- Setup a tunnel
cloudflared tunnel login
cloudflared tunnel create test
cloudflared tunnel route dns test test.christophemarois.com
// adapted from https://jsr.io/@backend/safe-assignment | |
type WithErrResultPlain<T> = [Error, null] | [null, T] | |
type WithErrResult<T> = T extends Promise<infer U> | |
? Promise<WithErrResultPlain<U>> | |
: WithErrResultPlain<T> | |
type WithErr<T> = T extends Promise<unknown> | |
? WithErrResult<T> | |
: T extends () => infer U |
/** Typed context creation helper | |
* @example | |
* export const [useLevel, LevelProvider] = createTypedContext<{ level: number }>('LevelContext') | |
*/ | |
export function createTypedContext<T>(name: string) { | |
const Context = createContext<T | null>(null) | |
function useEnsuredContext() { | |
const ctx = useContext(Context) | |
if (ctx === null) { |
/* eslint-disable no-console */ | |
/** | |
* Represents a deeply readonly version of a type, including nested objects, | |
* arrays, sets, and maps. | |
* @template T - The type to make deeply readonly. | |
*/ | |
export type DeepReadonly<T> = T extends (infer R)[] | |
? ReadonlyArray<DeepReadonly<R>> | |
: T extends Set<infer R> | |
? ReadonlySet<DeepReadonly<R>> |
/** Create a wrapped AbortController that is aborted when a SIGINT/SIGTERM is received. | |
* Supports auto-unregistering via explicit resource management. | |
* | |
* @example | |
* using shutdownSignal = new ShutdownSignal() | |
* shutdownSignal.throwIfAborted() | |
* | |
* // or | |
* const shutdownSignal = new ShutdownSignal() | |
* try { shutdownSignal.throwIfAborted() } finally { shutdownSignal.unregister() } |
Cloudflare is a better and free ngrok. With a domain that uses it, set it up like this
cloudflared tunnel login
cloudflared tunnel create test
cloudflared tunnel route dns test test.christophemarois.com
/** Transform the password part of a connection string URL into [redacted]. | |
* Useful for logging. */ | |
export function redactPasswordFromUrl(url: string) { | |
return url.replace(/^([^:]+):\/\/([^:]*):([^@]+)@/, '$1://$2:[redacted]@') | |
} |
curl -s https://raw.githubusercontent.com/midnightmonster/icloud-calendar-urls/master/icloud_calendar_urls | bash
Monitor in Node (PerformanceObserver is not yet implemented in Bun.
in bun 1.0.3)
import { collectDefaultMetrics, register } from 'prom-client'
if (req.method === 'GET' && pathname === '/metrics/') {
return new Response(await register.metrics(), {
headers: {
'Content-Type': register.contentType,
},
/** Array where are elements are expected to be unique by a custom key */ | |
export function zUniqueArray< | |
ArrSchema extends z.ZodArray<z.ZodTypeAny, 'many'>, | |
UniqueVal, | |
>( | |
uniqueBy: (item: z.infer<ArrSchema>[number]) => UniqueVal, | |
schema: ArrSchema, | |
) { | |
return schema.superRefine((items, ctx) => { | |
const seen = new Set<UniqueVal>() |
# list changed files in a branch compared to its base branch | |
# usage: git_list_branch_changes [base_branch?] | xargs echo | |
function git_list_branch_changes { | |
local BASE_BRANCH="${1:-main}" | |
(git diff --diff-filter=MA --name-only $BASE_BRANCH... && git status --short --porcelain | awk '{print $2}') | sort -u | |
} |