@keplog/cli 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/LICENSE +21 -0
- package/README.md +495 -0
- package/bin/keplog +2 -0
- package/dist/commands/delete.d.ts +3 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +158 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +131 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/issues.d.ts +3 -0
- package/dist/commands/issues.d.ts.map +1 -0
- package/dist/commands/issues.js +543 -0
- package/dist/commands/issues.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +104 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/releases.d.ts +3 -0
- package/dist/commands/releases.d.ts.map +1 -0
- package/dist/commands/releases.js +100 -0
- package/dist/commands/releases.js.map +1 -0
- package/dist/commands/upload.d.ts +3 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +76 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +57 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +155 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/uploader.d.ts +11 -0
- package/dist/lib/uploader.d.ts.map +1 -0
- package/dist/lib/uploader.js +171 -0
- package/dist/lib/uploader.js.map +1 -0
- package/jest.config.js +16 -0
- package/package.json +58 -0
- package/src/commands/delete.ts +186 -0
- package/src/commands/init.ts +137 -0
- package/src/commands/issues.ts +695 -0
- package/src/commands/list.ts +124 -0
- package/src/commands/releases.ts +122 -0
- package/src/commands/upload.ts +76 -0
- package/src/index.ts +31 -0
- package/src/lib/config.ts +138 -0
- package/src/lib/uploader.ts +168 -0
- package/tests/README.md +380 -0
- package/tests/config.test.ts +397 -0
- package/tests/uploader.test.ts +524 -0
- package/tsconfig.json +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Keplog Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
# Keplog CLI
|
|
2
|
+
|
|
3
|
+
Official command-line interface for [Keplog](https://keplog.com) - Error tracking and monitoring platform.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ā” **Interactive Setup** - Run `keplog init` to configure in seconds
|
|
8
|
+
- š¦ **Source Map Upload** - Upload source maps for error stack trace transformation
|
|
9
|
+
- š **Secure Configuration** - Local `.keplog.json` or global `~/.keplogrc` support
|
|
10
|
+
- š **Glob Patterns** - Flexible file matching with glob support
|
|
11
|
+
- šØ **Beautiful Output** - Progress indicators and colored terminal output
|
|
12
|
+
- š **Fast & Efficient** - Optimized upload performance
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Global Installation (Recommended)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @keplog/cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Local Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install --save-dev @keplog/cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Using npx (No installation required)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @keplog/cli upload --release=v1.0.0 --files="dist/**/*.map"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Initialize Configuration (Recommended)
|
|
37
|
+
|
|
38
|
+
Run the interactive setup wizard:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
keplog init
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This will prompt you for:
|
|
45
|
+
- Project ID
|
|
46
|
+
- API Key
|
|
47
|
+
- API URL (optional)
|
|
48
|
+
- Project name (optional)
|
|
49
|
+
|
|
50
|
+
Your credentials will be saved to `.keplog.json` in the current directory.
|
|
51
|
+
|
|
52
|
+
**Alternative:** Use global configuration with `keplog init --global` to save to `~/.keplogrc`.
|
|
53
|
+
|
|
54
|
+
### 2. Upload Source Maps
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
keplog upload --release=v1.0.0 --files="dist/**/*.map"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The CLI will automatically use credentials from `.keplog.json` or `~/.keplogrc`.
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
### Init Command
|
|
65
|
+
|
|
66
|
+
Initialize Keplog configuration for your project interactively.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
keplog init [options]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Options
|
|
73
|
+
|
|
74
|
+
| Option | Alias | Description |
|
|
75
|
+
|--------|-------|-------------|
|
|
76
|
+
| `--global` | `-g` | Save configuration globally (in ~/.keplogrc) |
|
|
77
|
+
| `--force` | `-f` | Overwrite existing configuration |
|
|
78
|
+
|
|
79
|
+
#### Examples
|
|
80
|
+
|
|
81
|
+
**Local configuration (project-specific):**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
keplog init
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Creates `.keplog.json` in the current directory.
|
|
88
|
+
|
|
89
|
+
**Global configuration (user-level):**
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
keplog init --global
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Creates `~/.keplogrc` in your home directory.
|
|
96
|
+
|
|
97
|
+
**Force overwrite:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
keplog init --force
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Configuration Priority
|
|
104
|
+
|
|
105
|
+
The CLI loads configuration in this order (first wins):
|
|
106
|
+
|
|
107
|
+
1. Command-line flags (`--project-id`, `--api-key`)
|
|
108
|
+
2. Local `.keplog.json` (in current directory or parent directories)
|
|
109
|
+
3. Global `~/.keplogrc` (in home directory)
|
|
110
|
+
4. Environment variables (`KEPLOG_PROJECT_ID`, `KEPLOG_API_KEY`)
|
|
111
|
+
|
|
112
|
+
### Upload Command
|
|
113
|
+
|
|
114
|
+
Upload source maps for a specific release version.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
keplog upload [options]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Options
|
|
121
|
+
|
|
122
|
+
| Option | Alias | Description | Required | Default |
|
|
123
|
+
|--------|-------|-------------|----------|---------|
|
|
124
|
+
| `--release <version>` | `-r` | Release version (e.g., v1.0.0) | ā
Yes | - |
|
|
125
|
+
| `--files <patterns...>` | `-f` | Source map file patterns (glob) | ā
Yes | - |
|
|
126
|
+
| `--project-id <id>` | `-p` | Project ID | ā
Yes* | `KEPLOG_PROJECT_ID` |
|
|
127
|
+
| `--api-key <key>` | `-k` | API Key | ā
Yes* | `KEPLOG_API_KEY` |
|
|
128
|
+
| `--api-url <url>` | `-u` | API URL | ā No | `https://api.keplog.com` |
|
|
129
|
+
| `--verbose` | `-v` | Verbose output | ā No | `false` |
|
|
130
|
+
|
|
131
|
+
\* Required, but can be provided via environment variables
|
|
132
|
+
|
|
133
|
+
#### Examples
|
|
134
|
+
|
|
135
|
+
**Basic upload:**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
keplog upload --release=v1.0.0 --files="dist/**/*.map"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Multiple file patterns:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
keplog upload \
|
|
145
|
+
--release=v1.0.0 \
|
|
146
|
+
--files="dist/js/**/*.map" \
|
|
147
|
+
--files="dist/css/**/*.map"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**With explicit credentials:**
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
keplog upload \
|
|
154
|
+
--release=v1.0.0 \
|
|
155
|
+
--files="build/**/*.map" \
|
|
156
|
+
--project-id="abc-123-def-456" \
|
|
157
|
+
--api-key="proj_xyz789"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Verbose output:**
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
keplog upload \
|
|
164
|
+
--release=v1.0.0 \
|
|
165
|
+
--files="*.map" \
|
|
166
|
+
--verbose
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Custom API URL (self-hosted):**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
keplog upload \
|
|
173
|
+
--release=v1.0.0 \
|
|
174
|
+
--files="*.map" \
|
|
175
|
+
--api-url="https://keplog.yourcompany.com"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## CI/CD Integration
|
|
179
|
+
|
|
180
|
+
### GitHub Actions
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
name: Deploy with Source Maps
|
|
184
|
+
|
|
185
|
+
on:
|
|
186
|
+
push:
|
|
187
|
+
tags:
|
|
188
|
+
- 'v*'
|
|
189
|
+
|
|
190
|
+
jobs:
|
|
191
|
+
deploy:
|
|
192
|
+
runs-on: ubuntu-latest
|
|
193
|
+
steps:
|
|
194
|
+
- uses: actions/checkout@v3
|
|
195
|
+
|
|
196
|
+
- name: Build Application
|
|
197
|
+
run: npm run build
|
|
198
|
+
|
|
199
|
+
- name: Upload Source Maps
|
|
200
|
+
run: npx @keplog/cli upload --release=${{ github.ref_name }} --files="dist/**/*.map"
|
|
201
|
+
env:
|
|
202
|
+
KEPLOG_PROJECT_ID: ${{ secrets.KEPLOG_PROJECT_ID }}
|
|
203
|
+
KEPLOG_API_KEY: ${{ secrets.KEPLOG_API_KEY }}
|
|
204
|
+
|
|
205
|
+
- name: Deploy
|
|
206
|
+
run: npm run deploy
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### GitLab CI
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
deploy:
|
|
213
|
+
stage: deploy
|
|
214
|
+
script:
|
|
215
|
+
- npm run build
|
|
216
|
+
- npx @keplog/cli upload --release=${CI_COMMIT_TAG} --files="dist/**/*.map"
|
|
217
|
+
- npm run deploy
|
|
218
|
+
variables:
|
|
219
|
+
KEPLOG_PROJECT_ID: $KEPLOG_PROJECT_ID
|
|
220
|
+
KEPLOG_API_KEY: $KEPLOG_API_KEY
|
|
221
|
+
only:
|
|
222
|
+
- tags
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### CircleCI
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
version: 2.1
|
|
229
|
+
|
|
230
|
+
jobs:
|
|
231
|
+
deploy:
|
|
232
|
+
docker:
|
|
233
|
+
- image: node:18
|
|
234
|
+
steps:
|
|
235
|
+
- checkout
|
|
236
|
+
- run:
|
|
237
|
+
name: Build
|
|
238
|
+
command: npm run build
|
|
239
|
+
- run:
|
|
240
|
+
name: Upload Source Maps
|
|
241
|
+
command: npx @keplog/cli upload --release=${CIRCLE_TAG} --files="dist/**/*.map"
|
|
242
|
+
- run:
|
|
243
|
+
name: Deploy
|
|
244
|
+
command: npm run deploy
|
|
245
|
+
|
|
246
|
+
workflows:
|
|
247
|
+
deploy:
|
|
248
|
+
jobs:
|
|
249
|
+
- deploy:
|
|
250
|
+
filters:
|
|
251
|
+
tags:
|
|
252
|
+
only: /^v.*/
|
|
253
|
+
branches:
|
|
254
|
+
ignore: /.*/
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Jenkins
|
|
258
|
+
|
|
259
|
+
```groovy
|
|
260
|
+
pipeline {
|
|
261
|
+
agent any
|
|
262
|
+
|
|
263
|
+
environment {
|
|
264
|
+
KEPLOG_PROJECT_ID = credentials('keplog-project-id')
|
|
265
|
+
KEPLOG_API_KEY = credentials('keplog-api-key')
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
stages {
|
|
269
|
+
stage('Build') {
|
|
270
|
+
steps {
|
|
271
|
+
sh 'npm run build'
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
stage('Upload Source Maps') {
|
|
276
|
+
steps {
|
|
277
|
+
sh 'npx @keplog/cli upload --release=${GIT_TAG} --files="dist/**/*.map"'
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
stage('Deploy') {
|
|
282
|
+
steps {
|
|
283
|
+
sh 'npm run deploy'
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## npm Scripts Integration
|
|
291
|
+
|
|
292
|
+
Add to your `package.json`:
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"scripts": {
|
|
297
|
+
"build": "webpack --mode production",
|
|
298
|
+
"upload-sourcemaps": "keplog upload --release=$npm_package_version --files='dist/**/*.map'",
|
|
299
|
+
"deploy": "npm run build && npm run upload-sourcemaps && npm run deploy-to-prod"
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Then run:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npm run deploy
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Environment Variables
|
|
311
|
+
|
|
312
|
+
The CLI supports the following environment variables:
|
|
313
|
+
|
|
314
|
+
| Variable | Description |
|
|
315
|
+
|----------|-------------|
|
|
316
|
+
| `KEPLOG_PROJECT_ID` | Your Keplog project ID |
|
|
317
|
+
| `KEPLOG_API_KEY` | Your Keplog API key |
|
|
318
|
+
| `KEPLOG_API_URL` | Custom API URL (optional) |
|
|
319
|
+
| `DEBUG` | Enable debug output (shows stack traces) |
|
|
320
|
+
|
|
321
|
+
Create a `.env` file in your project root:
|
|
322
|
+
|
|
323
|
+
```env
|
|
324
|
+
KEPLOG_PROJECT_ID=abc-123-def-456
|
|
325
|
+
KEPLOG_API_KEY=proj_xyz789
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Getting Your Credentials
|
|
329
|
+
|
|
330
|
+
### Project ID and API Key
|
|
331
|
+
|
|
332
|
+
1. Go to your project settings in Keplog dashboard
|
|
333
|
+
2. Navigate to **Settings ā General**
|
|
334
|
+
3. Find the **Project Credentials** section
|
|
335
|
+
4. Copy your **Project ID** and **API Key**
|
|
336
|
+
|
|
337
|
+
## Glob Patterns
|
|
338
|
+
|
|
339
|
+
The `--files` option supports glob patterns for flexible file matching:
|
|
340
|
+
|
|
341
|
+
| Pattern | Description | Example |
|
|
342
|
+
|---------|-------------|---------|
|
|
343
|
+
| `*.map` | All .map files in current directory | `bundle.js.map` |
|
|
344
|
+
| `**/*.map` | All .map files recursively | `dist/js/bundle.js.map` |
|
|
345
|
+
| `dist/**/*.map` | All .map files in dist/ | `dist/assets/main.js.map` |
|
|
346
|
+
| `{js,css}/**/*.map` | .map files in js/ and css/ | `js/app.js.map` |
|
|
347
|
+
|
|
348
|
+
## Best Practices
|
|
349
|
+
|
|
350
|
+
### 1. Use Semantic Versioning
|
|
351
|
+
|
|
352
|
+
Always use semantic versioning for your releases:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
keplog upload --release=v1.2.3 --files="dist/**/*.map"
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### 2. Match Release with Error Tags
|
|
359
|
+
|
|
360
|
+
Ensure your application sends the same release version:
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
keplog.init({
|
|
364
|
+
apiKey: 'your-api-key',
|
|
365
|
+
release: 'v1.2.3' // Must match uploaded source maps
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### 3. Don't Deploy Source Maps
|
|
370
|
+
|
|
371
|
+
Never deploy `.map` files to production. Upload them to Keplog, then exclude from deployment:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# Upload to Keplog
|
|
375
|
+
keplog upload --release=v1.0.0 --files="dist/**/*.map"
|
|
376
|
+
|
|
377
|
+
# Remove from deployment
|
|
378
|
+
rm dist/**/*.map
|
|
379
|
+
|
|
380
|
+
# Then deploy
|
|
381
|
+
npm run deploy
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### 4. Automate in CI/CD
|
|
385
|
+
|
|
386
|
+
Integrate source map uploads into your CI/CD pipeline for automatic uploads on every release.
|
|
387
|
+
|
|
388
|
+
### 5. Use Environment Variables
|
|
389
|
+
|
|
390
|
+
Store credentials as environment variables or secrets, never commit them to git:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# ā
Good
|
|
394
|
+
export KEPLOG_API_KEY="proj_xyz789"
|
|
395
|
+
keplog upload --release=v1.0.0 --files="*.map"
|
|
396
|
+
|
|
397
|
+
# ā Bad
|
|
398
|
+
keplog upload --release=v1.0.0 --files="*.map" --api-key="proj_xyz789" # Visible in history
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Troubleshooting
|
|
402
|
+
|
|
403
|
+
### Error: "Source map integration not configured"
|
|
404
|
+
|
|
405
|
+
**Solution**: Configure the S3/GCS storage plugin in your Keplog project settings first.
|
|
406
|
+
|
|
407
|
+
1. Go to Project Settings ā Plugins
|
|
408
|
+
2. Enable a source map storage plugin (S3, GCS, or HTTP)
|
|
409
|
+
3. Configure your storage credentials
|
|
410
|
+
|
|
411
|
+
### Error: "Project ID mismatch"
|
|
412
|
+
|
|
413
|
+
**Solution**: Ensure your API key matches the project ID:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# Wrong
|
|
417
|
+
keplog upload --project-id=project-A --api-key=key-for-project-B
|
|
418
|
+
|
|
419
|
+
# Correct
|
|
420
|
+
keplog upload --project-id=project-A --api-key=key-for-project-A
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Error: "No files matched the patterns"
|
|
424
|
+
|
|
425
|
+
**Solution**: Check your glob patterns:
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
# See what files exist
|
|
429
|
+
ls -la dist/**/*.map
|
|
430
|
+
|
|
431
|
+
# Adjust your pattern
|
|
432
|
+
keplog upload --release=v1.0.0 --files="dist/static/**/*.map"
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Error: "Connection refused"
|
|
436
|
+
|
|
437
|
+
**Solution**: Check your API URL and internet connection:
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# Test connection
|
|
441
|
+
curl https://api.keplog.com/health
|
|
442
|
+
|
|
443
|
+
# Use custom URL if self-hosted
|
|
444
|
+
keplog upload --api-url="https://keplog.yourcompany.com" ...
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Development
|
|
448
|
+
|
|
449
|
+
### Build from Source
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
# Clone the repository
|
|
453
|
+
git clone https://github.com/keplog/keplog-cli.git
|
|
454
|
+
cd keplog-cli
|
|
455
|
+
|
|
456
|
+
# Install dependencies
|
|
457
|
+
npm install
|
|
458
|
+
|
|
459
|
+
# Build
|
|
460
|
+
npm run build
|
|
461
|
+
|
|
462
|
+
# Link locally
|
|
463
|
+
npm link
|
|
464
|
+
|
|
465
|
+
# Test
|
|
466
|
+
keplog upload --help
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Watch Mode
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
npm run dev
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## Support
|
|
476
|
+
|
|
477
|
+
- š§ Email: support@keplog.com
|
|
478
|
+
- š Documentation: https://docs.keplog.com
|
|
479
|
+
- š Issues: https://github.com/keplog/keplog-cli/issues
|
|
480
|
+
- š¬ Discord: https://discord.gg/keplog
|
|
481
|
+
|
|
482
|
+
## License
|
|
483
|
+
|
|
484
|
+
MIT Ā© Keplog Team
|
|
485
|
+
|
|
486
|
+
## Changelog
|
|
487
|
+
|
|
488
|
+
### v1.0.0 (2025-01-15)
|
|
489
|
+
|
|
490
|
+
- ⨠Initial release
|
|
491
|
+
- š¦ Source map upload functionality
|
|
492
|
+
- šØ Beautiful CLI interface with progress indicators
|
|
493
|
+
- š Glob pattern support
|
|
494
|
+
- š API key authentication
|
|
495
|
+
- š Comprehensive documentation
|
package/bin/keplog
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,aAAa,SAuKtB,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deleteCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
11
|
+
const config_js_1 = require("../lib/config.js");
|
|
12
|
+
exports.deleteCommand = new commander_1.Command('delete')
|
|
13
|
+
.description('Delete source maps for a specific release')
|
|
14
|
+
.option('-r, --release <version>', 'Release version')
|
|
15
|
+
.option('-f, --file <filename>', 'Specific file to delete (optional - omit to delete all)')
|
|
16
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
17
|
+
.option('-p, --project-id <id>', 'Project ID (overrides config)')
|
|
18
|
+
.option('-k, --api-key <key>', 'API key (overrides config)')
|
|
19
|
+
.option('-u, --api-url <url>', 'API URL (overrides config)')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
try {
|
|
22
|
+
// Read config from file (priority: local > global > env)
|
|
23
|
+
const config = config_js_1.ConfigManager.getConfig();
|
|
24
|
+
const release = options.release || process.env.KEPLOG_RELEASE;
|
|
25
|
+
const filename = options.file;
|
|
26
|
+
const skipConfirm = options.yes || false;
|
|
27
|
+
const projectId = options.projectId || config.projectId;
|
|
28
|
+
const apiKey = options.apiKey || config.apiKey;
|
|
29
|
+
const apiUrl = options.apiUrl || config.apiUrl || 'https://api.keplog.com';
|
|
30
|
+
// Validate required parameters
|
|
31
|
+
if (!projectId) {
|
|
32
|
+
console.error(chalk_1.default.red('\nā Error: Project ID is required\n'));
|
|
33
|
+
console.log('Options:');
|
|
34
|
+
console.log(' 1. Run: keplog init (recommended)');
|
|
35
|
+
console.log(' 2. Use flag: --project-id=<your-project-id>');
|
|
36
|
+
console.log(' 3. Set env: KEPLOG_PROJECT_ID=<your-project-id>\n');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
if (!apiKey) {
|
|
40
|
+
console.error(chalk_1.default.red('\nā Error: API key is required\n'));
|
|
41
|
+
console.log('Options:');
|
|
42
|
+
console.log(' 1. Run: keplog init (recommended)');
|
|
43
|
+
console.log(' 2. Use flag: --api-key=<your-api-key>');
|
|
44
|
+
console.log(' 3. Set env: KEPLOG_API_KEY=<your-api-key>\n');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
if (!release) {
|
|
48
|
+
console.error(chalk_1.default.red('\nā Error: Release version is required\n'));
|
|
49
|
+
console.log('Options:');
|
|
50
|
+
console.log(' 1. Use flag: --release=v1.0.0');
|
|
51
|
+
console.log(' 2. Set env: KEPLOG_RELEASE=v1.0.0\n');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
console.log(chalk_1.default.bold.red('\nšļø Keplog Source Maps - Delete\n'));
|
|
55
|
+
console.log(`Release: ${chalk_1.default.yellow(release)}`);
|
|
56
|
+
console.log(`Project ID: ${chalk_1.default.gray(projectId)}`);
|
|
57
|
+
if (filename) {
|
|
58
|
+
console.log(`File: ${chalk_1.default.yellow(filename)}\n`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.log(chalk_1.default.yellow('Target: All source maps for this release\n'));
|
|
62
|
+
}
|
|
63
|
+
// If deleting all files, fetch and show the list first
|
|
64
|
+
let filesToDelete = [];
|
|
65
|
+
if (!filename) {
|
|
66
|
+
const spinner = (0, ora_1.default)('Fetching source maps...').start();
|
|
67
|
+
const listUrl = `${apiUrl}/api/v1/cli/projects/${projectId}/sourcemaps?release=${encodeURIComponent(release)}`;
|
|
68
|
+
const listResponse = await fetch(listUrl, {
|
|
69
|
+
method: 'GET',
|
|
70
|
+
headers: {
|
|
71
|
+
'X-API-Key': apiKey,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (!listResponse.ok) {
|
|
75
|
+
const error = await listResponse.json();
|
|
76
|
+
spinner.fail(chalk_1.default.red('Failed to fetch source maps'));
|
|
77
|
+
console.error(chalk_1.default.red(`\nā Error: ${error.error || 'Unknown error'}\n`));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const data = await listResponse.json();
|
|
81
|
+
spinner.succeed(`Found ${data.count} source map${data.count !== 1 ? 's' : ''}`);
|
|
82
|
+
if (data.count === 0) {
|
|
83
|
+
console.log(chalk_1.default.yellow('\nNo source maps found for this release.\n'));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
filesToDelete = data.source_maps.map(f => f.Filename);
|
|
87
|
+
console.log(chalk_1.default.gray('\nFiles to be deleted:'));
|
|
88
|
+
for (const file of data.source_maps) {
|
|
89
|
+
console.log(` ${chalk_1.default.red('ā')} ${file.Filename}`);
|
|
90
|
+
}
|
|
91
|
+
console.log('');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
filesToDelete = [filename];
|
|
95
|
+
}
|
|
96
|
+
// Confirmation prompt (unless --yes flag is used)
|
|
97
|
+
if (!skipConfirm) {
|
|
98
|
+
const message = filename
|
|
99
|
+
? `Are you sure you want to delete ${chalk_1.default.yellow(filename)} from release ${chalk_1.default.yellow(release)}?`
|
|
100
|
+
: `Are you sure you want to delete ${chalk_1.default.red.bold('ALL')} ${filesToDelete.length} source maps from release ${chalk_1.default.yellow(release)}?`;
|
|
101
|
+
const response = await (0, prompts_1.default)({
|
|
102
|
+
type: 'confirm',
|
|
103
|
+
name: 'confirmed',
|
|
104
|
+
message,
|
|
105
|
+
initial: false,
|
|
106
|
+
});
|
|
107
|
+
if (!response.confirmed) {
|
|
108
|
+
console.log(chalk_1.default.gray('\nDeletion cancelled.\n'));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Delete files
|
|
113
|
+
let deletedCount = 0;
|
|
114
|
+
let failedCount = 0;
|
|
115
|
+
const errors = [];
|
|
116
|
+
console.log(chalk_1.default.gray('\nDeleting source maps...\n'));
|
|
117
|
+
for (const file of filesToDelete) {
|
|
118
|
+
const spinner = (0, ora_1.default)(`Deleting ${file}...`).start();
|
|
119
|
+
try {
|
|
120
|
+
const deleteUrl = `${apiUrl}/api/v1/cli/projects/${projectId}/sourcemaps/${encodeURIComponent(file)}?release=${encodeURIComponent(release)}`;
|
|
121
|
+
const response = await fetch(deleteUrl, {
|
|
122
|
+
method: 'DELETE',
|
|
123
|
+
headers: {
|
|
124
|
+
'X-API-Key': apiKey,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const error = await response.json();
|
|
129
|
+
throw new Error(error.error || 'Unknown error');
|
|
130
|
+
}
|
|
131
|
+
spinner.succeed(chalk_1.default.green(`Deleted ${file}`));
|
|
132
|
+
deletedCount++;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
spinner.fail(chalk_1.default.red(`Failed to delete ${file}`));
|
|
136
|
+
errors.push(`${file}: ${error.message}`);
|
|
137
|
+
failedCount++;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Summary
|
|
141
|
+
console.log(chalk_1.default.bold('\nā
Deletion Complete!\n'));
|
|
142
|
+
console.log(`Release: ${chalk_1.default.yellow(release)}`);
|
|
143
|
+
console.log(`Deleted: ${chalk_1.default.green(deletedCount)} file${deletedCount !== 1 ? 's' : ''}`);
|
|
144
|
+
if (failedCount > 0) {
|
|
145
|
+
console.log(`Failed: ${chalk_1.default.red(failedCount)} file${failedCount !== 1 ? 's' : ''}\n`);
|
|
146
|
+
console.log(chalk_1.default.red.bold('ā ļø Errors:'));
|
|
147
|
+
for (const error of errors) {
|
|
148
|
+
console.log(` ${chalk_1.default.red('ā')} ${error}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
console.log('');
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error(chalk_1.default.red(`\nā Error: ${error.message}\n`));
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"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"}
|