Skip to content

Instantly share code, notes, and snippets.

View xzec's full-sized avatar

Juraj Žec xzec

View GitHub Profile
const input = await Deno.readTextFile('input.txt')
const lines = input.split('\n')
type Direction = 'L' | 'U' | 'R' | 'D'
type Movement = [Direction, number]
type Vector2D = [x: number, y: number]
type Rope = Vector2D[]
const ROPE_LENGTH = 10
@xzec
xzec / asyncHandler.ts
Created December 3, 2023 19:10
Express.js asyncHandler + typing
import {
type NextFunction,
type Request,
type RequestHandler,
type Response,
} from 'express'
export const asyncHandler =
(
fun: (req: Request, res: Response, next: NextFunction) => Promise<void>,
@xzec
xzec / resolveAllSettled.ts
Last active September 28, 2025 07:03
const [errors, results] = resolveAllSettled(await Promise.allSettled(promises))
const resolveAllSettled = <T>(results: PromiseSettledResult<T>[]): [errors: string[], data: T[]] => {
const errors = results
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
.map(({ reason }) => {
if (reason instanceof Error) return reason.message
if (typeof reason === 'string') return reason
return 'undetected reason'
})
const data = results
@xzec
xzec / resolve.ts
Last active December 13, 2023 16:23
const [error, result] = await resolve(promise)
type Resolved<Data> = [undefined, Data] | [Error, undefined]
export const resolve = <Data>(promise: Promise<Data>): Promise<Resolved<Data>> =>
promise
.then((data): [undefined, Data] => [undefined, data])
.catch((error): [Error, undefined] => [error, undefined])
@xzec
xzec / filterAndTypePredicate.ts
Last active December 13, 2023 16:28
Array.prototype.filter() + type predicate
type Sensor = {
lastMeasuredValue?: number | null
}
const sensors: Sensor[] = []
// type of `values` is narrowed down to `number[]`
const values = sensors
.map((sensor) => sensor.lastMeasuredValue)
.filter((value): value is number => typeof value === 'number')
@xzec
xzec / resolveFetch.ts
Last active December 13, 2023 16:30
const [err, res] = await resolveFetch(fetch(url))
import resolve from './resolve' // https://gist.github.com/xzec/fac8ca82ce0e5cee41cf3d9769f9c9d0
const resolveFetch = (promise: Promise<Response>) =>
resolve(
promise.then((response) => {
if (response.ok) return response
throw new Error(`${response.status} ${response.statusText}`)
})
)
@xzec
xzec / isRegExpMatchArrayWithGroups.ts
Created January 3, 2024 13:04
Type guard for RegExp match with named capturing groups
type RegExpMatchArrayWithGroups<G extends string> = RegExpMatchArray & {
groups: Record<G, string> & Record<string, never>
}
const isRegExpMatchArrayWithGroups = <G extends string>(
match: RegExpMatchArray | null,
...groups: G[]
): match is RegExpMatchArrayWithGroups<G> => groups.every((g) => match?.groups !== undefined && g in match.groups)
// usage
@xzec
xzec / parametrize.ts
Created May 24, 2024 08:17
Appends search params to a URL
const parametrize = (url: string, params: ConstructorParameters<typeof URLSearchParams>[0]) => {
return `${url}?${new URLSearchParams(params)}`
}
@xzec
xzec / fibonacci.ts
Created September 8, 2024 19:57
Simple and readable Fibonacci sequence AsyncGenerator in Node.js
import { setTimeout } from 'node:timers/promises'
export async function* fibonacci(frequencyMs = 200) {
let a = 0n
let b = 1n
while (true) {
yield String(b)
b = a + b
a = b - a
@xzec
xzec / zodPrivateKeySchema.ts
Last active September 13, 2024 08:32
Zod schema to validate a private key in PEM format. Useful when validating private keys from environment variables, for instance. https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail#Format
import { z } from 'zod'
const privateKeySchema = z.object({
MY_PRIVATE_KEY: z
.string()
.regex(
/-----BEGIN PRIVATE KEY-----\s*\S[\s\S]*?\s*-----END PRIVATE KEY-----/,
'MY_PRIVATE_KEY must be a valid private key.',
)
.describe('Full contents of the private key used to sign/encrypt the thing.'),