@icarusmx/creta 1.5.12 → 1.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/creta.js +31 -1
- package/lib/data/command-help/aws-ec2.js +34 -0
- package/lib/data/command-help/grep.js +76 -0
- package/lib/data/command-help/index.js +11 -1
- package/lib/data/command-help/lz.js +57 -0
- package/lib/executors/CommandHelpExecutor.js +6 -1
- package/lib/exercises/.claude/settings.local.json +12 -0
- package/lib/exercises/01-developing-muscle-for-nvim.md +528 -0
- package/lib/exercises/{iterm2-pane-navigation.md → 02-iterm2-pane-navigation.md} +1 -1
- package/lib/exercises/05-svelte-first-steps.md +1340 -0
- package/lib/exercises/{curl-and-pipes.md → 06-curl-and-pipes.md} +187 -72
- package/lib/exercises/07-claude-api-first-steps.md +855 -0
- package/lib/exercises/08-playwright-svelte-guide.md +1384 -0
- package/lib/exercises/09-docker-first-steps.md +1475 -0
- package/lib/exercises/{railway-deployment.md → 10-railway-deployment.md} +1 -0
- package/lib/exercises/{aws-billing-detective.md → 11-aws-billing-detective.md} +215 -35
- package/lib/exercises/12-install-skills.md +755 -0
- package/lib/exercises/13-shell-aliases.md +134 -0
- package/lib/exercises/README.md +187 -0
- package/lib/exercises/utils/booklet-2up.js +133 -0
- package/lib/exercises/utils/booklet-manual-duplex.js +159 -0
- package/lib/exercises/utils/booklet-simple.js +136 -0
- package/lib/exercises/utils/create-booklet.js +116 -0
- package/lib/scripts/aws-ec2-all.sh +58 -0
- package/package.json +3 -2
- /package/lib/exercises/{git-stash-workflow.md → 03-git-stash-workflow.md} +0 -0
- /package/lib/exercises/{array-object-manipulation.md → 04-array-object-manipulation.md} +0 -0
|
@@ -10,6 +10,45 @@ This document uses fold markers `{{{` and `}}}` for organized reading.
|
|
|
10
10
|
|
|
11
11
|
}}}
|
|
12
12
|
|
|
13
|
+
## 📜 What is curl? {{{
|
|
14
|
+
|
|
15
|
+
**curl** stands for "Client URL" - a command-line tool for transferring data with URLs.
|
|
16
|
+
|
|
17
|
+
**Created:** 1997 by Daniel Stenberg (Swedish developer)
|
|
18
|
+
**Original purpose:** Transfer files over networks without GUI
|
|
19
|
+
**Today's use:** The universal tool for testing APIs, downloading files, and debugging HTTP requests
|
|
20
|
+
|
|
21
|
+
**Why curl won:**
|
|
22
|
+
- Pre-installed on macOS, Linux, and Windows 10+
|
|
23
|
+
- Supports HTTP, HTTPS, FTP, and 20+ protocols
|
|
24
|
+
- Scriptable, pipe-friendly, and lightweight
|
|
25
|
+
- Used by millions of developers daily
|
|
26
|
+
|
|
27
|
+
**Fun fact:** curl powers more devices than you think - from smart cars to Mars rovers to your terminal.
|
|
28
|
+
|
|
29
|
+
}}}
|
|
30
|
+
|
|
31
|
+
## 🔑 Essential curl Flags (Quick Overview) {{{
|
|
32
|
+
|
|
33
|
+
Before diving into real-world scenarios, here are the flags you'll use 90% of the time:
|
|
34
|
+
|
|
35
|
+
| Flag | Purpose | Example |
|
|
36
|
+
|------|---------|---------|
|
|
37
|
+
| `-s` | Silent (no progress bar) | `curl -s https://api.github.com` |
|
|
38
|
+
| `-L` | Follow redirects | `curl -sL https://icarus.mx/creta` |
|
|
39
|
+
| `-i` | Include HTTP headers | `curl -si https://api.github.com` |
|
|
40
|
+
| `-H` | Add custom header | `curl -H "Authorization: Bearer $TOKEN"` |
|
|
41
|
+
| `-w` | Custom output format | `curl -s -w "%{http_code}"` |
|
|
42
|
+
|
|
43
|
+
**Pattern you'll see everywhere:**
|
|
44
|
+
```bash
|
|
45
|
+
curl -sL [URL] | grep [pattern]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Translation:** "Silently fetch this URL, follow redirects, and filter the output."
|
|
49
|
+
|
|
50
|
+
}}}
|
|
51
|
+
|
|
13
52
|
## 🚨 Problem: Need Quick API Insights Without Postman {{{
|
|
14
53
|
|
|
15
54
|
You're debugging an API and need to:
|
|
@@ -42,8 +81,8 @@ curl [API] | [filter] | [process] | [output]
|
|
|
42
81
|
|
|
43
82
|
**Real example:**
|
|
44
83
|
```bash
|
|
45
|
-
# Count
|
|
46
|
-
curl -
|
|
84
|
+
# Count lines in Creta README
|
|
85
|
+
curl -sL https://icarus.mx/creta/README.md | wc -l
|
|
47
86
|
```
|
|
48
87
|
|
|
49
88
|
**Benefits:**
|
|
@@ -92,19 +131,19 @@ curl -si https://api.github.com/users/fake123 | head -n 1
|
|
|
92
131
|
|
|
93
132
|
### -L (Follow Redirects) {{{
|
|
94
133
|
|
|
95
|
-
**Problem:**
|
|
134
|
+
**Problem:** URLs redirect, curl doesn't follow by default
|
|
96
135
|
|
|
97
136
|
```bash
|
|
98
137
|
# Without -L (stops at redirect)
|
|
99
|
-
curl -s https://
|
|
100
|
-
# <redirect
|
|
138
|
+
curl -s https://icarus.mx/creta/README.md
|
|
139
|
+
# <HTML redirect page>
|
|
101
140
|
|
|
102
141
|
# With -L (follows to final destination)
|
|
103
|
-
curl -sL https://
|
|
104
|
-
#
|
|
142
|
+
curl -sL https://icarus.mx/creta/README.md
|
|
143
|
+
# # Creta - Tu Compañero de Terminal...
|
|
105
144
|
```
|
|
106
145
|
|
|
107
|
-
**Use:** Essential for
|
|
146
|
+
**Use:** Essential for CDN redirects, HTTPS upgrades, URL shorteners.
|
|
108
147
|
|
|
109
148
|
}}}
|
|
110
149
|
|
|
@@ -114,16 +153,16 @@ curl -sL https://bit.ly/example
|
|
|
114
153
|
|
|
115
154
|
```bash
|
|
116
155
|
# Add authorization header
|
|
117
|
-
curl -s -H "Authorization: Bearer $TOKEN" https://api.
|
|
156
|
+
curl -s -H "Authorization: Bearer $TOKEN" https://api.icarus.mx/admin/students
|
|
118
157
|
|
|
119
158
|
# Specify JSON content type
|
|
120
|
-
curl -s -H "Content-Type: application/json" https://api.
|
|
159
|
+
curl -s -H "Content-Type: application/json" https://api.icarus.mx/config
|
|
121
160
|
|
|
122
161
|
# Multiple headers
|
|
123
162
|
curl -s \
|
|
124
163
|
-H "Authorization: Bearer $TOKEN" \
|
|
125
164
|
-H "Accept: application/json" \
|
|
126
|
-
https://api.
|
|
165
|
+
https://api.icarus.mx/students
|
|
127
166
|
```
|
|
128
167
|
|
|
129
168
|
}}}
|
|
@@ -294,10 +333,10 @@ curl -s https://jsonplaceholder.typicode.com/posts | grep "userId" | sort | uniq
|
|
|
294
333
|
|
|
295
334
|
```bash
|
|
296
335
|
# Check status code
|
|
297
|
-
curl -s -w "%{http_code}" -o /dev/null https://api.
|
|
336
|
+
curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health
|
|
298
337
|
|
|
299
338
|
# One-liner health check
|
|
300
|
-
if [ $(curl -s -w "%{http_code}" -o /dev/null https://api.
|
|
339
|
+
if [ $(curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health) -eq 200 ]; then
|
|
301
340
|
echo "✅ API is healthy"
|
|
302
341
|
else
|
|
303
342
|
echo "❌ API is down"
|
|
@@ -314,13 +353,13 @@ fi
|
|
|
314
353
|
|
|
315
354
|
```bash
|
|
316
355
|
# Count ERROR lines in logs API
|
|
317
|
-
curl -s https://logs.
|
|
356
|
+
curl -s https://logs.icarus.mx/last-hour | grep "ERROR" | wc -l
|
|
318
357
|
|
|
319
358
|
# Find critical errors only
|
|
320
|
-
curl -s https://logs.
|
|
359
|
+
curl -s https://logs.icarus.mx/last-hour | grep "CRITICAL" | wc -l
|
|
321
360
|
|
|
322
361
|
# Group by error type
|
|
323
|
-
curl -s https://logs.
|
|
362
|
+
curl -s https://logs.icarus.mx/last-hour | grep "ERROR" | cut -d':' -f2 | sort | uniq -c
|
|
324
363
|
```
|
|
325
364
|
|
|
326
365
|
**Use case:** Incident response, debugging production issues.
|
|
@@ -333,14 +372,14 @@ curl -s https://logs.myapp.com/last-hour | grep "ERROR" | cut -d':' -f2 | sort |
|
|
|
333
372
|
|
|
334
373
|
```bash
|
|
335
374
|
# Test: Does response contain expected field?
|
|
336
|
-
curl -s https://api.
|
|
375
|
+
curl -s https://api.icarus.mx/config | grep -q "version" && echo "✅ Pass" || echo "❌ Fail"
|
|
337
376
|
|
|
338
|
-
# Test: Is there at least one
|
|
339
|
-
|
|
340
|
-
if [ $
|
|
341
|
-
echo "✅
|
|
377
|
+
# Test: Is there at least one student?
|
|
378
|
+
STUDENT_COUNT=$(curl -s https://api.icarus.mx/students | grep "\"id\":" | wc -l)
|
|
379
|
+
if [ $STUDENT_COUNT -gt 0 ]; then
|
|
380
|
+
echo "✅ Students endpoint working"
|
|
342
381
|
else
|
|
343
|
-
echo "❌ No
|
|
382
|
+
echo "❌ No students returned"
|
|
344
383
|
fi
|
|
345
384
|
```
|
|
346
385
|
|
|
@@ -353,18 +392,18 @@ fi
|
|
|
353
392
|
**Problem:** Download API data, filter active records, save to file
|
|
354
393
|
|
|
355
394
|
```bash
|
|
356
|
-
# Extract active
|
|
357
|
-
curl -s https://api.
|
|
395
|
+
# Extract active students to file
|
|
396
|
+
curl -s https://api.icarus.mx/students | grep "\"status\": \"active\"" > active-students.json
|
|
358
397
|
|
|
359
|
-
# Extract and count
|
|
360
|
-
curl -s https://api.
|
|
398
|
+
# Extract and count pending submissions
|
|
399
|
+
curl -s https://api.icarus.mx/submissions | grep "\"status\": \"pending\"" | wc -l > pending-submissions.txt
|
|
361
400
|
|
|
362
|
-
# Multi-step pipeline
|
|
363
|
-
curl -s https://api.
|
|
401
|
+
# Multi-step pipeline: Get all lesson names
|
|
402
|
+
curl -s https://api.icarus.mx/lessons \
|
|
364
403
|
| grep "\"name\":" \
|
|
365
404
|
| sed 's/.*"name": "\(.*\)".*/\1/' \
|
|
366
405
|
| sort \
|
|
367
|
-
>
|
|
406
|
+
> lesson-names.txt
|
|
368
407
|
```
|
|
369
408
|
|
|
370
409
|
**Use case:** ETL jobs, data exports, scheduled reports.
|
|
@@ -398,10 +437,10 @@ curl -si https://api.github.com/users/github \
|
|
|
398
437
|
|
|
399
438
|
```bash
|
|
400
439
|
# Get response from v1
|
|
401
|
-
curl -s https://api.
|
|
440
|
+
curl -s https://api.icarus.mx/v1/students > v1-response.json
|
|
402
441
|
|
|
403
442
|
# Get response from v2
|
|
404
|
-
curl -s https://api.
|
|
443
|
+
curl -s https://api.icarus.mx/v2/students > v2-response.json
|
|
405
444
|
|
|
406
445
|
# Compare
|
|
407
446
|
diff v1-response.json v2-response.json
|
|
@@ -519,10 +558,10 @@ curl -s https://jsonplaceholder.typicode.com/users \
|
|
|
519
558
|
|
|
520
559
|
```bash
|
|
521
560
|
# ❌ Bad: progress bar interferes with grep
|
|
522
|
-
curl https://api.
|
|
561
|
+
curl https://api.icarus.mx/students | grep "name"
|
|
523
562
|
|
|
524
563
|
# ✅ Good: clean output
|
|
525
|
-
curl -s https://api.
|
|
564
|
+
curl -s https://api.icarus.mx/students | grep "name"
|
|
526
565
|
```
|
|
527
566
|
|
|
528
567
|
}}}
|
|
@@ -533,10 +572,10 @@ curl -s https://api.example.com | grep "name"
|
|
|
533
572
|
|
|
534
573
|
```bash
|
|
535
574
|
# ❌ Bad: processes error HTML as JSON
|
|
536
|
-
curl -s https://api.
|
|
575
|
+
curl -s https://api.icarus.mx/fake | grep "name"
|
|
537
576
|
|
|
538
577
|
# ✅ Good: check status first
|
|
539
|
-
RESPONSE=$(curl -s -w "\n%{http_code}" https://api.
|
|
578
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" https://api.icarus.mx/students)
|
|
540
579
|
STATUS=$(echo "$RESPONSE" | tail -n 1)
|
|
541
580
|
BODY=$(echo "$RESPONSE" | head -n -1)
|
|
542
581
|
|
|
@@ -556,13 +595,13 @@ fi
|
|
|
556
595
|
|
|
557
596
|
```bash
|
|
558
597
|
# Pipes: Quick field search
|
|
559
|
-
curl -s https://api.
|
|
598
|
+
curl -s https://api.icarus.mx/students | grep "email"
|
|
560
599
|
|
|
561
600
|
# jq: Proper JSON parsing
|
|
562
|
-
curl -s https://api.
|
|
601
|
+
curl -s https://api.icarus.mx/students | jq '.[].email'
|
|
563
602
|
|
|
564
603
|
# jq: Complex queries
|
|
565
|
-
curl -s https://api.
|
|
604
|
+
curl -s https://api.icarus.mx/students | jq '.[] | select(.id > 5) | .name'
|
|
566
605
|
```
|
|
567
606
|
|
|
568
607
|
**Rule of thumb:** If you need more than 2-3 greps/seds, switch to jq.
|
|
@@ -575,15 +614,15 @@ curl -s https://api.example.com/users | jq '.[] | select(.id > 5) | .name'
|
|
|
575
614
|
|
|
576
615
|
```bash
|
|
577
616
|
# ❌ Bad: hits API every time you test
|
|
578
|
-
curl -s https://api.
|
|
579
|
-
curl -s https://api.
|
|
580
|
-
curl -s https://api.
|
|
617
|
+
curl -s https://api.icarus.mx/students | grep "name"
|
|
618
|
+
curl -s https://api.icarus.mx/students | grep "email"
|
|
619
|
+
curl -s https://api.icarus.mx/students | grep "phone"
|
|
581
620
|
|
|
582
621
|
# ✅ Good: save once, test multiple times
|
|
583
|
-
curl -s https://api.
|
|
584
|
-
cat
|
|
585
|
-
cat
|
|
586
|
-
cat
|
|
622
|
+
curl -s https://api.icarus.mx/students > students.json
|
|
623
|
+
cat students.json | grep "name"
|
|
624
|
+
cat students.json | grep "email"
|
|
625
|
+
cat students.json | grep "phone"
|
|
587
626
|
```
|
|
588
627
|
|
|
589
628
|
}}}
|
|
@@ -594,7 +633,7 @@ cat users.json | grep "phone"
|
|
|
594
633
|
|
|
595
634
|
```bash
|
|
596
635
|
# Store response
|
|
597
|
-
RESPONSE=$(curl -s https://api.
|
|
636
|
+
RESPONSE=$(curl -s https://api.icarus.mx/students)
|
|
598
637
|
|
|
599
638
|
# Check if empty
|
|
600
639
|
if [ -z "$RESPONSE" ]; then
|
|
@@ -614,10 +653,10 @@ echo "$RESPONSE" | grep "name"
|
|
|
614
653
|
|
|
615
654
|
```bash
|
|
616
655
|
# Default: waits forever
|
|
617
|
-
curl -s https://
|
|
656
|
+
curl -s https://api.icarus.mx/analytics
|
|
618
657
|
|
|
619
658
|
# With timeout: fails after 10 seconds
|
|
620
|
-
curl -s --max-time 10 https://
|
|
659
|
+
curl -s --max-time 10 https://api.icarus.mx/analytics
|
|
621
660
|
```
|
|
622
661
|
|
|
623
662
|
}}}
|
|
@@ -677,19 +716,19 @@ curl -s URL | grep "active" > output.txt
|
|
|
677
716
|
|
|
678
717
|
```bash
|
|
679
718
|
# Health check
|
|
680
|
-
curl -s -w "%{http_code}" -o /dev/null https://api.
|
|
719
|
+
curl -s -w "%{http_code}" -o /dev/null https://api.icarus.mx/health
|
|
681
720
|
|
|
682
721
|
# Count records
|
|
683
|
-
curl -s https://api.
|
|
722
|
+
curl -s https://api.icarus.mx/students | grep "\"id\":" | wc -l
|
|
684
723
|
|
|
685
724
|
# Extract field
|
|
686
|
-
curl -s https://api.
|
|
725
|
+
curl -s https://api.icarus.mx/config | grep "version" | sed 's/.*"version": "\(.*\)".*/\1/'
|
|
687
726
|
|
|
688
727
|
# Monitor errors
|
|
689
|
-
curl -s https://logs.
|
|
728
|
+
curl -s https://logs.icarus.mx/today | grep "ERROR" | wc -l
|
|
690
729
|
|
|
691
730
|
# Test endpoint
|
|
692
|
-
curl -s https://api.
|
|
731
|
+
curl -s https://api.icarus.mx/students | grep -q "data" && echo "OK" || echo "FAIL"
|
|
693
732
|
```
|
|
694
733
|
|
|
695
734
|
}}}
|
|
@@ -721,7 +760,7 @@ echo -e "api.service1.com\napi.service2.com\napi.service3.com" \
|
|
|
721
760
|
|
|
722
761
|
```bash
|
|
723
762
|
# Stream large response
|
|
724
|
-
curl -s https://api.
|
|
763
|
+
curl -s https://api.icarus.mx/analytics \
|
|
725
764
|
| while IFS= read -r line; do
|
|
726
765
|
echo "$line" | grep "active" >> active-records.txt
|
|
727
766
|
done
|
|
@@ -733,28 +772,104 @@ curl -s https://api.example.com/large-dataset \
|
|
|
733
772
|
|
|
734
773
|
### Authenticated API Requests {{{
|
|
735
774
|
|
|
736
|
-
**
|
|
775
|
+
**Progressive security: unsafe → safe → production**
|
|
776
|
+
|
|
777
|
+
#### 🚨 Level 0: Hardcoded (NEVER do this)
|
|
778
|
+
|
|
779
|
+
```bash
|
|
780
|
+
# ❌ DANGER: JWT visible in shell history
|
|
781
|
+
curl -s -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" \
|
|
782
|
+
https://api.icarus.mx/admin/students | grep "data"
|
|
783
|
+
|
|
784
|
+
# Verify the problem: token saved forever
|
|
785
|
+
history | tail -n 2
|
|
786
|
+
# 482 curl -s -H "Authorization: Bearer eyJhbGci...
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
**Why dangerous:**
|
|
790
|
+
- Stored in `~/.bash_history` forever
|
|
791
|
+
- Visible in `ps aux` while running
|
|
792
|
+
- Accidentally committed to git
|
|
793
|
+
- Leaked in screenshots/demos
|
|
794
|
+
|
|
795
|
+
#### ✅ Level 1: Environment Variable (Basic safety)
|
|
737
796
|
|
|
738
797
|
```bash
|
|
739
|
-
# Store
|
|
740
|
-
TOKEN="
|
|
798
|
+
# Store JWT in variable (not in command)
|
|
799
|
+
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
|
|
741
800
|
|
|
742
|
-
#
|
|
801
|
+
# Use variable (history only shows $TOKEN)
|
|
743
802
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
744
|
-
https://api.
|
|
745
|
-
|
|
803
|
+
https://api.icarus.mx/admin/students | grep "data"
|
|
804
|
+
|
|
805
|
+
# Check history - no JWT visible!
|
|
806
|
+
history | tail -n 1
|
|
807
|
+
# 483 curl -s -H "Authorization: Bearer $TOKEN" ...
|
|
746
808
|
```
|
|
747
809
|
|
|
748
|
-
**
|
|
810
|
+
**Better, but:** Token still in memory during session.
|
|
811
|
+
|
|
812
|
+
#### ✅ Level 2: .env File (Recommended for scripts)
|
|
749
813
|
|
|
750
814
|
```bash
|
|
751
|
-
#
|
|
752
|
-
|
|
815
|
+
# Create .env file (add to .gitignore!)
|
|
816
|
+
cat > .env <<'EOF'
|
|
817
|
+
ICARUS_JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
|
|
818
|
+
EOF
|
|
819
|
+
|
|
820
|
+
# Protect .env and ensure it's ignored
|
|
821
|
+
chmod 600 .env
|
|
822
|
+
echo '.env' >> .gitignore
|
|
823
|
+
|
|
824
|
+
# Source environment
|
|
825
|
+
source .env
|
|
753
826
|
|
|
754
|
-
#
|
|
755
|
-
curl -s -H "Authorization: Bearer $
|
|
827
|
+
# Use safely
|
|
828
|
+
curl -s -H "Authorization: Bearer $ICARUS_JWT" \
|
|
829
|
+
https://api.icarus.mx/admin/students | grep "data"
|
|
756
830
|
```
|
|
757
831
|
|
|
832
|
+
**Best practice:** Never commit .env to version control.
|
|
833
|
+
|
|
834
|
+
#### ✅ Level 3: Secure File Read (No environment variables)
|
|
835
|
+
|
|
836
|
+
```bash
|
|
837
|
+
# Store JWT in protected file
|
|
838
|
+
echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U' > ~/.icarus-jwt
|
|
839
|
+
chmod 600 ~/.icarus-jwt # Only you can read
|
|
840
|
+
|
|
841
|
+
# Read directly in subshell (never enters environment)
|
|
842
|
+
curl -s -H "Authorization: Bearer $(cat ~/.icarus-jwt)" \
|
|
843
|
+
https://api.icarus.mx/admin/students | grep "data"
|
|
844
|
+
|
|
845
|
+
# Verify: no JWT in environment
|
|
846
|
+
env | grep -i jwt
|
|
847
|
+
# (empty - JWT never loaded into environment)
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
**Advantage:** Token never enters shell environment.
|
|
851
|
+
|
|
852
|
+
#### 🔒 Level 4: Production (Keychain/Secret Manager)
|
|
853
|
+
|
|
854
|
+
```bash
|
|
855
|
+
# macOS Keychain
|
|
856
|
+
security add-generic-password -a "$USER" -s icarus-jwt -w "eyJhbGci..."
|
|
857
|
+
JWT=$(security find-generic-password -a "$USER" -s icarus-jwt -w)
|
|
858
|
+
curl -s -H "Authorization: Bearer $JWT" https://api.icarus.mx/admin/students
|
|
859
|
+
|
|
860
|
+
# Linux pass (password-store)
|
|
861
|
+
pass insert icarus/jwt
|
|
862
|
+
JWT=$(pass show icarus/jwt)
|
|
863
|
+
curl -s -H "Authorization: Bearer $JWT" https://api.icarus.mx/admin/students
|
|
864
|
+
|
|
865
|
+
# GitHub Actions / CI/CD
|
|
866
|
+
# Use encrypted secrets, never hardcode
|
|
867
|
+
curl -s -H "Authorization: Bearer ${{ secrets.ICARUS_JWT }}" \
|
|
868
|
+
https://api.icarus.mx/admin/students
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
**Production rule:** If you can see your JWT in `history` or `env`, you did it wrong.
|
|
872
|
+
|
|
758
873
|
}}}
|
|
759
874
|
|
|
760
875
|
### POST Requests with Data {{{
|
|
@@ -788,34 +903,34 @@ curl -s -X POST \
|
|
|
788
903
|
|
|
789
904
|
1. **Combine with watch for live monitoring:**
|
|
790
905
|
```bash
|
|
791
|
-
watch -n 5 'curl -s https://api.
|
|
906
|
+
watch -n 5 'curl -s https://api.icarus.mx/metrics | grep "active" | wc -l'
|
|
792
907
|
```
|
|
793
908
|
|
|
794
909
|
2. **Save complex one-liners as shell functions:**
|
|
795
910
|
```bash
|
|
796
911
|
# In .bashrc or .zshrc
|
|
797
912
|
api_health() {
|
|
798
|
-
curl -s -w "%{http_code}" -o /dev/null "https://api.
|
|
913
|
+
curl -s -w "%{http_code}" -o /dev/null "https://api.icarus.mx/$1"
|
|
799
914
|
}
|
|
800
915
|
|
|
801
916
|
# Usage
|
|
802
|
-
api_health
|
|
917
|
+
api_health students # Check /students endpoint
|
|
803
918
|
```
|
|
804
919
|
|
|
805
920
|
3. **Use aliases for frequent API checks:**
|
|
806
921
|
```bash
|
|
807
|
-
alias check-api='curl -s https://api.
|
|
922
|
+
alias check-api='curl -s https://api.icarus.mx/health | grep "ok"'
|
|
808
923
|
```
|
|
809
924
|
|
|
810
925
|
4. **Pipe to pbcopy (Mac) or xclip (Linux) to copy output:**
|
|
811
926
|
```bash
|
|
812
|
-
curl -
|
|
927
|
+
curl -sL https://icarus.mx/creta/README.md | pbcopy
|
|
813
928
|
```
|
|
814
929
|
|
|
815
930
|
5. **Chain with git for API version tracking:**
|
|
816
931
|
```bash
|
|
817
|
-
curl -s https://api.
|
|
818
|
-
git diff
|
|
932
|
+
curl -s https://api.icarus.mx/config > config.json
|
|
933
|
+
git diff config.json # See what changed
|
|
819
934
|
```
|
|
820
935
|
|
|
821
936
|
}}}
|