Sign in

Chris Cook

@zirkelc.dev
327 followers 405 following 210 posts

software engineer at heart ❤️ co-founder of flyweight.io aws community builder

PostsRepliesMedia
Chris Cook @zirkelc.dev · 28/07/2025
TIL you can use `@entity.Attributes.Lambda.Function` to group messages from multiple different log groups. Useful when you need to analyze cold starts from many Lambdas with a single cloudwatch query.
010
Chris Cook @zirkelc.dev · 10/07/2025
Flow in a nutshell: 1️⃣ Lambda #1 uploads the HTML to S3 and queues requests 2️⃣ SQS FIFO for async processing and deduplication 3️⃣ Lambda #2 downloads HTML, converts to Markdown, extracts content via Bedrock and saves to Notion
100
Chris Cook @zirkelc.dev · 10/07/2025
Here's Lambdalet.AI - an AI-powered bookmarking and read-it-later service. It saves any page you're reading into your own Notion database — full text, fully searchable, zero fuss. I built this for the AWS Lambda Hackathon!
110
Chris Cook @zirkelc.dev · 18/06/2025
If your using JSONata instead of JSONPath for your AWS Step Function workflow, here's how you can flatten an array of arrays:
110
Chris Cook @zirkelc.dev · 18/03/2025
Found this TODO in my codebase 😄 If I make a PR, will @vitest.dev accept it? 👀
010
Chris Cook @zirkelc.dev · 02/02/2025
TIL `$*` captures all positional arguments into a space separated string You can abuse this for a Git alias to avoid typing the commit message in double quotes: `gc my commit message`
010
Chris Cook @zirkelc.dev · 23/01/2025
What if `expect(obj).toMatchPrompt("...")` was a thing It's probably a stupid idea, but I couldn't resist and quickly implemented @vitest.dev custom matcher
010
Chris Cook @zirkelc.dev · 18/01/2025
I love how you can use TypeScripts' unique symbols as a parking spot for types 👀 Here's a simple query helper function to attach the result type to an object and infer it back later I've shared a complete example on @dev.to: dev.to/zirkelc/uniq...
010
Chris Cook @zirkelc.dev · 16/01/2025
I noticed that Vercels' popular `ms` pkg for converting time units to milliseconds uses 365.25 as a multiplier for the days in a year. I know this is to account for leap years, but is that the right assumption to make here? Effectively this means that `ms(1y) != ms(365d)` without ppl knowing it
100
Chris Cook @zirkelc.dev · 15/01/2025
Inspired by React Query's `queryOptions()`, I made a little helper to add the type of the parameter and the return type to the query definition (yes, I know about ORM). The next step would be to use template literal types to parse the parameters and return type from the query string.
030
Chris Cook @zirkelc.dev · 12/01/2025
I released `aws-sigv4-sign` today. It contains the core logic for signing requests with AWS SigV4, but does not use the fetch API The question now is: if you use fetch, then use `aws-sigv4-fetch`. In all other cases (axios, got, ky, node:https...) use `aws-sigv4-sign` www.npmjs.com/package/aws-...
020
Chris Cook @zirkelc.dev · 10/01/2025
@arethetypeswrong doesn't support @pnpm.io `publishConfig` to override package.json export fields when using live types As workaround, we can run pnpm pack, extract the tarball name and pass it to @arethetypeswrong to check the types: `pnpm pack | tail -n1 | xargs attw` github.com/arethetypesw...
020
Chris Cook @zirkelc.dev · 04/01/2025
The length of the rest args acts like a discriminator of the signature. If the function is called with one parameter it's the first signature, two parameters for the second signature, and so on.
010
Chris Cook @zirkelc.dev · 04/01/2025
TypeScript Function Overloading I used to overload functions where I merge the different parameter names and types into one implementation signature like `startOrLength`. But it get's really messy with more than 2 params. The usage of rest args offers a really nice alternative. /
131
Chris Cook @zirkelc.dev · 02/01/2025
TIL: Vitest has a built-in option to suppress logs during tests. I usually spy on the logger/console object and mock the implementation to disable logging during tests. It turns out Vitest has `onConsoleLog` option to filter or even suppress logs. vitest.dev/config/#onco...
000
Chris Cook @zirkelc.dev · 23/12/2024
Looking forward to Vitest v3. I made my first contribution with a new matcher `expect.toBeOneOf()` to check for optional properties that can be undefined or null. main.vitest.dev/api/expect.h...
010
Chris Cook @zirkelc.dev · 23/12/2024
I really like the JS-DevTools/npm-publish action for publishing npm packages from a GitHub workflow. Just increment the package version and push it to GitHub and it will do the rest. github.com/JS-DevTools/...
010
Chris Cook @zirkelc.dev · 18/12/2024
I updated my snapshot plugin for Jest and Vitest Now you can replace or remove multiple properties at once using arrays or regex patterns in your snapshots. Perfect for handling dynamic values like auto-generated IDs or timestamps github.com/zirkelc/snap...
010
Chris Cook @zirkelc.dev · 16/12/2024
Good idea for a Cursor rule 🤓 Inspired by @tkdodo.eu article tkdodo.eu/blog/array-t...
081
Chris Cook @zirkelc.dev · 16/12/2024
TIL: Undici uses Math.random as boundary of the FormData body I'm working on unit tests for my AWS SignatureV4 fetch library. It tests several body types (string, Blob, Uint8, ...) but the FormData tests kept failing. Turns out every new Request generates a random number as separator in the body
010
Chris Cook @zirkelc.dev · 15/12/2024
Running a GitHub action workflow from a PR comment seems to be in high demand. Last year, I created a sample workflow and PR that has since received more than 300 comments from a hundred different people. github.com/zirkelc/gith... Maybe this is something that GitHub Actions should make easier
020
Chris Cook @zirkelc.dev · 14/12/2024
JSON unfortunately does not allow comments. The alternative *.jsonc (JSON with comments) is not widely accepted. For example, Biome.js accepts a biome.jsonc configuration. A workaround is to tell VSCode to treat certain files as JSON with comments. For example, turbo.json can be treated as *.jsonc
220
Chris Cook @zirkelc.dev · 13/12/2024
I updated my snapshot serializer plugin to be a bit more type safe. If the optional generic parameter T is specified, all possible keys of T are suggested for auto-completion and other keys show an error. github.com/zirkelc/snap...
010
Chris Cook @zirkelc.dev · 13/12/2024
It would be nice if there was a way to deep link into a web page, like on GitHub, where you can select any code and create a permalink. With web pages, we only have anchors if we're lucky. CSS selectors were possible, but they break when the layout changes.
120
Chris Cook @zirkelc.dev · 11/12/2024
If you are working with multiple git branches, you may have outdated dependencies because node modules are git ignored. A git diff for the lock file can check if npm dependencies were changed in a branch. Here is a simple post-merge git hook to automatically run npm install on git switch.
110
Chris Cook @zirkelc.dev · 07/12/2024
What's the fastest way to download a file from AWS S3? I built a @raycast.com script command to download any S3 URI in just a few clicks. It can even download entire buckets.
010
Chris Cook @zirkelc.dev · 06/12/2024
I built a small library to compile search queries for Shopify's GraphQL search syntax. It exports functions for comparisons (eq, gt, lt,...) and logic (and, or, not) to compose complex queries, and takes care of specifics (escaping, phrases,...). github.com/zirkelc/shop...
000
Chris Cook @zirkelc.dev · 06/12/2024
The amount of automation they put into the DefinitelyTyped repo is very impressive. I updated the TypeScript definitions for an npm package yesterday and received a nice reply from the typescript-bot. Whatever that's suppose to mean 😅
010
Chris Cook @zirkelc.dev · 05/12/2024
It seems like many people don't know that you can debug any Javascript file in VSCode without any extra extension. It works with React. It works with TypeScript. It works with any test runner. Create a .vscode/launch.json and use `type: node-terminal`.
150
Chris Cook @zirkelc.dev · 03/12/2024
Here's one of the most valuable resources for web scraping: Chrome's runtime flags This spreadsheet contains all command line flags for Chrome with descriptions and their library support (Puppeteer, Playwright,...). I found this gem in an official Chrome repo. docs.google.com/spreadsheets...
100
Chris Cook @zirkelc.dev · 01/12/2024
I like to build local CLIs for my monorepo to automate build and deploy tasks that require more than just a few commands executed as npm scripts. By combining pnpm, commander.js and tsx, I can create executable programs in Typescript: ./cli <command> All the magic is in the shebang.
070
Chris Cook @zirkelc.dev · 30/11/2024
I am this much old.
110
Chris Cook @zirkelc.dev · 28/11/2024
In a list of possible locales like ['de', 'de-DE', 'de-CH', 'de-AT', ...], I need to find the best fit for a given locale like 'de'. If no direct match for 'de' is available, I need the next best fit. For 'de' it would be 'de-DE'. I wanted to build myself but then I found Intl.Locale.maximize() 🤯
100
Chris Cook @zirkelc.dev · 22/11/2024
`middy-store` works with Stores. A Store is any service that allows you to store and load arbitrary payloads, like Amazon S3 or other persistent storage systems. You can even work with multiple Stores which are backed by different underlying services.
100
Chris Cook @zirkelc.dev · 22/11/2024
I have built `middy-store` for this purpose. It's a middleware for Lambda that runs before and after the handler. If the handlers' output exceeds a configurable limit, it saves it to S3 and replaces it with a reference. On the next Lambda, it loads it from S3 and converts it back into an object.
100
Chris Cook @zirkelc.dev · 22/11/2024
The feature I miss most with AWS Step Functions: not having to care about the size of a States' output. The payload should be saved to S3 if the output size is too big (e.g. > 256kb). The next Task should load the payload from S3 again. Ideally, this process should happen automatically.
100
Chris Cook @zirkelc.dev · 17/11/2024
I'm looking for TypeScript `Autocomplete<T>` type that suggests possible literals for a given type `T`, recursively expanding keys for nested objects. Here's what I have so far: www.typescriptlang.org/play/?ssl=13... Any suggestions ti make it more robust?
110
Chris Cook @zirkelc.dev · 12/11/2024
The fastest way to launch ChatGPT from the browser: Add a new search to Chrome with a shortcut @gpt and URL chatgpt.com?q=%s. Then type @gpt followed by your message into the omnibox and hit enter.
000
Chris Cook @zirkelc.dev · 12/11/2024
I often use snapshots in my unit tests, but dynamic values such as dates or auto-generated IDs break snapshots. If mocking these values is not an option, e.g. due to side effects, then you can replace or remove the values from the snapshot at serialization. github.com/zirkelc/snap...
000
Chris Cook @zirkelc.dev · 12/11/2024
I just found out how Docker contexts lets you run Docker commands over SSH without login into the remote machine in a terminal. The user, host and private key can be added to ~/.ssh/config with an alias to make the SSH url even shorter. blog.mikesir87.io/2019/08/usin...
000
Chris Cook @zirkelc.dev · 06/11/2024
Hey @colinhacks.com in some other post you mentioned how to extend Zod. I used it to add an `empty()` onto the ZodString like `z.string().email().empty()` Is there any way to extend ZodOptional<z.ZodString> so I can use something like `z.string().email().optional().empty()`?
100
Chris Cook @zirkelc.dev · 06/11/2024
I was finally able replace most of my AWS DynamoDB mocks with actual database calls by using @localstack.cloud with testcontainers. This combination allows to start the container inside the actual test case, without the need for a pre-test script to start and stop the container.
110
Chris Cook @zirkelc.dev · 03/11/2024
I've been doing web development for a long time, but I just now found out that you can turn any HTML element into input element by using the `contenteditable` attribute. No more complicated JS logic to make a textarea fit the height of its content. developer.mozilla.org/en-US/docs/W...
000