Skip to content

Instantly share code, notes, and snippets.

View christophemarois's full-sized avatar

Christophe Marois christophemarois

  • Doximity
  • Montreal
View GitHub Profile
@christophemarois
christophemarois / zod-unique-array.ts
Created September 29, 2023 23:04
Zod Unique Array
/** 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>()
@christophemarois
christophemarois / git_list_branch_changes.sh
Created September 15, 2023 12:57
List branch changes in git
# 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
}
@christophemarois
christophemarois / node-cli-args-parse.ts
Created August 9, 2023 14:15
Native parsing for CLI args in node
import { parseArgs } from 'node:util'
const args = parseArgs({
options: { env: { type: 'string' }, dryRun: { type: 'boolean' } },
})
@christophemarois
christophemarois / node-inspector.ts
Last active July 12, 2023 18:24
Boot up a node inspector anywhere
// will act --inspect-brk, but only when evaluated
// works inside the main thread, a worker thread
// also works with typescript sources, built-in support in tsx
require('node:inspector').open(undefined, undefined, true)
@christophemarois
christophemarois / streamWretchResponseToFile.ts
Last active July 5, 2023 19:31
Stream a wretch response directly to a file in node.js
import wretch, { WretchResponse } from 'wretch'
import fs from 'node:fs'
async function streamWretchResponseToFile(
res: WretchResponse,
writable: fs.WriteStream,
) {
if (!res.body) {
throw new Error('Response body is null')
}
@christophemarois
christophemarois / zMapKeys.ts
Last active June 16, 2023 21:26
zMapKeys.ts
// Type inference does not work yet
export function zMapKeys<
Shape extends z.ZodRawShape,
T extends z.ZodObject<Shape>,
Key extends keyof Shape,
MapFn extends <T extends Key>(v: Shape[T], k: T) => PropertyKey,
>(schema: T, renameMap: Record<Key, PropertyKey | MapFn>) {
const keys = Object.keys(schema.shape) as Key[]
return schema.transform((input) => {
let output: Record<PropertyKey, any> = {}
@christophemarois
christophemarois / postgres-cls.md
Created April 12, 2023 16:13
Whitelist-based CLS (column level security) for Postgres

With the following generic trigger function:

CREATE OR REPLACE FUNCTION allow_updating_only()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
DECLARE
  whitelist TEXT[] := TG_ARGV::TEXT[];
  schema_table TEXT;
@christophemarois
christophemarois / local-caddy.md
Created March 23, 2023 17:04
Run a local HTTPS server

Use Caddy (brew install caddy) to run localhost sites with custom addresses and https certificates.

  1. Run caddy reverse-proxy --from site.localhost --to localhost:3000
  2. Visit https://site.localhost/

For a more stable config, create a Caddyfile

site.localhost {
 reverse_proxy localhost:3000
@christophemarois
christophemarois / git-remove-file.md
Last active March 18, 2023 19:39
Remove a file from git

Remove a file from git

Accidentally committed a 4GB file and GitHub (rightly) doesn't let you push? Commited a .env with your social insurance number?

  1. Back up the entire repo
  2. Run bfg --delete-files [filenames...] (brew install bfg)
  3. Follow instructions
@christophemarois
christophemarois / docker-cheatsheet.md
Last active September 21, 2023 15:49
Docker Cheatsheet

Run a local Dockerfile with a local .env file

docker build \

Show complete log

--progress=plain \

Nested dockerfile, useful for monorepos when we want to preserve CWD