langctl 0.1.1 → 0.2.0
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/.gitattributes +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +26 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/CONTRIBUTING.md +33 -0
- package/LICENSE +1 -1
- package/README.md +1018 -113
- package/dist/api.d.ts +20 -0
- package/dist/api.js +75 -0
- package/dist/auth.d.ts +7 -2
- package/dist/auth.js +27 -27
- package/dist/commands/auth.js +2 -10
- package/dist/commands/config.js +1 -0
- package/dist/commands/debug.js +45 -41
- package/dist/commands/export.d.ts +13 -0
- package/dist/commands/export.js +125 -0
- package/dist/commands/import.d.ts +12 -0
- package/dist/commands/import.js +150 -0
- package/dist/commands/init.js +0 -10
- package/dist/commands/keys.d.ts +25 -0
- package/dist/commands/keys.js +294 -0
- package/dist/commands/org.d.ts +13 -0
- package/dist/commands/org.js +118 -0
- package/dist/commands/projects.d.ts +31 -0
- package/dist/commands/projects.js +295 -24
- package/dist/commands/pull.js +40 -95
- package/dist/commands/team.d.ts +29 -0
- package/dist/commands/team.js +270 -0
- package/dist/config.d.ts +1 -0
- package/dist/index.js +357 -6
- package/package.json +53 -7
- package/NPM_PUBLISH_GUIDE.md +0 -293
- package/QUICK_PUBLISH.md +0 -64
- package/SECURITY_FIX.md +0 -167
- package/dist/supabase.d.ts +0 -14
- package/dist/supabase.js +0 -30
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "langctl",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Translation management CLI for developers. Manage i18n translations, export to 6 formats (iOS, Android, Flutter, i18next), import translations, and collaborate with teams. Affordable alternative to Lokalise and Crowdin.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"langctl": "
|
|
8
|
+
"langctl": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "rm -rf dist && tsc",
|
|
12
12
|
"dev": "tsx src/index.ts",
|
|
13
13
|
"start": "node dist/index.js",
|
|
14
14
|
"prepublishOnly": "npm run build",
|
|
@@ -24,13 +24,60 @@
|
|
|
24
24
|
"translations",
|
|
25
25
|
"translate",
|
|
26
26
|
"language",
|
|
27
|
-
"multilingual"
|
|
27
|
+
"multilingual",
|
|
28
|
+
"translation-management",
|
|
29
|
+
"localization-management",
|
|
30
|
+
"translation-tool",
|
|
31
|
+
"i18next",
|
|
32
|
+
"developer-tools",
|
|
33
|
+
"devtools",
|
|
34
|
+
"dev-tool",
|
|
35
|
+
"ios",
|
|
36
|
+
"android",
|
|
37
|
+
"flutter",
|
|
38
|
+
"react",
|
|
39
|
+
"angular",
|
|
40
|
+
"vue",
|
|
41
|
+
"react-native",
|
|
42
|
+
"json",
|
|
43
|
+
"xml",
|
|
44
|
+
"arb",
|
|
45
|
+
"strings",
|
|
46
|
+
"automation",
|
|
47
|
+
"ci-cd",
|
|
48
|
+
"cicd",
|
|
49
|
+
"continuous-integration",
|
|
50
|
+
"workflow",
|
|
51
|
+
"export",
|
|
52
|
+
"import",
|
|
53
|
+
"translation-export",
|
|
54
|
+
"translation-import",
|
|
55
|
+
"team",
|
|
56
|
+
"collaboration",
|
|
57
|
+
"multilanguage",
|
|
58
|
+
"multi-language",
|
|
59
|
+
"lokalise-alternative",
|
|
60
|
+
"crowdin-alternative",
|
|
61
|
+
"phrase-alternative",
|
|
62
|
+
"affordable",
|
|
63
|
+
"free",
|
|
64
|
+
"gettext",
|
|
65
|
+
"po",
|
|
66
|
+
"locale",
|
|
67
|
+
"translation-keys",
|
|
68
|
+
"localization-tool",
|
|
69
|
+
"string-management",
|
|
70
|
+
"mobile-localization",
|
|
71
|
+
"web-localization",
|
|
72
|
+
"app-localization",
|
|
73
|
+
"saas",
|
|
74
|
+
"api"
|
|
28
75
|
],
|
|
29
76
|
"author": "Siddharth Saxena <hello@langctl.com>",
|
|
30
77
|
"license": "MIT",
|
|
31
78
|
"repository": {
|
|
32
79
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/siddharthsaxena0/langctl.git"
|
|
80
|
+
"url": "git+https://github.com/siddharthsaxena0/langctl.git"
|
|
34
81
|
},
|
|
35
82
|
"bugs": {
|
|
36
83
|
"url": "https://github.com/siddharthsaxena0/langctl/issues"
|
|
@@ -40,7 +87,6 @@
|
|
|
40
87
|
"node": ">=16.0.0"
|
|
41
88
|
},
|
|
42
89
|
"dependencies": {
|
|
43
|
-
"@supabase/supabase-js": "^2.89.0",
|
|
44
90
|
"chalk": "^5.6.2",
|
|
45
91
|
"commander": "^14.0.2",
|
|
46
92
|
"conf": "^15.0.2",
|
package/NPM_PUBLISH_GUIDE.md
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
# 🚀 Publishing Langctl CLI to npm
|
|
2
|
-
|
|
3
|
-
**Date:** January 5, 2026
|
|
4
|
-
**Package:** langctl
|
|
5
|
-
**Version:** 0.1.0
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## ✅ Pre-Publish Checklist
|
|
10
|
-
|
|
11
|
-
Before publishing, verify these items:
|
|
12
|
-
|
|
13
|
-
- [x] Package name available: `langctl` ✅
|
|
14
|
-
- [x] README.md complete with examples ✅
|
|
15
|
-
- [x] package.json properly configured ✅
|
|
16
|
-
- [x] .npmignore configured ✅
|
|
17
|
-
- [x] TypeScript source code ready ✅
|
|
18
|
-
- [x] License file present (MIT) ✅
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 📋 Step-by-Step Publishing Guide
|
|
23
|
-
|
|
24
|
-
### Step 1: Verify npm Login
|
|
25
|
-
|
|
26
|
-
Check if you're logged into npm:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm whoami
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**If not logged in:**
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm login
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Enter your credentials:
|
|
39
|
-
- Username
|
|
40
|
-
- Password
|
|
41
|
-
- Email
|
|
42
|
-
- One-time password (if 2FA enabled)
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
### Step 2: Final Build & Test
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
cd /Users/siddharthsaxena/Documents/projects/langctl/langctl-cli
|
|
50
|
-
|
|
51
|
-
# Clean previous build
|
|
52
|
-
rm -rf dist/
|
|
53
|
-
|
|
54
|
-
# Fresh build
|
|
55
|
-
npm run build
|
|
56
|
-
|
|
57
|
-
# Verify build succeeded
|
|
58
|
-
ls -la dist/
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Expected:** You should see `.js` and `.d.ts` files in dist/
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
### Step 3: Test Package Locally
|
|
66
|
-
|
|
67
|
-
Before publishing, test the package works:
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# Link package globally for testing
|
|
71
|
-
npm link
|
|
72
|
-
|
|
73
|
-
# Test the CLI
|
|
74
|
-
langctl --version
|
|
75
|
-
langctl --help
|
|
76
|
-
|
|
77
|
-
# If it works, unlink
|
|
78
|
-
npm unlink -g langctl
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
### Step 4: Dry Run (Recommended)
|
|
84
|
-
|
|
85
|
-
See what will be published WITHOUT actually publishing:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
npm pack --dry-run
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
This shows:
|
|
92
|
-
- ✅ Files that will be included
|
|
93
|
-
- ✅ Package size
|
|
94
|
-
- ✅ No errors
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
### Step 5: Create Package Tarball (Optional)
|
|
99
|
-
|
|
100
|
-
Create actual tarball to inspect:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
npm pack
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
This creates: `langctl-0.1.0.tgz`
|
|
107
|
-
|
|
108
|
-
**To inspect:**
|
|
109
|
-
```bash
|
|
110
|
-
tar -xzf langctl-0.1.0.tgz
|
|
111
|
-
ls -la package/
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Clean up after:**
|
|
115
|
-
```bash
|
|
116
|
-
rm langctl-0.1.0.tgz
|
|
117
|
-
rm -rf package/
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
### Step 6: Publish to npm! 🚀
|
|
123
|
-
|
|
124
|
-
**First time publishing (public package):**
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npm publish --access public
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Expected output:**
|
|
131
|
-
```
|
|
132
|
-
npm notice
|
|
133
|
-
npm notice 📦 langctl@0.1.0
|
|
134
|
-
npm notice === Tarball Contents ===
|
|
135
|
-
npm notice 1.1kB LICENSE
|
|
136
|
-
npm notice 2.3kB README.md
|
|
137
|
-
npm notice 845B package.json
|
|
138
|
-
npm notice 15.2kB dist/...
|
|
139
|
-
npm notice === Tarball Details ===
|
|
140
|
-
npm notice name: langctl
|
|
141
|
-
npm notice version: 0.1.0
|
|
142
|
-
npm notice package size: XX.X kB
|
|
143
|
-
npm notice unpacked size: XXX.X kB
|
|
144
|
-
npm notice total files: XX
|
|
145
|
-
npm notice
|
|
146
|
-
+ langctl@0.1.0
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
### Step 7: Verify Publication
|
|
152
|
-
|
|
153
|
-
**Check on npm:**
|
|
154
|
-
1. Visit: https://www.npmjs.com/package/langctl
|
|
155
|
-
2. Verify README displays correctly
|
|
156
|
-
3. Check version number
|
|
157
|
-
|
|
158
|
-
**Test installation:**
|
|
159
|
-
```bash
|
|
160
|
-
# In a different directory
|
|
161
|
-
npx langctl@latest --version
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## 🎉 Success! Package Published
|
|
167
|
-
|
|
168
|
-
Your CLI is now available globally at:
|
|
169
|
-
- **npm:** https://www.npmjs.com/package/langctl
|
|
170
|
-
- **Install:** `npm install -g langctl`
|
|
171
|
-
- **Use:** `npx langctl`
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## 📊 Post-Publish Tasks
|
|
176
|
-
|
|
177
|
-
### Update Landing Page
|
|
178
|
-
|
|
179
|
-
Add npm install instructions to langctl.com:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
npm install -g langctl
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Update README (if needed)
|
|
186
|
-
|
|
187
|
-
If you notice issues, you can publish patches:
|
|
188
|
-
|
|
189
|
-
```bash
|
|
190
|
-
# Fix README or other files
|
|
191
|
-
# Bump version
|
|
192
|
-
npm version patch # 0.1.0 → 0.1.1
|
|
193
|
-
|
|
194
|
-
# Rebuild and republish
|
|
195
|
-
npm run build
|
|
196
|
-
npm publish
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Monitor npm Stats
|
|
200
|
-
|
|
201
|
-
Check download stats:
|
|
202
|
-
- https://www.npmjs.com/package/langctl
|
|
203
|
-
- https://npmtrends.com/langctl
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
## 🔧 Troubleshooting
|
|
208
|
-
|
|
209
|
-
### Error: "You do not have permission to publish"
|
|
210
|
-
|
|
211
|
-
**Solution:**
|
|
212
|
-
```bash
|
|
213
|
-
npm login
|
|
214
|
-
npm whoami # Verify correct account
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Error: "Package name already exists"
|
|
218
|
-
|
|
219
|
-
**Solution:** The name is taken. Since you reserved it, make sure you're logged in correctly.
|
|
220
|
-
|
|
221
|
-
### Error: "Must be logged in to publish"
|
|
222
|
-
|
|
223
|
-
**Solution:**
|
|
224
|
-
```bash
|
|
225
|
-
npm login
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Build errors
|
|
229
|
-
|
|
230
|
-
**Solution:**
|
|
231
|
-
```bash
|
|
232
|
-
rm -rf node_modules/ dist/
|
|
233
|
-
npm install
|
|
234
|
-
npm run build
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
---
|
|
238
|
-
|
|
239
|
-
## 📈 Version Updates (Future)
|
|
240
|
-
|
|
241
|
-
**Patch (bug fixes):** 0.1.0 → 0.1.1
|
|
242
|
-
```bash
|
|
243
|
-
npm version patch
|
|
244
|
-
npm run build
|
|
245
|
-
npm publish
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Minor (new features):** 0.1.0 → 0.2.0
|
|
249
|
-
```bash
|
|
250
|
-
npm version minor
|
|
251
|
-
npm run build
|
|
252
|
-
npm publish
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**Major (breaking changes):** 0.1.0 → 1.0.0
|
|
256
|
-
```bash
|
|
257
|
-
npm version major
|
|
258
|
-
npm run build
|
|
259
|
-
npm publish
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## ✅ Final Checklist
|
|
265
|
-
|
|
266
|
-
Before running `npm publish`:
|
|
267
|
-
|
|
268
|
-
- [ ] Logged into npm (`npm whoami`)
|
|
269
|
-
- [ ] Build succeeded (`npm run build`)
|
|
270
|
-
- [ ] Local test passed (`npm link` + test commands)
|
|
271
|
-
- [ ] Dry run clean (`npm pack --dry-run`)
|
|
272
|
-
- [ ] Ready to publish! (`npm publish --access public`)
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## 🎯 Quick Command Summary
|
|
277
|
-
|
|
278
|
-
```bash
|
|
279
|
-
# From langctl-cli directory:
|
|
280
|
-
npm whoami # Verify login
|
|
281
|
-
npm run build # Build TypeScript
|
|
282
|
-
npm pack --dry-run # Preview package
|
|
283
|
-
npm publish --access public # Publish!
|
|
284
|
-
npx langctl@latest --version # Verify
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
**Good luck! You're about to publish your first npm package! 🚀**
|
|
290
|
-
|
|
291
|
-
**Questions? Issues?**
|
|
292
|
-
- npm support: https://www.npmjs.com/support
|
|
293
|
-
- Package page: https://www.npmjs.com/package/langctl
|
package/QUICK_PUBLISH.md
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# 🚀 PUBLISH LANGCTL - QUICK COMMANDS
|
|
2
|
-
|
|
3
|
-
**Run these commands in order on YOUR MAC:**
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
# 1. Navigate to CLI directory
|
|
7
|
-
cd /Users/siddharthsaxena/Documents/projects/langctl/langctl-cli
|
|
8
|
-
|
|
9
|
-
# 2. Check npm login
|
|
10
|
-
npm whoami
|
|
11
|
-
|
|
12
|
-
# 3. If not logged in:
|
|
13
|
-
npm login
|
|
14
|
-
|
|
15
|
-
# 4. Build the package
|
|
16
|
-
npm run build
|
|
17
|
-
|
|
18
|
-
# 5. Test locally (optional but recommended)
|
|
19
|
-
npm link
|
|
20
|
-
langctl --version
|
|
21
|
-
langctl --help
|
|
22
|
-
npm unlink -g langctl
|
|
23
|
-
|
|
24
|
-
# 6. Dry run to preview
|
|
25
|
-
npm pack --dry-run
|
|
26
|
-
|
|
27
|
-
# 7. PUBLISH! 🚀
|
|
28
|
-
npm publish --access public
|
|
29
|
-
|
|
30
|
-
# 8. Verify it worked
|
|
31
|
-
npx langctl@latest --version
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## ✅ Expected Result
|
|
37
|
-
|
|
38
|
-
After `npm publish`, you should see:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
+ langctl@0.1.0
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Then check: https://www.npmjs.com/package/langctl
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 🎉 That's It!
|
|
49
|
-
|
|
50
|
-
Your CLI is now installable worldwide:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
npm install -g langctl
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
or
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
npx langctl --help
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
**Full guide:** See `NPM_PUBLISH_GUIDE.md` for detailed instructions and troubleshooting.
|
package/SECURITY_FIX.md
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# 🔒 Security Fix - Supabase Credentials
|
|
2
|
-
|
|
3
|
-
**Date:** January 5, 2026
|
|
4
|
-
**Issue:** Supabase credentials were being stored in user config files
|
|
5
|
-
**Status:** ✅ FIXED
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🚨 What Was Wrong
|
|
10
|
-
|
|
11
|
-
Previously, the CLI was:
|
|
12
|
-
- ❌ Storing Supabase URL in `~/.langctl/config.json`
|
|
13
|
-
- ❌ Storing Supabase anon key in `~/.langctl/config.json`
|
|
14
|
-
- ❌ Asking users about "Supabase configuration" during init
|
|
15
|
-
- ❌ Exposing backend implementation details to users
|
|
16
|
-
|
|
17
|
-
**Why this was bad:**
|
|
18
|
-
- Users could see our backend credentials
|
|
19
|
-
- Users could manipulate Supabase connection
|
|
20
|
-
- Exposed unnecessary implementation details
|
|
21
|
-
- Confused users with technical jargon
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## ✅ What's Fixed
|
|
26
|
-
|
|
27
|
-
Now the CLI:
|
|
28
|
-
- ✅ Hardcodes Supabase credentials in source code
|
|
29
|
-
- ✅ Only stores user credentials (API key, org ID, preferences)
|
|
30
|
-
- ✅ Users never see or interact with Supabase
|
|
31
|
-
- ✅ Clean, simple user experience
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 📄 Files Changed
|
|
36
|
-
|
|
37
|
-
### 1. `src/config.ts`
|
|
38
|
-
**Removed from interface:**
|
|
39
|
-
```typescript
|
|
40
|
-
// REMOVED - no longer stored
|
|
41
|
-
supabaseUrl?: string;
|
|
42
|
-
supabaseAnonKey?: string;
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**Now only stores:**
|
|
46
|
-
```typescript
|
|
47
|
-
apiKey?: string; // User's API key
|
|
48
|
-
organizationId?: string; // User's org ID
|
|
49
|
-
organizationName?: string; // User's org name
|
|
50
|
-
defaultProject?: string; // User preference
|
|
51
|
-
defaultLanguage?: string; // User preference
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### 2. `src/supabase.ts`
|
|
55
|
-
**Before:**
|
|
56
|
-
```typescript
|
|
57
|
-
// BAD - pulled from user config
|
|
58
|
-
const supabaseUrl = config.get('supabaseUrl');
|
|
59
|
-
const supabaseAnonKey = config.get('supabaseAnonKey');
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**After:**
|
|
63
|
-
```typescript
|
|
64
|
-
// GOOD - hardcoded in source
|
|
65
|
-
const SUPABASE_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co';
|
|
66
|
-
const SUPABASE_ANON_KEY = 'eyJhbGci...';
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 3. `src/commands/init.ts`
|
|
70
|
-
**Before:**
|
|
71
|
-
```typescript
|
|
72
|
-
// BAD - saved to user config
|
|
73
|
-
config.set('supabaseUrl', SUPABASE_URL);
|
|
74
|
-
config.set('supabaseAnonKey', SUPABASE_ANON_KEY);
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**After:**
|
|
78
|
-
```typescript
|
|
79
|
-
// GOOD - just initializes, doesn't save
|
|
80
|
-
initializeSupabase();
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 4. `src/commands/config.ts`
|
|
84
|
-
**Before:**
|
|
85
|
-
```typescript
|
|
86
|
-
// BAD - displayed Supabase credentials
|
|
87
|
-
supabaseAnonKey: allConfig.supabaseAnonKey ? maskSensitive(...) : undefined
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**After:**
|
|
91
|
-
```typescript
|
|
92
|
-
// GOOD - only displays user data
|
|
93
|
-
apiKey: allConfig.apiKey ? maskApiKey(allConfig.apiKey) : undefined,
|
|
94
|
-
organizationId: allConfig.organizationId,
|
|
95
|
-
organizationName: allConfig.organizationName
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## 🔐 Security Notes
|
|
101
|
-
|
|
102
|
-
**Is it safe to hardcode Supabase credentials in the CLI?**
|
|
103
|
-
|
|
104
|
-
✅ **YES!** This is perfectly safe because:
|
|
105
|
-
|
|
106
|
-
1. **Anon key is designed for client-side use**
|
|
107
|
-
- It's meant to be public-facing
|
|
108
|
-
- Row Level Security (RLS) protects all data
|
|
109
|
-
- Users can only access what they're authorized for
|
|
110
|
-
|
|
111
|
-
2. **RLS policies enforce security**
|
|
112
|
-
- Users can only see their own organization data
|
|
113
|
-
- API key verification happens server-side (Edge Function)
|
|
114
|
-
- All operations are protected by RLS
|
|
115
|
-
|
|
116
|
-
3. **This is standard practice**
|
|
117
|
-
- Same as mobile apps that embed API credentials
|
|
118
|
-
- Same as web apps that expose client keys
|
|
119
|
-
- Backend security, not client security
|
|
120
|
-
|
|
121
|
-
**What if someone decompiles the CLI?**
|
|
122
|
-
- They'll see the Supabase URL and anon key
|
|
123
|
-
- But they CANNOT access data without a valid API key
|
|
124
|
-
- API keys are user-specific and verified server-side
|
|
125
|
-
- RLS prevents unauthorized access
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## 📊 What Users See Now
|
|
130
|
-
|
|
131
|
-
### Config File (`~/.langctl/config.json`)
|
|
132
|
-
```json
|
|
133
|
-
{
|
|
134
|
-
"apiKey": "lc_abc123...",
|
|
135
|
-
"organizationId": "uuid-here",
|
|
136
|
-
"organizationName": "My Company",
|
|
137
|
-
"defaultLanguage": "en"
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Clean and simple!** No backend implementation details.
|
|
142
|
-
|
|
143
|
-
### Running `langctl config`
|
|
144
|
-
```
|
|
145
|
-
📋 Langctl Configuration
|
|
146
|
-
|
|
147
|
-
apiKey: lc_abc123...wxyz
|
|
148
|
-
organizationId: 550e8400-e29b-41d4-a716-446655440000
|
|
149
|
-
organizationName: My Company
|
|
150
|
-
defaultLanguage: en
|
|
151
|
-
|
|
152
|
-
Config file: /Users/username/.langctl/config.json
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
**Only user-relevant information!**
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## ✅ Ready to Publish
|
|
160
|
-
|
|
161
|
-
This security fix is complete. The CLI now:
|
|
162
|
-
- ✅ Keeps backend credentials private
|
|
163
|
-
- ✅ Only exposes user data to users
|
|
164
|
-
- ✅ Maintains full security with RLS
|
|
165
|
-
- ✅ Provides clean user experience
|
|
166
|
-
|
|
167
|
-
**Safe to publish to npm!** 🚀
|
package/dist/supabase.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
/**
|
|
3
|
-
* Initialize Supabase client with hardcoded credentials
|
|
4
|
-
*/
|
|
5
|
-
export declare function initializeSupabase(): SupabaseClient;
|
|
6
|
-
/**
|
|
7
|
-
* Get existing Supabase client or initialize it
|
|
8
|
-
*/
|
|
9
|
-
export declare function getSupabase(): SupabaseClient;
|
|
10
|
-
/**
|
|
11
|
-
* Reset Supabase client (useful for tests)
|
|
12
|
-
*/
|
|
13
|
-
export declare function resetSupabase(): void;
|
|
14
|
-
//# sourceMappingURL=supabase.d.ts.map
|
package/dist/supabase.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { createClient } from '@supabase/supabase-js';
|
|
2
|
-
// Hardcoded Supabase credentials (safe for client-side use with RLS)
|
|
3
|
-
const SUPABASE_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co';
|
|
4
|
-
const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJjZ25tdmtna2JoYnh6emZsd2RiIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzQ3OTE4ODEsImV4cCI6MjA1MDM2Nzg4MX0.LqZYO8GGQfI-C9WCF_a2NTKqIrO1TDsPXU9LHRE8b0E';
|
|
5
|
-
let supabaseClient = null;
|
|
6
|
-
/**
|
|
7
|
-
* Initialize Supabase client with hardcoded credentials
|
|
8
|
-
*/
|
|
9
|
-
export function initializeSupabase() {
|
|
10
|
-
if (!supabaseClient) {
|
|
11
|
-
supabaseClient = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
12
|
-
}
|
|
13
|
-
return supabaseClient;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Get existing Supabase client or initialize it
|
|
17
|
-
*/
|
|
18
|
-
export function getSupabase() {
|
|
19
|
-
if (!supabaseClient) {
|
|
20
|
-
return initializeSupabase();
|
|
21
|
-
}
|
|
22
|
-
return supabaseClient;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Reset Supabase client (useful for tests)
|
|
26
|
-
*/
|
|
27
|
-
export function resetSupabase() {
|
|
28
|
-
supabaseClient = null;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=supabase.js.map
|