1
0
mirror of https://github.com/jbranchaud/til synced 2026-01-15 21:18:02 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
sandeep singh negi
4db0017665 Merge cea4ffc0a3 into 0b994346fe 2024-03-11 12:56:12 -07:00
32 changed files with 1 additions and 1100 deletions

View File

@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
_1427 TILs and counting..._
_1396 TILs and counting..._
---
@@ -41,7 +41,6 @@ _1427 TILs and counting..._
* [jq](#jq)
* [Kitty](#kitty)
* [Linux](#linux)
* [LLM](#llm)
* [Mac](#mac)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
@@ -99,7 +98,6 @@ _1427 TILs and counting..._
### Brew
- [Configure Brew Environment Variables](brew/configure-brew-environment-variables.md)
- [List All Services Managed By Brew](brew/list-all-services-managed-by-brew.md)
### Chrome
@@ -261,7 +259,6 @@ _1427 TILs and counting..._
- [Accessing a Lost Commit](git/accessing-a-lost-commit.md)
- [Add A Range Of Filename To gitignore](git/add-a-range-of-filenames-to-gitignore.md)
- [Add Only Tracked Files From A Directory](git/add-only-tracked-files-from-a-directory.md)
- [Amend Author Of Previous Commit](git/amend-author-of-previous-commit.md)
- [Auto-Squash Those Fixup Commits](git/auto-squash-those-fixup-commits.md)
- [Caching Credentials](git/caching-credentials.md)
@@ -321,7 +318,6 @@ _1427 TILs and counting..._
- [Quicker Commit Fixes With The Fixup Flag](git/quicker-commit-fixes-with-the-fixup-flag.md)
- [Rebase Commits With An Arbitrary Command](git/rebase-commits-with-an-arbitrary-command.md)
- [Reference A Commit Via Commit Message Pattern Matching](git/reference-a-commit-via-commit-message-pattern-matching.md)
- [Remove Untracked Files From A Directory](git/remove-untracked-files-from-a-directory.md)
- [Rename A Remote](git/rename-a-remote.md)
- [Renaming A Branch](git/renaming-a-branch.md)
- [Resetting A Reset](git/resetting-a-reset.md)
@@ -401,7 +397,6 @@ _1427 TILs and counting..._
- [Adding Alt Text To An Image](html/adding-alt-text-to-an-image.md)
- [Determine Which Button Submitted The Form](html/determine-which-button-submitted-the-form.md)
- [Disable Auto-Completion For A Form Input](html/disable-auto-completion-for-a-form-input.md)
- [Make Elements Non-Interactive With Inert](html/make-elements-non-interactive-with-inert.md)
- [Prevent Search Engines From Indexing A Page](html/prevent-search-engines-from-indexing-a-page.md)
- [Render Text As Superscript](html/render-text-as-superscript.md)
- [Submit A Form With A Button Outside The Form](html/submit-a-form-with-a-button-outside-the-form.md)
@@ -412,7 +407,6 @@ _1427 TILs and counting..._
### Inngest
- [Ensure Lookup Can Be Retried](inngest/ensure-lookup-can-be-retried.md)
- [Exit Function Early Without Retries](inngest/exit-function-early-without-retries.md)
### Internet
@@ -442,7 +436,6 @@ _1427 TILs and counting..._
- [Computed Property Names In ES6](javascript/computed-property-names-in-es6.md)
- [Conditionally Include Pairs In An Object](javascript/conditionally-include-pairs-in-an-object.md)
- [Configure Jest To Run A Test Setup File](javascript/configure-jest-to-run-a-test-setup-file.md)
- [Convert Seconds To Date Object](javascript/convert-seconds-to-date-object.md)
- [Create A Cancelable Promise With PCancelable](javascript/create-a-cancelable-promise-with-pcancelable.md)
- [Create An Array Containing 1 To N](javascript/create-an-array-containing-1-to-n.md)
- [Create An Object With No Properties](javascript/create-an-object-with-no-properties.md)
@@ -559,11 +552,6 @@ _1427 TILs and counting..._
- [Show Used And Available System Memory](linux/show-used-and-available-system-memory.md)
- [Upgrading Ubuntu](linux/upgrading-ubuntu.md)
### LLM
- [Send cURL To Claude Text Completion API](llm/send-curl-to-claude-text-completion-api.md)
- [Use The llm CLI With Claude Models](llm/use-the-llm-cli-with-claude-models.md)
### Mac
- [Access All Screen And Video Capture Options](mac/access-all-screen-and-video-capture-options.md)
@@ -633,10 +621,8 @@ _1427 TILs and counting..._
- [Create Files And Directories For Dynamic Routes](nextjs/create-files-and-directories-for-dynamic-routes.md)
- [Define URL Redirects In The Next Config](nextjs/define-url-redirects-in-the-next-config.md)
- [Fetch Does Not Work In API Serverless Function](nextjs/fetch-does-not-work-in-api-serverless-function.md)
- [Make Environment Variable Publicly Available](nextjs/make-environment-variable-publicly-available.md)
- [Match Middleware On Groups Of Paths](nextjs/match-middleware-on-groups-of-paths.md)
- [Precedence Of Dot Env Files](nextjs/precedence-of-dot-env-files.md)
- [Push A Route With A URL Object](nextjs/push-a-route-with-a-url-object.md)
- [Redirect An Unauthorized User](nextjs/redirect-an-unauthorized-user.md)
- [Remove A Query Param From The URL](nextjs/remove-a-query-param-from-the-url.md)
@@ -675,7 +661,6 @@ _1427 TILs and counting..._
- [Capitalize All The Words](postgres/capitalize-all-the-words.md)
- [Change The Current Directory For psql](postgres/change-the-current-directory-for-psql.md)
- [Change The Owner Of A Sequence](postgres/change-the-owner-of-a-sequence.md)
- [Check If Clusters Are Upgrade Compatible](postgres/check-if-clusters-are-upgrade-compatible.md)
- [Check If The Local Server Is Running](postgres/check-if-the-local-server-is-running.md)
- [Check If User Role Exists For Database](postgres/check-if-user-role-exists-for-database.md)
- [Check Table For Any Oprhaned Records](postgres/check-table-for-any-orphaned-records.md)
@@ -692,7 +677,6 @@ _1427 TILs and counting..._
- [Count How Many Records There Are Of Each Type](postgres/count-how-many-records-there-are-of-each-type.md)
- [Count Records By Type](postgres/count-records-by-type.md)
- [Count The Number Of Trues In An Aggregate Query](postgres/count-the-number-of-trues-in-an-aggregate-query.md)
- [Create A Cluster In A Specific Data Directory](postgres/create-a-cluster-in-a-specific-data-directory.md)
- [Create A Composite Primary Key](postgres/create-a-composite-primary-key.md)
- [Create A Table From The Structure Of Another](postgres/create-a-table-from-the-structure-of-another.md)
- [Create An Index Across Two Columns](postgres/create-an-index-across-two-columns.md)
@@ -740,7 +724,6 @@ _1427 TILs and counting..._
- [Group By The Result Of A Function Call](postgres/group-by-the-result-of-a-function-call.md)
- [Idempotent Inserts](postgres/idempotent-inserts.md)
- [Include All Queries In The Log File](postgres/include-all-queries-in-the-log-file.md)
- [Include Columns In A Covering Index](postgres/include-columns-in-a-covering-index.md)
- [Include Multiple Tables In A pg_dump](postgres/include-multiple-tables-in-a-pg-dump.md)
- [Insert A Bunch Of Records With Generate Series](postgres/insert-a-bunch-of-records-with-generate-series.md)
- [Insert Just The Defaults](postgres/insert-just-the-defaults.md)
@@ -833,7 +816,6 @@ _1427 TILs and counting..._
- [Access Instance Variables](python/access-instance-variables.md)
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
- [Test A Function With Pytest](python/test-a-function-with-pytest.md)
- [Use pipx To Install End User Apps](python/use-pipx-to-install-end-user-apps.md)
### Rails
@@ -894,7 +876,6 @@ _1427 TILs and counting..._
- [Get ActiveRecord Attribute Directly From Database](rails/get-active-record-attribute-directly-from-database.md)
- [Get An Array Of Values From The Database](rails/get-an-array-of-values-from-the-database.md)
- [Get An Empty ActiveRecord Relation](rails/get-an-empty-activerecord-relation.md)
- [Get Formatted UTC Offset Value](rails/get-formatted-utc-offset-value.md)
- [Get Help With A Rails App Update](rails/get-help-with-a-rails-app-update.md)
- [Get The Column Names For A Model](rails/get-the-column-names-for-a-model.md)
- [Get The Current Time](rails/get-the-current-time.md)
@@ -910,7 +891,6 @@ _1427 TILs and counting..._
- [Load A File When Starting Rails Console](rails/load-a-file-when-starting-rails-console.md)
- [Load Records In Batches With find_each](rails/load-records-in-batches-with-find-each.md)
- [Log SQL Queries Executed By ActiveRecord](rails/log-sql-queries-executed-by-activerecord.md)
- [Look Up Time Zone Info For Identifier](rails/look-up-time-zone-info-for-identifier.md)
- [Mark A Migration As Irreversible](rails/mark-a-migration-as-irreversible.md)
- [Make A String Attribute Easy To Inquire About](rails/make-a-string-attribute-easy-to-inquire-about.md)
- [Make ActionMailer Synchronous In Test](rails/make-action-mailer-synchronous-in-test.md)
@@ -1107,7 +1087,6 @@ _1427 TILs and counting..._
- [Add Progress Reporting To Long-Running Script](ruby/add-progress-reporting-to-long-running-script.md)
- [Are They All True?](ruby/are-they-all-true.md)
- [Assert About An Object's Attributes With RSpec](ruby/assert-about-an-objects-attributes-with-rspec.md)
- [Audit Your Ruby Project For Any CVEs](ruby/audit-your-ruby-project-for-any-cves.md)
- [Assoc For Hashes](ruby/assoc-for-hashes.md)
- [Block Comments](ruby/block-comments.md)
- [Build HTTP And HTTPS URLs](ruby/build-http-and-https-urls.md)
@@ -1131,7 +1110,6 @@ _1427 TILs and counting..._
- [Defaulting To Frozen String Literals](ruby/defaulting-to-frozen-string-literals.md)
- [Define A Custom RSpec Matcher](ruby/define-a-custom-rspec-matcher.md)
- [Define A Method On A Struct](ruby/define-a-method-on-a-struct.md)
- [Define Multiline Strings With Heredocs](ruby/define-multiline-strings-with-heredocs.md)
- [Destructure The First Item From An Array](ruby/destructure-the-first-item-from-an-array.md)
- [Destructuring Arrays In Blocks](ruby/destructuring-arrays-in-blocks.md)
- [Disassemble Some Codes](ruby/disassemble-some-codes.md)
@@ -1150,12 +1128,10 @@ _1427 TILs and counting..._
- [Fetch Warns About Superseding Block Argument](ruby/fetch-warns-about-superseding-block-argument.md)
- [Find The Min And Max With A Single Call](ruby/find-the-min-and-max-with-a-single-call.md)
- [Finding The Source of Ruby Methods](ruby/finding-the-source-of-ruby-methods.md)
- [Format A Hash Into A String Template](ruby/format-a-hash-into-a-string-template.md)
- [Generate A Signed JWT Token](ruby/generate-a-signed-jwt-token.md)
- [Generate Ruby Version And Gemset Files With RVM](ruby/generate-ruby-version-and-gemset-files-with-rvm.md)
- [Get Info About Your RubyGems Environment](ruby/get-info-about-your-ruby-gems-environment.md)
- [Get The Output Of Running A System Program](ruby/get-the-output-of-running-a-system-program.md)
- [Get UTC Offset For Different Time Zones](ruby/get-utc-offset-for-different-time-zones.md)
- [Identify Outdated Gems](ruby/identify-outdated-gems.md)
- [If You Detect None](ruby/if-you-detect-none.md)
- [Iterate With An Offset Index](ruby/iterate-with-an-offset-index.md)
@@ -1211,7 +1187,6 @@ _1427 TILs and counting..._
- [Single And Double Quoted String Notation](ruby/single-and-double-quoted-string-notation.md)
- [Skip Specific CVEs When Auditing Your Bundle](ruby/skip-specific-cves-when-auditing-your-bundle.md)
- [Specify Dependencies For A Rake Task](ruby/specify-dependencies-for-a-rake-task.md)
- [Specify How Random Array#sample Is](ruby/specify-how-random-array-sample-is.md)
- [Split A Float Into Its Integer And Decimal](ruby/split-a-float-into-its-integer-and-decimal.md)
- [Squeeze Out The Extra Space](ruby/squeeze-out-the-extra-space.md)
- [String Interpolation With Instance Variables](ruby/string-interpolation-with-instance-variables.md)
@@ -1376,9 +1351,7 @@ _1427 TILs and counting..._
- [Fix Unlinked Node Binaries With asdf](unix/fix-unlinked-node-binaries-with-asdf.md)
- [Forward Multiple Ports Over SSH](unix/forward-multiple-ports-over-ssh.md)
- [Generate A SAML Key And Certificate Pair](unix/generate-a-saml-key-and-certificate-pair.md)
- [Generate Base64 Encoding Without Newlines](unix/generate-base64-encoding-without-newlines.md)
- [Generate Random 20-Character Hex String](unix/generate-random-20-character-hex-string.md)
- [Get A List Of Locales On Your System](unix/get-a-list-of-locales-on-your-system.md)
- [Get Matching Filenames As Output From Grep](unix/get-matching-filenames-as-output-from-grep.md)
- [Get The Unix Timestamp](unix/get-the-unix-timestamp.md)
- [Global Substitution On The Previous Command](unix/global-substitution-on-the-previous-command.md)
@@ -1390,7 +1363,6 @@ _1427 TILs and counting..._
- [Hexdump A Compiled File](unix/hexdump-a-compiled-file.md)
- [Ignore A Directory During ripgrep Search](unix/ignore-a-directory-during-ripgrep-search.md)
- [Ignore The Alias When Running A Command](unix/ignore-the-alias-when-running-a-command.md)
- [Include Ignore Files In Ripgrep Search](unix/include-ignore-files-in-ripgrep-search.md)
- [Interactively Browse Available Node Versions](unix/interactively-browse-availabile-node-versions.md)
- [Interactively Switch asdf Package Versions](unix/interactively-switch-asdf-package-versions.md)
- [Jump To The Ends Of Your Shell History](unix/jump-to-the-ends-of-your-shell-history.md)
@@ -1400,7 +1372,6 @@ _1427 TILs and counting..._
- [Less With Style](unix/less-with-style.md)
- [List All The Enabled ZSH Options](unix/list-all-the-enabled-zsh-options.md)
- [List All Users](unix/list-all-users.md)
- [List Files In A Single Column](unix/list-files-in-a-single-column.md)
- [List Files Ordered By Modification Date](unix/list-files-ordered-by-modification-date.md)
- [List Names Of Files With Matches](unix/list-names-of-files-with-matches.md)
- [List Of Sessions To A Machine](unix/list-of-sessions-to-a-machine.md)
@@ -1419,7 +1390,6 @@ _1427 TILs and counting..._
- [Partial String Matching In Bash Scripts](unix/partial-string-matching-in-bash-scripts.md)
- [PID Of The Current Shell](unix/pid-of-the-current-shell.md)
- [Print A Range Of Lines For A File With Bat](unix/print-a-range-of-lines-for-a-file-with-bat.md)
- [Print DateTime Represented By Unix Timestamp](unix/print-datetime-represented-by-unix-timestamp.md)
- [Print Milliseconds In Human-Readable Format](unix/print-milliseconds-in-human-readable-format.md)
- [Print Out Files In Reverse](unix/print-out-files-in-reverse.md)
- [Print The Current Date In Human-Readable Format](unix/print-the-current-date-in-human-readable-format.md)
@@ -1450,7 +1420,6 @@ _1427 TILs and counting..._
- [Tell direnv To Load The Env File](unix/tell-direnv-to-load-the-env-file.md)
- [Touch Access And Modify Times Individually](unix/touch-access-and-modify-times-individually.md)
- [Undo Some Command Line Editing](unix/undo-some-command-line-editing.md)
- [Unrestrict Where ripgrep Searches](unix/unrestrict-where-ripgrep-searches.md)
- [Update Package Versions Known By asdf Plugin](unix/update-package-versions-known-by-asdf-plugin.md)
- [Use fzf To Change Directories](unix/use-fzf-to-change-directories.md)
- [Use Regex Pattern Matching With Grep](unix/use-regex-pattern-matching-with-grep.md)
@@ -1633,12 +1602,10 @@ _1427 TILs and counting..._
- [Add The VSCode CLI To Your Path](vscode/add-the-vscode-cli-to-your-path.md)
- [Advance Through Search Results](vscode/advance-through-search-results.md)
- [Enable Breadcrumbs For Version 1.26 Release](vscode/enable-breadcrumbs-for-version-126-release.md)
- [Find The Location Of User Settings JSON File](vscode/find-the-location-of-user-settings-json-file.md)
- [Open An Integrated Terminal Window](vscode/open-an-integrated-terminal-window.md)
- [Pop Open The Quick Fix Window](vscode/pop-open-the-quick-fix-window.md)
- [Step Through Project-Wide Search Results](vscode/step-through-project-wide-search-results.md)
- [Toggle Between Terminals](vscode/toggle-between-terminals.md)
- [Turn Off Display Of Tabs For Files](vscode/turn-off-display-of-tabs-for-files.md)
### Webpack
@@ -1650,8 +1617,6 @@ _1427 TILs and counting..._
### Workflow
- [Add Subtitles To Existing Mux Video Asset](workflow/add-subtitles-to-existing-mux-video-asset.md)
- [Access 1Password Credential From CLI](workflow/access-1password-credential-from-cli.md)
- [Change Window Name In iTerm](workflow/change-window-name-in-iterm.md)
- [Convert An ePub Document To PDF On Mac](workflow/convert-an-epub-document-to-pdf-on-mac.md)
- [Create A Local Sanity Dataset Backup](workflow/create-a-local-sanity-dataset-backup.md)

View File

@@ -1,28 +0,0 @@
# List All Services Managed By Brew
Daemonized services, such as PostgreSQL, can be installed and managed with
Homebrew. Under the hood `brew` uses `launchctl` on Mac to manage these
services — i.e. starting, restarting, and stopping them.
Assuming you've already installed some services, you can run `brew services
list` to see what services there are and what their current status is.
```bash
$ brew services list
Name Status User File
mailhog none
mysql none
postgresql@11 started jbranchaud ~/Library/LaunchAgents/homebrew.mxcl.postgresql@11.plist
postgresql@13 none
postgresql@16 none
unbound none
```
This is the default behavior if you just run `brew services` without a subcommand.
This is helpful if you are, for instance, trying to see which PostgreSQL server
version you are currently running and which other ones are available to run. I
might then issue a `stop` to `postgresql@11` so that I can then `start` the
`postgresql@16` service.
See `brew services --help` for more details.

View File

@@ -1,26 +0,0 @@
# Add Only Tracked Files From A Directory
The two extremes of staging files in a git repo are to either selectively pick
each individual chunk of changes with `git add --patch` (my preference!) or to
run `git add -A` to add everything.
Now let's say I have large directory full of files that get generated during
test runs. Most of these files are tracked (already checked in to the
repository). There are also many new files generated as part of the most recent
test run.
I want to staging the changes to files that are already tracked, but hold off
on doing anything with the new files.
Running `git add spec/cassettes` won't do the track because that will pull in
everything. Running `git add --patch spec/cassettes` will take long and be
tedious. Instead what I want is the `-u` flag. It's short for _update_ which
means it will only stage already tracked files.
```bash
$ git add -u spec/cassettes
```
That will stage every change to any already known files in `spec/cassettes`.
See `man git-add` for more details.

View File

@@ -1,26 +0,0 @@
# Remove Untracked Files From A Directory
Let's say I have a directory (`spec/cassettes`) full of a ton of generated YAML
files. Most of these files are tracked by git. However, I just generated a
bunch of new ones that are untracked. For whatever reason, I don't want these
files. I need to delete them.
Running `rm` on each of them is going to be too tedious. And it is tricky to
target them for a bulk delete since there are a ton of other files in that
directory that I want to keep.
One way to approach this is have `git ls-files` help out with listing all files in the
directory that are untracked. The `--others` flag filters to untracked files.
```bash
git ls-files --others --exclude-standard spec/cassettes
```
From there, I can pipe it to `rm` (with `xargs` collapsing all the files into a
single line):
```bash
git ls-files --others --exclude-standard spec/cassettes | xargs rm
```
See `man git-ls-files` for more details.

View File

@@ -1,25 +0,0 @@
# Make Elements Non-Interactive With Inert
The [`inert`
attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert)
global attribute is a boolean that can be applied to an element or section of
content in an HTML document. When it is `true`, that elements and anything
nested within it will not be interactive.
```html
<div class="fancy-animation" inert>
<!-- ... -->
</div>
```
This has a couple different implications:
1. Click events are not fired on these elements.
2. These elements will not be able to gain focus.
3. These elements and content are hidden from assistive technology.
This is useful for a variety of things. In particular, it is good for
accessibility when a portion of the document, like a fancy animation, isn't
meant to be traversed by assistive technology.

View File

@@ -1,57 +0,0 @@
# Ensure Lookup Can Be Retried
A common thing to do in a workflow step is to look up a record. This might be a
record that was created or updated around the time that the workflow was
triggered.
You need to be sure the record was found before proceeding. That might end up
looking like this:
```typescript
export default inngest.createFunction(
{ id: "record-user-purchase" },
{ event: "app/record.purchase" },
async ({ event, step }) => {
const checkoutSession =
await step.run("find checkout session", async () => {
const cs = provider.lookupSession(event.checkoutSessionId)
return cs;
});
if(!checkoutSession) {
throw new Error('Checkout session not found')
}
}
);
```
This approach has a subtle problem which is that the error for a missing
checkout session is raised _outside_ the step that sets `checkoutSession`. As
inngest does a series of retries, the memorized `checkoutSession` step won't be
rerun and the error will continue to be thrown.
It is better to raise the error _within_ the lookup step:
```typescript
export default inngest.createFunction(
{ id: "record-user-purchase" },
{ event: "app/record.purchase" },
async ({ event, step }) => {
const checkoutSession =
await step.run("find checkout session", async () => {
const cs = provider.lookupSession(event.checkoutSessionId)
if(!cs) {
throw new Error('Checkout session not found')
}
return cs;
});
}
);
```
If the checkout session is missing on the first couple tries, the step will
have a chance to retry the lookup and maybe eventually find what it is looking
for.

View File

@@ -1,32 +0,0 @@
# Convert Seconds To Date Object
Let's say you have an integer that represents the number of seconds since the
unix epoch. This is a reasonably common way for systems to represent a date.
For example, `1713350171` is an _Expiration Date_ I just got from an API.
But how do we know what date that actually represents and how can we get a
JavaScript `Date` object from that value?
The `new Date()` constructor can produce a date object given an integer. That
integer is not supposed to be seconds since the unix epoch though. See what we
get here:
```javascript
> new Date(1713350171)
1970-01-20T19:55:50.171Z
```
Something is off. The integer that you pass to `new Date()` needs to be the
_number of milliseconds_ since the unix epoch. We can get there by multiplying
our _seconds_ value by `1000`.
```javascript
> new Date(1713350171 * 1000)
2024-04-17T10:36:11.000Z
```
Not only can we, as humans, read that date, but we have a `Date` object that we
can use within our program.
Note: if you execute `Date.now()`, the value you get is in milliseconds.

View File

@@ -1,40 +0,0 @@
# Send cURL To Claude Text Completion API
Here is how we can make a `cURL` (`POST`) request to the Claude text completion
API. It requires already having a Claude API account with (paid) credits. At
this time, you can get $5 in free credits to try it out.
Assuming all that, we can grab an API key, store it somewhere safe and
accessible like 1Password, and then start formatting a request.
We need to specify a couple headers as well as `POST` body parameters.
```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: $(op item get "Anthropic Claude API Key" --field credential)" \
-H "anthropic-version: 2023-06-01" \
-d \
'{
"model": "claude-2.1",
"max_tokens_to_sample": 1024,
"prompt": "Human: Show me an example of a simple Ruby program.\n\nAssistant:"
}' \
https://api.anthropic.com/v1/complete
```
The required headers are:
- `"Content-Type: application/json"`
- `x-api-key` with our API key
- `"anthropic-version: 2023-06-01"` (the latest Anthropic API version)
Then, in the body, we specify:
- the `model` (e.g. `claude-2.1`)
- the max number of tokens you want the model to use
- a prompt that starts with `Human:` and then prompts the `Assistant:`
Note: this is a legacy API and the [Messages
API](https://docs.anthropic.com/claude/reference/messages_post) should be
preferred.
[source](https://docs.anthropic.com/claude/reference/complete_post)

View File

@@ -1,26 +0,0 @@
# Use The llm CLI With Claude Models
[Simon Willison's `llm`](https://llm.datasette.io/en/stable/index.html) can be
used with a bunch of different models (local and API). The whole thing is
plugin driven. To use a specific model, you'll need to install the plugin for
it. For instance, to use the [Claude 3 family of
models](https://www.anthropic.com/news/claude-3-family) you need to install
`llm-claude-3`.
```bash
$ llm install llm-claude-3
```
Then when prompting `llm`, specify which of the Claude models you want to use —
`claude-3-haiku`, `claude-3-sonnet`, or `claude-3-opus` — with the `-m` flag:
```bash
$ llm \
-m claude-3-haiku \
--key $CLAUDE_API_KEY \
'Show me the SQL query to create a cocktails table.'
```
Note: instead of adding my Claude API key to the key store, I've opted to
include it with the `--key` flag via an environment variable that I've set
ahead of time.

View File

@@ -1,24 +0,0 @@
# Fetch Does Not Work In API Serverless Function
Next.js ships with [its own implementation of
`fetch`](https://nextjs.org/docs/app/api-reference/functions/fetch) that
extends the [native `fetch`
API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
I ran into a bug recently that was only reproducible in production. I had a
Next.js API function that was `POST`ing to another API endpoint using `fetch`.
I tested it several ways in development. It worked great. However, once the
feature was in production, it was silently failing. After some `console.log`
debugging, I discovered that the target API was getting an empty `body` in the
`POST` request.
I don't know the specifics of why, but somehow the `fetch` implementation
running in the Vercel serverless function environment apparently strips out the
`body` of a POST request.
The solution, for me, was to add the
[`node-fetch`](https://github.com/node-fetch/node-fetch) package and import
that version of fetch in my API function. Once I made that change, my feature
was working again.
[source](https://github.com/vercel/vercel/discussions/4971)

View File

@@ -1,41 +0,0 @@
# Precedence Of Dot Env Files
_Dot Env_ files like `.env`, `.env.development`, `.env.local`, etc. are one of
the main ways to configure your Next.js app across various environments.
It's not uncommon to see several different `.env*` files in production app that
is under active development.
Here is an example of almost every variant in play:
```bash
$ ls -a -1 .env*
.env
.env.development
.env.development.local
.env.development.local.example
.env.local
.env.production
.env.test
```
So, how does Next.js decide which files to load and in what order?
It will always attempt to load `.env` and `.env.local` (except in `test`) if
those exist. It will also look for environment-specific files based on the
`NODE_ENV` (which can be one of `development`, `test`, or `production`). So, in
`development`, the `.env.development` and `.env.development.local` will be
loaded. Something like `.env.development.local.example` isn't on the list, but
rather is a convention for a dotenv file's template.
As for the order, the environment itself (your system's environment variables)
which are present in `process.env` take the highest precedence. After that, it
looks in any of the follow present files in this order, stopping once it finds
what it is looking for:
- `.env.$(NODE_ENV).local`
- `.env.local`
- `.env.$(NODE_ENV)`
- `.env`
[source](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order)

View File

@@ -1,42 +0,0 @@
# Check If Clusters Are Upgrade Compatible
One of the ways to upgrade a PostgreSQL database from one server version to
another is to use the built-in `pg_upgrade` command. This can be faster and
require fewer manual steps than something like a `pg_dump` and `pg_restore`.
However, before you run the `pg_upgrade` command for real, you should check
that the target database is compatible with the current database. To do this,
write your `pg_update` command with all the flags you need and then tack on
`--check` at the end. This does a dry-run reporting the results of a series of
consistency checks.
Here is what a successful _check_ looks like:
```bash
$ /usr/local/opt/postgresql@13/bin/pg_upgrade \
--old-bindir $HOME/.asdf/installs/postgres/12.3/bin \
--new-bindir /usr/local/opt/postgresql@13/bin \
--old-datadir $HOME/.asdf/installs/postgres/12.3/data \
--new-datadir ./postgres/data \
--check
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for system-defined composite types in user tables ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for presence of required libraries ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for new cluster tablespace directories ok
*Clusters are compatible*
```
If there is an issue, such as mismatched collation settings, the output will
report the issue. You'll have to decide how to resolve those on a case-by-case
basis.

View File

@@ -1,46 +0,0 @@
# Create A Cluster In A Specific Data Directory
Let's say I want to create a PostgreSQL cluster near my app. So, I create a
`postgres/data` directory next to my app. Then I run the `initdb` command
pointing at that directory and specifying the UTF-8 locale.
Here is what that looks like:
```bash
$ /usr/local/opt/postgresql@13/bin/initdb -D postgres/data --locale=en_US.UTF-8
The files belonging to this database system will be owned by user "jbranchaud".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory postgres/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... America/Chicago
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
'/usr/local/opt/postgresql@13/bin/pg_ctl' -D postgres/data -l logfile start
```
As stated at the end of the command's output, I can run the `postgres` server
with that data directory with:
```bash
$ '/usr/local/opt/postgresql@13/bin/pg_ctl' -D postgres/data -l logfile start
```

View File

@@ -1,33 +0,0 @@
# Include Columns In A Covering Index
A _covering index_ is a special type of B-Tree index that, in addition to
indexing on a certain field, also _includes_ one or more columns as extra data
in the leaves of the tree. When created correctly, this can speed up the
queries it targets by achieving an _index-only scan_.
Let's say we have a frequently run query on a large `events` table that looks
like this:
```sql
select user_id, identifier, type
from events
where user_id = $1;
```
Here is what it looks like to create an index for this query with the `include`
keyword:
```sql
create index user_id_on_events_idx
on (user_id)
include (identifier, type);
```
An index on its own can already cause a significant speed up to the queries it
targets, but may still need to retrieve some `select` attributes from the
table. For hot-path queries with a set of specific columns always included in
the select, there can be significant additional speed ups by having the index
_cover_ those columns.
For more details, check out [A Close Look At The Index Include
Clause](https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes).

View File

@@ -1,31 +0,0 @@
# Use pipx To Install End User Apps
The [`pipx`](https://pipx.pypa.io/stable/) tool is an installer for the python
ecosystem. It differs from `pip` in that it is for installing end-user
applications and it does so in isolated environments.
You can install `pipx` with an OS-specific installer like Homebrew:
```bash
$ brew install pipx
```
Ensure `pipx`-installed apps are on your path:
```bash
$ pipx ensurepath
```
Then use `pipx` to install programs like
[`cowsay`](https://pypi.org/project/cowsay/) or
[`llm`](https://llm.datasette.io/en/stable/setup.html):
```bash
$ pipx install llm
$ which llm
/Users/jbranchaud/.local/bin/llm
$ llm --version
llm, version 0.13.1
```

View File

@@ -1,37 +0,0 @@
# Get Formatted UTC Offset Value
The UTC offset (during DST) for Chicago is `-05:00`. And for Newfoundland it is
`-02:30`.
Rails has an [`ActiveSupport::TimeZone`
module](https://api.rubyonrails.org/v7.1.3.2/classes/ActiveSupport/TimeZone.html#method-c-seconds_to_utc_offset)
that can turn the UTC offset in seconds into this formatted value.
```ruby
> chicago = TZInfo::Timezone.get('America/Chicago')
=> #<TZInfo::DataTimezone: America/Chicago>
> ActiveSupport::TimeZone.seconds_to_utc_offset(chicago.utc_offset)
=> "-05:00"
> newfoundland = TZInfo::Timezone.get('America/St_Johns')
=> #<TZInfo::DataTimezone: America/St_Johns>
> ActiveSupport::TimeZone.seconds_to_utc_offset(newfoundland.utc_offset)
=> "-02:30"
```
The underlying `tzinfo` gem is DST-aware and its database even knows which time
zone identifiers don't observe DST, so you can run this anytime of the year and
expect reliable results.
Here is another way at this:
```ruby
> chicago = TZInfo::Timezone.get('America/Chicago')
=> #<TZInfo::DataTimezone: America/Chicago>
> ActiveSupport::TimeZone[chicago.name]
=> #<ActiveSupport::TimeZone:0x00000001099d8140 @name="America/Chicago", @tzinfo=#<TZInfo::DataTimezone: America/Chicago>, @utc_offset=nil>
> ActiveSupport::TimeZone[chicago.name].formatted_offset
=> "-06:00"
> ActiveSupport::TimeZone[chicago.name].formatted_offset(false)
=> "-0600"
```

View File

@@ -1,33 +0,0 @@
# Look Up Time Zone Info For Identifier
The `ActiveSupport::TimeZone` class overrides the `#[]` method to be a lookup
mechanism for IANA Time Zone Identifier strings. These are strings like
`America/Chicago` (or anything else listed under `TZInfo::Timezone.all`).
Let's get an instance for `America/Chicago`.
```ruby
> chi = ActiveSupport::TimeZone['America/Chicago']
=> #<ActiveSupport::TimeZone:0x00000001099d8140
@name="America/Chicago",
@tzinfo=#<TZInfo::DataTimezone: America/Chicago>,
@utc_offset=nil>
```
Notice it has a `tzinfo` instance variable that we can access. That object
contains all kinds of useful things.
```ruby
> chi.tzinfo.name
=> "America/Chicago"
> chi.tzinfo.friendly_identifier
=> "America - Chicago"
> chi.tzinfo.abbr
=> "CDT"
> chi.tzinfo.utc_offset
=> -18000
> chi.tzinfo.dst?
=> true
```
All of these and more. Run `ls chi.tzinfo` in a `pry` session to see what else.

View File

@@ -1,45 +0,0 @@
# Audit Your Ruby Project For Any CVEs
The [`bundler-audit` gem](https://github.com/rubysec/bundler-audit) is a handy
tool that you can run manually or integrate into your CI workflow to warn you
about any CVEs in your dependencies.
Running this tool without any arguments will perform a check of your
`Gemfile.lock` file. It will check against the
[`ruby-advisory-db`](https://github.com/rubysec/ruby-advisory-db) for any CVEs
linked to your dependencies, down to the patch-level.
```bash
$ bundle exec bundler-audit
Name: puma
Version: 4.3.12
CVE: CVE-2024-21647
GHSA: GHSA-c2f4-cvqm-65w2
Criticality: Medium
URL: https://github.com/puma/puma/security/advisories/GHSA-c2f4-cvqm-65w2
Title: Puma HTTP Request/Response Smuggling vulnerability
Solution: upgrade to '~> 5.6.8', '>= 6.4.2'
Vulnerabilities found!
```
In this example run, a vulnerability was found in the currently installed
version of the `puma` gem.
I believe a standard `bundler-audit` command will make sure the advisory DB is
up-to-date, but to be sure, you can run the `update` command.
```bash
$ bundle exec bundler-audit update
Updating ruby-advisory-db ...
From https://github.com/rubysec/ruby-advisory-db
* branch master -> FETCH_HEAD
Already up to date.
Updated ruby-advisory-db
ruby-advisory-db:
advisories: 884 advisories
last updated: 2024-03-26 16:27:16 -0700
commit: 840f21aeeb8a06a93a3c3bf1e2a92d7167029992
```

View File

@@ -1,47 +0,0 @@
# Define Multiline Strings With Heredocs
[A _heredoc_ (_here document_) is a special ruby
syntax](https://ruby-doc.org/core-2.5.0/doc/syntax/literals_rdoc.html#label-Here+Documents)
for defining formatted multiline strings. These are useful for any situation
where you need to define a block of text where newlines and indentation are
preserved -- e.g. output an error, help message, or some formatted SQL.
The standard syntax is defined with `<<` and some uppercase identifier (e.g.
`TXT`, `DOC`, `SQL`, etc.) to open and close the multiline string.
```ruby
def lookup_team(team_id)
query = <<SQL
select users.id from users
join teams
on teams.id = users.team_id
where teams.id = #{team_id}
order by created_at desc
limit 10;
SQL
team_member_ids = db.execute(query)
end
```
With the SQL formatted this way, it is easier to read and we can print/log out
this nicely formatted version to make debugging easier.
Notice that the terminating `SQL` identifier is fully left justified. I find
that visually off relative to the indentation of everything else, so I like to
use the _indented_ heredoc syntax (`<<-`).
```ruby
def lookup_team(team_id)
query = <<-SQL
select users.id from users
join teams
on teams.id = users.team_id
where teams.id = #{team_id}
order by created_at desc
limit 10;
SQL
team_member_ids = db.execute(query)
end
```

View File

@@ -1,35 +0,0 @@
# Format A Hash Into A String Template
The `%` method as defined by `String`
([`String#%`](https://ruby-doc.org/core-3.0.0/String.html#method-i-25)) allows
you to format (interpolate) an object or array of values into a string. That
string needs to contain template markers for where the values should go.
Here is an example of folding an array of values into a string with [`%s`
format
specifier](https://docs.ruby-lang.org/en/master/format_specifications_rdoc.html#label-Specifier+s):
```ruby
> User = Struct.new(:id)
=> User
> user1 = User.new(123)
=> #<struct User id=123>
> "%s ID: %s" % [user1.class.to_s, user1.id]
=> "User ID: 123"
```
Or perhaps more usefully for a string that acts as a template, you can used
named specifiers that correspond to hash keys:
```ruby
> template = "You paid %{formatted_price} for %{product}. Enjoy your purchase!"
=> "You paid %{formatted_price} for %{product}. Enjoy your purchase!"
> data = { product: "Ruby Explained™", formatted_price: "$38.99" }
=> {:product=>"Ruby Explained™", :formatted_price=>"$38.99"}
> template % data
=> "You paid $38.99 for Ruby Explained™. Enjoy your purchase!"
```
[source](https://hashrocket.com/blog/posts/using-a-hash-of-data-for-string-replacement-in-ruby)

View File

@@ -1,42 +0,0 @@
# Get UTC Offset For Different Time Zones
The [IANA Time Zone Database](https://www.iana.org/time-zones) uses identifiers
like `America/Chicago`, `Asia/Hong_Kong`, `Africa/Nairobi`, etc. as specifiers
for notable locations with time zone information.
> Most timezones correspond to a notable location and the database records all
> known clock transitions for that location; some timezones correspond instead
> to a fixed UTC offset.
—[Theory and pragmatics of the tz code and data](https://data.iana.org/time-zones/theory.html)
These identifiers can be used to look up time zone details with the [`tzinfo`
gem](https://github.com/tzinfo/tzinfo).
Here is an example of passing one to the `#get` method and then getting the UTC
offset in seconds.
```ruby
> require 'tzinfo'
> mountain = TZInfo::Timezone.get('America/Denver')
=> #<TZInfo::DataTimezone: America/Denver>
> mountain.utc_offset
=> -21600
```
We can even get the base UTC offset that doesn't account for DST:
```ruby
> moutain.base_utc_offset
=> -25200
```
Notice, this is the same as the standard offset for a time zone like Phoenix
that doesn't observe DST.
```ruby
> phoenix = TZInfo::Timezone.get('America/Phoenix')
=> #<TZInfo::DataTimezone: America/Phoenix>
> phoenix.utc_offset
=> -25200
```

View File

@@ -1,46 +0,0 @@
# Specify How Random Array#sample Is
A typical use of the
[`sample`](https://ruby-doc.org/core-2.4.0/Array.html#method-i-sample) method
on [`Array`](https://ruby-doc.org/core-2.4.0/Array.html) will look something
like this:
```ruby
> chars = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map(&:to_a).flatten
> chars.sample(6)
=> ["o", "Z", "X", "i", "8", "Y"]
```
By default, this is using `Random` (a pseudo-random number generator) to
produce a _random_ sampling of elements from your array.
The longer form of this looks like:
```ruby
> chars.sample(6, random: Random)
=> ["F", "c", "g", "I", "w", "E"]
```
Or to get reproducible results, you can specify the `Random` seed:
```ruby
> chars.sample(6, random: Random.new(123))
=> ["T", "c", "D", "K", "P", "s"]
```
If instead you want a cryptographically random sampling of elements from your
array, you can specify a different random number generator. Such as
[`SecureRandom`](https://ruby-doc.org/stdlib-2.5.1/libdoc/securerandom/rdoc/SecureRandom.html).
```ruby
> require 'securerandom'
=> true
> chars.sample(6, random: SecureRandom)
=> ["3", "C", "o", "i", "K", "4"]
```
The
[`Array#shuffle`](https://ruby-doc.org/core-2.4.0/Array.html#method-i-shuffle)
method is another example of a method that can take a `random` option.

View File

@@ -1,25 +0,0 @@
# Generate Base64 Encoding Without Newlines
There are a variety of tools that can generate a Base64 encoding of given text.
Most of them that I've encountered have a number of characters at which they
introduce a newline character. Here is `openssl` as an example:
```bash
echo "here is a long bit of text to base64 encode with openssl" | openssl base64
aGVyZSBpcyBhIGxvbmcgYml0IG9mIHRleHQgdG8gYmFzZTY0IGVuY29kZSB3aXRo
IG9wZW5zc2wK
```
[The theory I've seen](https://superuser.com/a/1225139) is that this is to
accommodate 80-character terminal screens when chunks of encoding were included
in emails.
With the `openssl base64` command, there is not an option to exclude the
newlines, but we can pipe it through `tr` to remove them.
```bash
echo "here is a long bit of text to base64 encode with openssl" | \
openssl base64 | \
tr -d '\n'
aGVyZSBpcyBhIGxvbmcgYml0IG9mIHRleHQgdG8gYmFzZTY0IGVuY29kZSB3aXRoIG9wZW5zc2wK
```

View File

@@ -1,36 +0,0 @@
# Get A List Of Locales On Your System
The `locale -a` command will list all the available locales on your system.
You'll see a giant list that probably includes these and many more values.
```bash
$ locale -a
en_NZ
nl_NL.UTF-8
pt_BR.UTF-8
fr_CH.ISO8859-15
eu_ES.ISO8859-15
en_US.US-ASCII
af_ZA
bg_BG
cs_CZ.UTF-8
fi_FI
zh_CN.UTF-8
eu_ES
sk_SK.ISO8859-2
nl_BE
fr_BE
sk_SK
en_US.UTF-8
...
```
Each of these locales identifies itself by the language and the manner in which
the language is used in a particular place. For example, `en_NZ` is _English as
it is spoken in New Zealand_. `fr_BE` is _French as it is spoken in Belgium_.
`en_US.UTF-8` is _English as it is spoken in the US, with a UTF-8 character set
encoding_.
[source](https://www.postgresql.org/docs/current/locale.html#LOCALE-OVERVIEW)

View File

@@ -1,31 +0,0 @@
# Include Ignore Files In Ripgrep Search
By default, [ripgrep (`rg`)](https://github.com/BurntSushi/ripgrep) will look
for and respect _ignore_ files like `.gitignore`. Any file and directory marked
by those ignore files will no be included in an `rg` search.
This is usually what you want. Sometimes, however, it can be useful to get
results from this ignored files as well.
In order to ignore your ignore files, pass the `--no-ignore` flag to `rg`:
```bash
$ rg --no-ignore ENV_VAR_KEY
```
Something to keep in mind is that `rg` also ignores _hidden_ files and
directories (those things that are prefixed with a `.`, such as `.env` or
`.config/`). If some of your ignored files are also _hidden_ files, then they
still won't show up in search. You'll need the `--hidden` flag as well.
```bash
$ rg --no-ignore --hidden ENV_VAR_KEY
```
A shorthand equivalent for that is `-uu`:
```bash
$ rg -uu ENV_VAR_KEY
```
See `man rg` for more details.

View File

@@ -1,34 +0,0 @@
# List Files In A Single Column
The `ls` command lists out the files and directories in your current directory
or a specified directory.
The standard output for an `ls` command expands the fit the width of your
terminal screen.
```bash
ls *.(ts|js)
cypress.config.ts postcss.config.js remix.config.js remix.env.d.ts server.ts tailwind.config.ts vitest.config.ts
```
This might not always be the ideal way to view that output. For instance, the
above example when shared as a code block like in this post ends up with
horizontal scroll.
With the `-1` flag, we can tell `ls` to display the results in a single
vertical column.
```bash
ls -1 *.(ts|js)
cypress.config.ts
postcss.config.js
remix.config.js
remix.env.d.ts
server.ts
tailwind.config.ts
vitest.config.ts
```
See `man ls` for more details.
[source](https://askubuntu.com/questions/954924/listing-files-in-directory-in-one-column)

View File

@@ -1,16 +0,0 @@
# Print DateTime Represented By Unix Timestamp
A lot of tools and systems use a Unix timestamp to represent a point in time.
It is the number of seconds since the Unix epoch (Jan 1, 1970). However, just
looking at a timestamp like `1623867544` doesn't tell a human much. I can't
mentally translate that to the date and time that it is representing.
The `date` utility can help. Give it the `-r` flag with the timestamp value (in
seconds) and it will display the date and time in a human-readable format.
```bash
date -r '1623867544'
Wed Jun 16 13:19:04 CDT 2021
```
See `man date` for more details.

View File

@@ -1,33 +0,0 @@
# Unrestrict Where ripgrep Searches
One of the conveniences of [`rg`
(ripgrep)](https://github.com/BurntSushi/ripgrep) is that by default it doesn't
search in places you probably don't want it to search. That means it ignores
anything specified by your `.gitignore` file, it excludes hidden files and
directories (dotfiles, e.g. `.git/` or `.env`), and it excludes binary files.
These restrictions can be incrementally undone as needed using the `-u` flag.
The `-u` flag on its own will remove the ignored files restriction. This is
equivalent to the `--no-ignore` flag.
```bash
$ rg -u pattern
```
Adding an additional `u` (`-uu`) to that flag will remove both the ignored files and
hidden files restrictions. This is a shorthand equivalent to both `--no-ignore`
and `--hidden`.
```bash
$ rg -uu pattern
```
Adding one more `u` (`-uuu`) will additionally remove the binary file
restriction. Equivalent to those other two flags plus `--text`.
```bash
$ rg -uuu pattern
```
[source](https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#automatic-filtering)

View File

@@ -1,31 +0,0 @@
# Find The Location Of User Settings JSON File
There are a ton ways to customize and fine-tune VS Code. All of the settings
have defaults which can then be customized on a workspace and user level.
Typically you'll access these files within VS Code via the Command Palette. I
was curious though: since it is just a JSON file, surely I can view and modify
it with any editor.
On a Mac, the user-level `settings.json` file is located at
`~/Library/Application\ Support/Code/User/settings.json`.
Open it up and you might see something like this:
```json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"window.zoomLevel": 1,
"workbench.editor.showTabs": "single"
}
```
A handful of settings with specific overrides.
Feel free to edit what is in here or add other settings that you want to set.
Just make sure you know what you're doing and that you set valid values.
The VS Code docs list [the locations of these files on other operating
systems](https://code.visualstudio.com/docs/getstarted/settings#_settings-file-locations).
[source](https://stackoverflow.com/questions/53840644/location-of-vs-code-preferences)

View File

@@ -1,18 +0,0 @@
# Turn Off Display Of Tabs For Files
Each time a file is opened in VS Code, it appears as one of many toward the top
of the window right above the text editor area. It shows the name of the file
and the 'dirty' status. Over time as more and more files are opened and edited,
the tabs accumulate and can only be viewed by horizontally scrolling left and
right.
There are other ways to navigate to files besides selecting tabs of already
opened files. So, if you'd like to reclaim some screen real estate and reduce
the visual clutter of the tabs, you can turn them off.
Hit `Cmd+Shift+P`, then search for and go to _Preferences: Open Settings (UI)_.
Search for _Show Tabs_ which will show up under _Workbench > Editor_.
The default is _Multiple_. You can switch it to _None_ to completely hide tabs.
You can also set it to _Single_ which will display file name and path for the
current file, but eliminate the clutter of all other tabs.

View File

@@ -1,29 +0,0 @@
# Access 1Password Credential From CLI
With the `op` CLI, I can store things like API keys and secrets in my 1Password
vault and then access them from the command line. This assumes I've already
installed the CLI (`brew install 1password-cli`) and connected it to the
1Password app via the _Developer_ settings.
The `op item get` command takes a credential name and returns all the details
for the entry with that _Title_. Here is how I can access my _Anthropic Claude
API Key_ details.
```bash
$ op item get "Anthropic Claude API Key"
```
With the `--field` flag, I can grab a specific field, such as the `credential`,
from that entry.
```bash
$ op item get "Anthropic Claude API Key" --field credential
sk-ant-api03-abc......xyz
```
A command like this can be embedded in other commands as a way of referencing
secrets without explicitly entering them into your shell history.
```bash
$ curl https://api -H "x-api-key: $(op item get "Anthropic Claude API Key" --field credential)" ...
```

View File

@@ -1,49 +0,0 @@
# Add Subtitles To Existing Mux Video Asset
There is a [JavaScript/TypeScript Mux
SDK](https://github.com/muxinc/mux-node-sdk) for interacting with Mux via their
[API](https://docs.mux.com/api-reference).
With a Mux client (initialized from `MUX_ACCESS_TOKEN` and `MUX_SECRET_KEY` in
our environment), we can destructure `Video` which will allow us to call
`Video.Assets.createTrack`. We pass that function the ID of an existing video
asset and then an object of data defining the subtitle track. In this case, it
is an English subtitle track. We need to point Mux to a `url` where the WebVTT
formatted subtitles are hosted.
```typescript
// add-srt-to-specific-video.ts
import Mux from '@mux/mux-node'
require('dotenv-flow').config({
default_node_env: 'development',
})
const assetId = "mux-asset-id" // set this value
const srtUrl = "https://public-webvtt-file" // set this value
// Set up Mux API Client
const MUX_ACCESS_TOKEN = process.env.MUX_ACCESS_TOKEN as string
const MUX_SECRET_KEY = process.env.MUX_SECRET_KEY as string
const muxClient = new Mux(MUX_ACCESS_TOKEN, MUX_SECRET_KEY)
const {Video} = muxClient
await Video.Assets.createTrack(assetId, {
url: srtUrl,
type: 'text',
text_type: 'subtitles',
closed_captions: false,
language_code: 'en-US',
name: 'English',
passthrough: 'English',
})
```
We can run the above script with `ts-node` from the command-line like so:
```bash
$ npx ts-node --files --skipProject add-srt-to-specific-video.ts
```
We'll see the new track on the existing asset in the Mux dashboard.