@beaulewis/saas-cli 1.0.0 → 1.0.2
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/README.md +121 -2
- package/dist/chunk-FGZ7PLMQ.js +38 -0
- package/dist/chunk-FGZ7PLMQ.js.map +1 -0
- package/dist/{chunk-5BCEXHNM.js → chunk-JTMQREZ6.js} +57 -38
- package/dist/chunk-JTMQREZ6.js.map +1 -0
- package/dist/chunk-N2ONDKDL.js +28 -0
- package/dist/chunk-N2ONDKDL.js.map +1 -0
- package/dist/{chunk-N4OIAZSA.js → chunk-O53ZYAOB.js} +6 -4
- package/dist/{chunk-N4OIAZSA.js.map → chunk-O53ZYAOB.js.map} +1 -1
- package/dist/{chunk-3KD5CFV3.js → chunk-T7ZSH2YP.js} +2 -2
- package/dist/{chunk-ZD2ZSBK3.js → chunk-VG47XMO6.js} +158 -11
- package/dist/chunk-VG47XMO6.js.map +1 -0
- package/dist/{dart-DXLFNGHR.js → dart-WFKEB4KF.js} +5 -4
- package/dist/{dart-DXLFNGHR.js.map → dart-WFKEB4KF.js.map} +1 -1
- package/dist/{drift-XYY4D366.js → drift-XIAPJPJ4.js} +10 -5
- package/dist/drift-XIAPJPJ4.js.map +1 -0
- package/dist/error-U45TQYWL.js +20 -0
- package/dist/error-U45TQYWL.js.map +1 -0
- package/dist/{flutter-J5BYPVIW.js → flutter-PUTNWBGH.js} +5 -4
- package/dist/{flutter-J5BYPVIW.js.map → flutter-PUTNWBGH.js.map} +1 -1
- package/dist/{freezed-QXFQ4GJC.js → freezed-RF4SOWLU.js} +9 -4
- package/dist/freezed-RF4SOWLU.js.map +1 -0
- package/dist/{gorouter-QBMTTFVR.js → gorouter-F5XDDQPJ.js} +9 -4
- package/dist/gorouter-F5XDDQPJ.js.map +1 -0
- package/dist/index.js +166 -105
- package/dist/index.js.map +1 -1
- package/dist/{package-QO75XHBD.js → package-IKHU3CJM.js} +5 -4
- package/dist/{package-QO75XHBD.js.map → package-IKHU3CJM.js.map} +1 -1
- package/dist/{powersync-I3LR7TDN.js → powersync-P7WQ7LFM.js} +9 -4
- package/dist/powersync-P7WQ7LFM.js.map +1 -0
- package/dist/{repository-BAOVD3NG.js → repository-7F22RXMA.js} +9 -4
- package/dist/repository-7F22RXMA.js.map +1 -0
- package/dist/{riverpod-XUU656PM.js → riverpod-6JWBNWS4.js} +9 -4
- package/dist/riverpod-6JWBNWS4.js.map +1 -0
- package/dist/types-VBEUX6S5.js +11 -0
- package/dist/types-VBEUX6S5.js.map +1 -0
- package/dist/{widget-YDKHPRXM.js → widget-JPM73WJ2.js} +5 -4
- package/dist/{widget-YDKHPRXM.js.map → widget-JPM73WJ2.js.map} +1 -1
- package/package.json +2 -1
- package/dist/chunk-5BCEXHNM.js.map +0 -1
- package/dist/chunk-ZD2ZSBK3.js.map +0 -1
- package/dist/drift-XYY4D366.js.map +0 -1
- package/dist/freezed-QXFQ4GJC.js.map +0 -1
- package/dist/gorouter-QBMTTFVR.js.map +0 -1
- package/dist/powersync-I3LR7TDN.js.map +0 -1
- package/dist/repository-BAOVD3NG.js.map +0 -1
- package/dist/riverpod-XUU656PM.js.map +0 -1
- /package/dist/{chunk-3KD5CFV3.js.map → chunk-T7ZSH2YP.js.map} +0 -0
package/README.md
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
Live documentation · AI-powered assistance · Code generation · Backend integrations
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@beaulewis/saas-cli)
|
|
10
|
+
[](https://www.npmjs.com/package/@beaulewis/saas-cli)
|
|
10
11
|
[](https://github.com/Beaulewis1977/saas-cli/blob/main/LICENSE)
|
|
11
|
-
[](https://github.com/Beaulewis1977/saas-cli/actions/workflows/ci.yml)
|
|
12
13
|
[](https://nodejs.org)
|
|
14
|
+
[](https://github.com/Beaulewis1977/saas-cli/pulls)
|
|
13
15
|
|
|
14
16
|
</div>
|
|
15
17
|
|
|
@@ -18,6 +20,7 @@ Live documentation · AI-powered assistance · Code generation · Backend integr
|
|
|
18
20
|
## Table of Contents
|
|
19
21
|
|
|
20
22
|
- [Features](#features)
|
|
23
|
+
- [Requirements](#requirements)
|
|
21
24
|
- [Installation](#installation)
|
|
22
25
|
- [Quick Start](#quick-start)
|
|
23
26
|
- [Commands](#commands)
|
|
@@ -53,6 +56,39 @@ Live documentation · AI-powered assistance · Code generation · Backend integr
|
|
|
53
56
|
|
|
54
57
|
---
|
|
55
58
|
|
|
59
|
+
## Requirements
|
|
60
|
+
|
|
61
|
+
### Core Requirement
|
|
62
|
+
|
|
63
|
+
- **Node.js 20+** - [Download](https://nodejs.org/)
|
|
64
|
+
|
|
65
|
+
### External CLI Dependencies
|
|
66
|
+
|
|
67
|
+
Some commands require external CLIs to be installed. The table below shows which CLIs are needed for each command:
|
|
68
|
+
|
|
69
|
+
| Command | Required CLI | Installation |
|
|
70
|
+
|---------|--------------|--------------|
|
|
71
|
+
| `saas init flutter` | Flutter SDK | [flutter.dev/get-started/install](https://docs.flutter.dev/get-started/install) |
|
|
72
|
+
| `saas init add` | Flutter SDK | [flutter.dev/get-started/install](https://docs.flutter.dev/get-started/install) |
|
|
73
|
+
| `saas init worker` | Wrangler CLI | `npm install -g wrangler` |
|
|
74
|
+
| `saas init supabase` | Supabase CLI | `npm install -g supabase` or `brew install supabase/tap/supabase` |
|
|
75
|
+
| `saas video *` | FFmpeg | `brew install ffmpeg` (macOS) or `apt install ffmpeg` (Linux) |
|
|
76
|
+
| `saas cf *` | Wrangler CLI | `npm install -g wrangler` |
|
|
77
|
+
| `saas supabase *` | Supabase CLI | `npm install -g supabase` or `brew install supabase/tap/supabase` |
|
|
78
|
+
|
|
79
|
+
### Commands Without External Dependencies
|
|
80
|
+
|
|
81
|
+
These commands work out of the box with just Node.js:
|
|
82
|
+
|
|
83
|
+
- `saas docs` - Documentation lookup (requires `CONTEXT7_API_KEY`)
|
|
84
|
+
- `saas ask` - AI questions (requires `PERPLEXITY_API_KEY`)
|
|
85
|
+
- `saas gen` - Code generation
|
|
86
|
+
- `saas redis` - Redis management (requires `REDIS_URL`)
|
|
87
|
+
- `saas push` - Push notifications (requires OneSignal keys)
|
|
88
|
+
- `saas flags` - Feature flags (requires PostHog keys)
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
56
92
|
## Installation
|
|
57
93
|
|
|
58
94
|
```bash
|
|
@@ -273,7 +309,86 @@ saas init add riverpod,drift,freezed
|
|
|
273
309
|
|
|
274
310
|
## Environment Variables
|
|
275
311
|
|
|
276
|
-
|
|
312
|
+
The CLI reads environment variables for API keys and service credentials. You have two options:
|
|
313
|
+
|
|
314
|
+
### Option 1: Project `.env` File (Recommended)
|
|
315
|
+
|
|
316
|
+
Create a `.env` file in your project directory. This allows different API keys per project.
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
# Create .env in your project root (add to .gitignore!)
|
|
320
|
+
touch .env
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Copy this template into your `.env` file:**
|
|
324
|
+
|
|
325
|
+
```ini
|
|
326
|
+
# Documentation (Context7)
|
|
327
|
+
CONTEXT7_API_KEY=
|
|
328
|
+
|
|
329
|
+
# AI Questions (Perplexity)
|
|
330
|
+
PERPLEXITY_API_KEY=
|
|
331
|
+
|
|
332
|
+
# Supabase
|
|
333
|
+
SUPABASE_PROJECT_REF=
|
|
334
|
+
SUPABASE_ACCESS_TOKEN=
|
|
335
|
+
|
|
336
|
+
# Redis
|
|
337
|
+
REDIS_URL=
|
|
338
|
+
|
|
339
|
+
# Cloudflare Workers
|
|
340
|
+
CF_API_TOKEN=
|
|
341
|
+
|
|
342
|
+
# Push Notifications (OneSignal)
|
|
343
|
+
ONESIGNAL_APP_ID=
|
|
344
|
+
ONESIGNAL_API_KEY=
|
|
345
|
+
|
|
346
|
+
# Feature Flags (PostHog)
|
|
347
|
+
POSTHOG_API_KEY=
|
|
348
|
+
POSTHOG_PROJECT_ID=
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Add `.env` to your `.gitignore` to avoid committing secrets:**
|
|
352
|
+
|
|
353
|
+
```gitignore
|
|
354
|
+
.env
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Option 2: Shell Exports (Global)
|
|
358
|
+
|
|
359
|
+
Add these to your `~/.bashrc`, `~/.zshrc`, or shell config for system-wide access:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# Documentation (Context7)
|
|
363
|
+
export CONTEXT7_API_KEY="your-key-here"
|
|
364
|
+
|
|
365
|
+
# AI Questions (Perplexity)
|
|
366
|
+
export PERPLEXITY_API_KEY="pplx-your-key-here"
|
|
367
|
+
|
|
368
|
+
# Supabase
|
|
369
|
+
export SUPABASE_PROJECT_REF="your-project-ref"
|
|
370
|
+
export SUPABASE_ACCESS_TOKEN="your-access-token"
|
|
371
|
+
|
|
372
|
+
# Redis
|
|
373
|
+
export REDIS_URL="redis://localhost:6379"
|
|
374
|
+
|
|
375
|
+
# Cloudflare Workers
|
|
376
|
+
export CF_API_TOKEN="your-cloudflare-token"
|
|
377
|
+
|
|
378
|
+
# Push Notifications (OneSignal)
|
|
379
|
+
export ONESIGNAL_APP_ID="your-app-id"
|
|
380
|
+
export ONESIGNAL_API_KEY="your-api-key"
|
|
381
|
+
|
|
382
|
+
# Feature Flags (PostHog)
|
|
383
|
+
export POSTHOG_API_KEY="your-posthog-key"
|
|
384
|
+
export POSTHOG_PROJECT_ID="your-project-id"
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
After adding, reload your shell: `source ~/.bashrc` or `source ~/.zshrc`
|
|
388
|
+
|
|
389
|
+
> **Note:** Shell-exported environment variables take precedence over `.env` file values. If you have both, the shell export wins.
|
|
390
|
+
|
|
391
|
+
### Variable Reference
|
|
277
392
|
|
|
278
393
|
| Variable | Description | Required For |
|
|
279
394
|
|----------|-------------|--------------|
|
|
@@ -328,6 +443,10 @@ This CLI executes external tools (FFmpeg, Wrangler, Flutter, Supabase CLI) via s
|
|
|
328
443
|
|
|
329
444
|
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.
|
|
330
445
|
|
|
446
|
+
- **Bug reports:** [Open an issue](https://github.com/Beaulewis1977/saas-cli/issues/new)
|
|
447
|
+
- **Feature requests:** [Start a discussion](https://github.com/Beaulewis1977/saas-cli/discussions)
|
|
448
|
+
- **Pull requests:** Fork, create a branch, and submit a PR
|
|
449
|
+
|
|
331
450
|
```bash
|
|
332
451
|
# Clone and install
|
|
333
452
|
git clone https://github.com/Beaulewis1977/saas-cli.git
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/types/index.ts
|
|
2
|
+
var MODEL_ALIASES = {
|
|
3
|
+
sonar: "sonar",
|
|
4
|
+
pro: "sonar-pro",
|
|
5
|
+
reasoning: "sonar-reasoning-pro",
|
|
6
|
+
deep: "sonar-deep-research"
|
|
7
|
+
};
|
|
8
|
+
var LIBRARY_IDS = {
|
|
9
|
+
flutter: "/websites/flutter_cn",
|
|
10
|
+
dart: "/websites/dart_dev",
|
|
11
|
+
riverpod: "/rrousselgit/riverpod",
|
|
12
|
+
drift: "/simolus3/drift",
|
|
13
|
+
go_router: "/websites/flutter_cn",
|
|
14
|
+
gorouter: "/websites/flutter_cn",
|
|
15
|
+
supabase: "/supabase/supabase-js",
|
|
16
|
+
powersync: "/powersync-ja/powersync-js",
|
|
17
|
+
freezed: "/rrousselgit/freezed",
|
|
18
|
+
bloc: "/felangel/bloc",
|
|
19
|
+
dio: "/cfug/dio",
|
|
20
|
+
hive: "/isar/hive",
|
|
21
|
+
isar: "/isar/isar",
|
|
22
|
+
firebase: "/firebase/flutterfire"
|
|
23
|
+
};
|
|
24
|
+
var EXIT_CODES = {
|
|
25
|
+
SUCCESS: 0,
|
|
26
|
+
GENERAL_ERROR: 1,
|
|
27
|
+
USAGE_ERROR: 2,
|
|
28
|
+
CONFIG_ERROR: 3,
|
|
29
|
+
NETWORK_ERROR: 4,
|
|
30
|
+
AUTH_ERROR: 5
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
MODEL_ALIASES,
|
|
35
|
+
LIBRARY_IDS,
|
|
36
|
+
EXIT_CODES
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-FGZ7PLMQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/index.ts"],"sourcesContent":["/**\n * Global CLI configuration stored in ~/.config/saas-cli/config.yaml\n */\nexport interface GlobalConfig {\n context7?: {\n enabled?: boolean;\n apiKey?: string;\n };\n perplexity?: {\n apiKey?: string;\n defaultModel?: PerplexityModel;\n };\n supabase?: {\n projectRef?: string;\n url?: string;\n serviceKey?: string;\n };\n redis?: {\n url?: string;\n };\n cloudflare?: {\n accountId?: string;\n apiToken?: string;\n };\n onesignal?: {\n appId?: string;\n apiKey?: string;\n };\n posthog?: {\n projectId?: string;\n apiKey?: string;\n };\n defaults?: {\n outputFormat?: OutputFormat;\n cacheTtl?: number;\n };\n}\n\n/**\n * Project-level configuration stored in ./saas.yaml\n */\nexport interface ProjectConfig {\n project?: {\n name?: string;\n type?: 'flutter' | 'dart' | 'other';\n };\n flutter?: {\n path?: string;\n };\n supabase?: {\n path?: string;\n typesOutput?: string;\n };\n templates?: Record<string, { path: string }>;\n}\n\n/**\n * Output format options\n */\nexport type OutputFormat = 'pretty' | 'json' | 'minimal';\n\n/**\n * Global CLI options available on all commands\n */\nexport interface GlobalOptions {\n json?: boolean;\n verbose?: boolean;\n debug?: boolean;\n}\n\n/**\n * Perplexity AI model options\n */\nexport type PerplexityModel = 'sonar' | 'sonar-pro' | 'sonar-reasoning-pro' | 'sonar-deep-research';\n\n/**\n * Model aliases for user-friendly names\n */\nexport const MODEL_ALIASES: Record<string, PerplexityModel> = {\n sonar: 'sonar',\n pro: 'sonar-pro',\n reasoning: 'sonar-reasoning-pro',\n deep: 'sonar-deep-research',\n};\n\n/**\n * Context7 library ID mapping for common Flutter/Dart packages\n */\nexport const LIBRARY_IDS: Record<string, string> = {\n flutter: '/websites/flutter_cn',\n dart: '/websites/dart_dev',\n riverpod: '/rrousselgit/riverpod',\n drift: '/simolus3/drift',\n go_router: '/websites/flutter_cn',\n gorouter: '/websites/flutter_cn',\n supabase: '/supabase/supabase-js',\n powersync: '/powersync-ja/powersync-js',\n freezed: '/rrousselgit/freezed',\n bloc: '/felangel/bloc',\n dio: '/cfug/dio',\n hive: '/isar/hive',\n isar: '/isar/isar',\n firebase: '/firebase/flutterfire',\n};\n\n/**\n * Context7 API response types\n */\nexport interface Context7SearchResult {\n libraryId: string;\n name?: string;\n description?: string;\n}\n\nexport interface Context7DocsResult {\n content: string;\n source?: string;\n title?: string;\n}\n\n/**\n * Perplexity API response types\n */\nexport interface PerplexityResponse {\n choices: Array<{\n message: {\n content: string;\n role: string;\n };\n }>;\n citations?: string[];\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n };\n}\n\nexport interface PerplexityAskOptions {\n model?: PerplexityModel;\n maxTokens?: number;\n temperature?: number;\n searchRecencyFilter?: 'day' | 'week' | 'month' | 'year';\n searchDomainFilter?: string[];\n returnSources?: boolean;\n}\n\n/**\n * Column specification for code generation\n */\nexport interface ColumnSpec {\n name: string;\n type: string;\n isPrimaryKey?: boolean;\n isForeignKey?: boolean;\n foreignKeyTable?: string;\n foreignKeyColumn?: string;\n isNullable?: boolean;\n defaultValue?: string;\n isAutoIncrement?: boolean;\n}\n\n/**\n * RLS policy types for Supabase\n */\nexport type RLSPolicyType = 'user-owned' | 'team-owned' | 'public-read' | 'admin-only';\n\n/**\n * Command exit codes\n */\nexport const EXIT_CODES = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n CONFIG_ERROR: 3,\n NETWORK_ERROR: 4,\n AUTH_ERROR: 5,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n"],"mappings":";AA8EO,IAAM,gBAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,KAAK;AAAA,EACL,WAAW;AAAA,EACX,MAAM;AACR;AAKO,IAAM,cAAsC;AAAA,EACjD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AACZ;AAkEO,IAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AACd;","names":[]}
|
|
@@ -1,39 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// src/types/index.ts
|
|
5
|
-
var MODEL_ALIASES = {
|
|
6
|
-
sonar: "sonar",
|
|
7
|
-
pro: "sonar-pro",
|
|
8
|
-
reasoning: "sonar-reasoning-pro",
|
|
9
|
-
deep: "sonar-deep-research"
|
|
10
|
-
};
|
|
11
|
-
var LIBRARY_IDS = {
|
|
12
|
-
flutter: "/websites/flutter_cn",
|
|
13
|
-
dart: "/websites/dart_dev",
|
|
14
|
-
riverpod: "/rrousselgit/riverpod",
|
|
15
|
-
drift: "/simolus3/drift",
|
|
16
|
-
go_router: "/websites/flutter_cn",
|
|
17
|
-
gorouter: "/websites/flutter_cn",
|
|
18
|
-
supabase: "/supabase/supabase-js",
|
|
19
|
-
powersync: "/powersync-ja/powersync-js",
|
|
20
|
-
freezed: "/rrousselgit/freezed",
|
|
21
|
-
bloc: "/felangel/bloc",
|
|
22
|
-
dio: "/cfug/dio",
|
|
23
|
-
hive: "/isar/hive",
|
|
24
|
-
isar: "/isar/isar",
|
|
25
|
-
firebase: "/firebase/flutterfire"
|
|
26
|
-
};
|
|
27
|
-
var EXIT_CODES = {
|
|
28
|
-
SUCCESS: 0,
|
|
29
|
-
GENERAL_ERROR: 1,
|
|
30
|
-
USAGE_ERROR: 2,
|
|
31
|
-
CONFIG_ERROR: 3,
|
|
32
|
-
NETWORK_ERROR: 4,
|
|
33
|
-
AUTH_ERROR: 5
|
|
34
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
EXIT_CODES
|
|
3
|
+
} from "./chunk-FGZ7PLMQ.js";
|
|
35
4
|
|
|
36
5
|
// src/utils/error.ts
|
|
6
|
+
import pc from "picocolors";
|
|
37
7
|
var CLIError = class extends Error {
|
|
38
8
|
constructor(message, exitCode = EXIT_CODES.GENERAL_ERROR, hint, seeAlso) {
|
|
39
9
|
super(message);
|
|
@@ -95,14 +65,63 @@ function handleError(error) {
|
|
|
95
65
|
console.error(pc.dim(String(error)));
|
|
96
66
|
process.exit(EXIT_CODES.GENERAL_ERROR);
|
|
97
67
|
}
|
|
68
|
+
function createAPIErrorHandler(service) {
|
|
69
|
+
return (error) => {
|
|
70
|
+
if (error instanceof APIError) {
|
|
71
|
+
handleError(error);
|
|
72
|
+
}
|
|
73
|
+
if (error && typeof error === "object" && "response" in error) {
|
|
74
|
+
const response = error.response;
|
|
75
|
+
const statusCode = response?.statusCode;
|
|
76
|
+
let hint;
|
|
77
|
+
switch (statusCode) {
|
|
78
|
+
case 401:
|
|
79
|
+
hint = `Check your ${service.toUpperCase()}_API_KEY environment variable`;
|
|
80
|
+
break;
|
|
81
|
+
case 403:
|
|
82
|
+
hint = `Your API key may not have permission for this operation`;
|
|
83
|
+
break;
|
|
84
|
+
case 429:
|
|
85
|
+
hint = `Rate limited. Wait a moment and try again`;
|
|
86
|
+
break;
|
|
87
|
+
case 404:
|
|
88
|
+
hint = `Resource not found. Check if the library or endpoint exists`;
|
|
89
|
+
break;
|
|
90
|
+
case 500:
|
|
91
|
+
case 502:
|
|
92
|
+
case 503:
|
|
93
|
+
hint = `${service} service is temporarily unavailable. Try again later`;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
const apiError = new APIError(
|
|
97
|
+
`${service} API request failed (${statusCode})`,
|
|
98
|
+
service,
|
|
99
|
+
statusCode,
|
|
100
|
+
hint
|
|
101
|
+
);
|
|
102
|
+
handleError(apiError);
|
|
103
|
+
}
|
|
104
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
105
|
+
handleError(new APIError(message, service));
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function withErrorHandler(fn) {
|
|
109
|
+
return async (...args) => {
|
|
110
|
+
try {
|
|
111
|
+
return await fn(...args);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
handleError(error);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
98
117
|
|
|
99
118
|
export {
|
|
100
|
-
MODEL_ALIASES,
|
|
101
|
-
LIBRARY_IDS,
|
|
102
119
|
CLIError,
|
|
103
120
|
APIError,
|
|
104
121
|
ConfigError,
|
|
105
122
|
AuthError,
|
|
106
|
-
handleError
|
|
123
|
+
handleError,
|
|
124
|
+
createAPIErrorHandler,
|
|
125
|
+
withErrorHandler
|
|
107
126
|
};
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-JTMQREZ6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/error.ts"],"sourcesContent":["import pc from 'picocolors';\nimport { EXIT_CODES, type ExitCode } from '../types/index.js';\n\n/**\n * Custom CLI error with exit code and helpful hints\n */\nexport class CLIError extends Error {\n constructor(\n message: string,\n public exitCode: ExitCode = EXIT_CODES.GENERAL_ERROR,\n public hint?: string,\n public seeAlso?: string,\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\n/**\n * API-specific error with service context\n */\nexport class APIError extends CLIError {\n constructor(\n message: string,\n public service: string,\n public statusCode?: number,\n hint?: string,\n ) {\n super(message, EXIT_CODES.NETWORK_ERROR, hint);\n this.name = 'APIError';\n }\n}\n\n/**\n * Configuration error\n */\nexport class ConfigError extends CLIError {\n constructor(message: string, hint?: string) {\n super(message, EXIT_CODES.CONFIG_ERROR, hint);\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Authentication error\n */\nexport class AuthError extends CLIError {\n constructor(message: string, hint?: string) {\n super(message, EXIT_CODES.AUTH_ERROR, hint);\n this.name = 'AuthError';\n }\n}\n\n/**\n * Format error message for display\n */\nfunction formatError(error: CLIError): string {\n const lines: string[] = [];\n\n // Main error message\n lines.push(pc.red(`Error: ${error.message}`));\n\n // Add hint if available\n if (error.hint) {\n lines.push(pc.yellow(`Hint: ${error.hint}`));\n }\n\n // Add see also if available\n if (error.seeAlso) {\n lines.push(pc.dim(`See: ${error.seeAlso}`));\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Handle errors and exit appropriately\n */\nexport function handleError(error: unknown): never {\n // Handle CLIError instances\n if (error instanceof CLIError) {\n console.error(formatError(error));\n\n // Show stack trace in debug mode\n if (process.env.DEBUG) {\n console.error(pc.dim('\\nStack trace:'));\n console.error(pc.dim(error.stack ?? ''));\n }\n\n process.exit(error.exitCode);\n }\n\n // Handle standard errors\n if (error instanceof Error) {\n console.error(pc.red(`Error: ${error.message}`));\n\n if (process.env.DEBUG) {\n console.error(pc.dim('\\nStack trace:'));\n console.error(pc.dim(error.stack ?? ''));\n }\n\n process.exit(EXIT_CODES.GENERAL_ERROR);\n }\n\n // Handle unknown errors\n console.error(pc.red('An unexpected error occurred'));\n console.error(pc.dim(String(error)));\n process.exit(EXIT_CODES.GENERAL_ERROR);\n}\n\n/**\n * Create an API error handler for a specific service\n */\nexport function createAPIErrorHandler(service: string) {\n return (error: unknown): never => {\n if (error instanceof APIError) {\n handleError(error);\n }\n\n // Handle got/HTTP errors\n if (error && typeof error === 'object' && 'response' in error) {\n const response = (error as { response?: { statusCode?: number; body?: unknown } }).response;\n const statusCode = response?.statusCode;\n\n let hint: string | undefined;\n\n switch (statusCode) {\n case 401:\n hint = `Check your ${service.toUpperCase()}_API_KEY environment variable`;\n break;\n case 403:\n hint = `Your API key may not have permission for this operation`;\n break;\n case 429:\n hint = `Rate limited. Wait a moment and try again`;\n break;\n case 404:\n hint = `Resource not found. Check if the library or endpoint exists`;\n break;\n case 500:\n case 502:\n case 503:\n hint = `${service} service is temporarily unavailable. Try again later`;\n break;\n }\n\n const apiError = new APIError(\n `${service} API request failed (${statusCode})`,\n service,\n statusCode,\n hint,\n );\n\n handleError(apiError);\n }\n\n // Re-throw as generic API error\n const message = error instanceof Error ? error.message : String(error);\n handleError(new APIError(message, service));\n };\n}\n\n/**\n * Wrap an async function with error handling\n */\nexport function withErrorHandler<T extends (...args: unknown[]) => Promise<unknown>>(\n fn: T,\n): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> {\n return async (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => {\n try {\n return (await fn(...args)) as Awaited<ReturnType<T>>;\n } catch (error) {\n handleError(error);\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLIError
|
|
3
|
+
} from "./chunk-JTMQREZ6.js";
|
|
4
|
+
import {
|
|
5
|
+
EXIT_CODES
|
|
6
|
+
} from "./chunk-FGZ7PLMQ.js";
|
|
7
|
+
|
|
8
|
+
// src/utils/path.ts
|
|
9
|
+
import { isAbsolute, normalize, relative, resolve, sep } from "path";
|
|
10
|
+
function validateOutputPath(userPath, baseDir = process.cwd()) {
|
|
11
|
+
const normalizedBase = normalize(resolve(baseDir));
|
|
12
|
+
const normalizedPath = normalize(resolve(baseDir, userPath));
|
|
13
|
+
const relativePath = relative(normalizedBase, normalizedPath);
|
|
14
|
+
const escapesBase = relativePath === ".." || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath);
|
|
15
|
+
if (escapesBase) {
|
|
16
|
+
throw new CLIError(
|
|
17
|
+
`Output path escapes project directory: "${userPath}"`,
|
|
18
|
+
EXIT_CODES.GENERAL_ERROR,
|
|
19
|
+
'Output path must be within the current project directory. Use relative paths like "./lib/output.dart".'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return normalizedPath;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
validateOutputPath
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=chunk-N2ONDKDL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/path.ts"],"sourcesContent":["import { isAbsolute, normalize, relative, resolve, sep } from 'node:path';\nimport { EXIT_CODES } from '../types/index.js';\nimport { CLIError } from './error.js';\n\n/**\n * Validate and normalize an output file path, preventing path traversal attacks.\n * Ensures the output path is within the specified base directory (defaults to cwd).\n *\n * @param userPath - The user-provided output path\n * @param baseDir - The base directory to restrict output to (defaults to process.cwd())\n * @returns The normalized absolute path if valid\n * @throws CLIError if the path escapes the base directory\n */\nexport function validateOutputPath(userPath: string, baseDir: string = process.cwd()): string {\n // Normalize and resolve the path\n const normalizedBase = normalize(resolve(baseDir));\n const normalizedPath = normalize(resolve(baseDir, userPath));\n\n // Check if the resolved path is within the base directory\n const relativePath = relative(normalizedBase, normalizedPath);\n\n // Segment-aware check: reject '..' or '../...' but allow '..hidden' filenames\n const escapesBase =\n relativePath === '..' || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath);\n\n if (escapesBase) {\n throw new CLIError(\n `Output path escapes project directory: \"${userPath}\"`,\n EXIT_CODES.GENERAL_ERROR,\n 'Output path must be within the current project directory. Use relative paths like \"./lib/output.dart\".',\n );\n }\n\n return normalizedPath;\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,YAAY,WAAW,UAAU,SAAS,WAAW;AAavD,SAAS,mBAAmB,UAAkB,UAAkB,QAAQ,IAAI,GAAW;AAE5F,QAAM,iBAAiB,UAAU,QAAQ,OAAO,CAAC;AACjD,QAAM,iBAAiB,UAAU,QAAQ,SAAS,QAAQ,CAAC;AAG3D,QAAM,eAAe,SAAS,gBAAgB,cAAc;AAG5D,QAAM,cACJ,iBAAiB,QAAQ,aAAa,WAAW,KAAK,GAAG,EAAE,KAAK,WAAW,YAAY;AAEzF,MAAI,aAAa;AACf,UAAM,IAAI;AAAA,MACR,2CAA2C,QAAQ;AAAA,MACnD,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -2,11 +2,13 @@ import {
|
|
|
2
2
|
cacheKey,
|
|
3
3
|
cachedFetch,
|
|
4
4
|
createAuthenticatedClient
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-T7ZSH2YP.js";
|
|
6
|
+
import {
|
|
7
|
+
APIError
|
|
8
|
+
} from "./chunk-JTMQREZ6.js";
|
|
6
9
|
import {
|
|
7
|
-
APIError,
|
|
8
10
|
LIBRARY_IDS
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FGZ7PLMQ.js";
|
|
10
12
|
|
|
11
13
|
// src/services/context7.ts
|
|
12
14
|
var CONTEXT7_BASE_URL = "https://context7.com/api/v2";
|
|
@@ -107,4 +109,4 @@ function getContext7Client(apiKey) {
|
|
|
107
109
|
export {
|
|
108
110
|
getContext7Client
|
|
109
111
|
};
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-O53ZYAOB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/context7.ts"],"sourcesContent":["import type { Got } from 'got';\nimport { LIBRARY_IDS } from '../types/index.js';\nimport { cachedFetch, cacheKey } from '../utils/cache.js';\nimport { APIError } from '../utils/error.js';\nimport { createAuthenticatedClient } from './http.js';\n\nconst CONTEXT7_BASE_URL = 'https://context7.com/api/v2';\n\n/**\n * Context7 API client for documentation lookup\n */\nexport class Context7Client {\n private client: Got;\n\n constructor(apiKey: string) {\n this.client = createAuthenticatedClient(CONTEXT7_BASE_URL, apiKey);\n }\n\n /**\n * Resolve a library name to its Context7 library ID\n */\n async resolveLibrary(libraryName: string, query: string): Promise<string> {\n // Check if we have a known mapping\n const normalizedName = libraryName.toLowerCase().replace(/-/g, '_');\n if (LIBRARY_IDS[normalizedName]) {\n return LIBRARY_IDS[normalizedName] as string;\n }\n\n // Search for the library\n try {\n const response = await this.client\n .get('libs/search', {\n searchParams: {\n libraryName,\n query,\n },\n })\n .json<{ results?: Array<{ libraryId: string; name: string }> }>();\n\n if (response.results && response.results.length > 0 && response.results[0]) {\n return response.results[0].libraryId;\n }\n\n // Fallback: try to construct a likely ID\n return `/${libraryName}/${libraryName}`;\n } catch (_error) {\n // If search fails, try the fallback pattern\n return `/${libraryName}/${libraryName}`;\n }\n }\n\n /**\n * Query documentation for a specific library\n */\n async queryDocs(libraryId: string, query: string): Promise<string> {\n try {\n const response = await this.client\n .get('context', {\n searchParams: {\n libraryId,\n query,\n tokens: 8000,\n },\n })\n .text();\n\n // API returns markdown text directly\n if (!response || response.trim() === '') {\n return 'No documentation found for this query.';\n }\n\n return response;\n } catch (error) {\n if (error && typeof error === 'object' && 'response' in error) {\n const response = (error as { response?: { statusCode?: number } }).response;\n const statusCode = response?.statusCode;\n\n if (statusCode === 202) {\n throw new APIError(\n 'Library is being indexed',\n 'Context7',\n 202,\n 'The library is being indexed. Please try again in a few minutes.',\n );\n }\n\n if (statusCode === 404) {\n throw new APIError(\n 'Library not found',\n 'Context7',\n 404,\n `Could not find library: ${libraryId}. Try a different package name.`,\n );\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Search for documentation (combines resolve + query)\n */\n async search(library: string, query: string): Promise<string> {\n const key = cacheKey('context7', library, query);\n\n return cachedFetch(\n key,\n async () => {\n const libraryId = await this.resolveLibrary(library, query);\n return this.queryDocs(libraryId, query);\n },\n 3600 * 1000, // 1 hour cache\n );\n }\n}\n\n// Singleton instance cache\nlet clientInstance: Context7Client | null = null;\nlet currentApiKey: string | null = null;\n\n/**\n * Get or create a Context7 client instance\n */\nexport function getContext7Client(apiKey: string): Context7Client {\n if (!clientInstance || currentApiKey !== apiKey) {\n clientInstance = new Context7Client(apiKey);\n currentApiKey = apiKey;\n }\n return clientInstance;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/services/context7.ts"],"sourcesContent":["import type { Got } from 'got';\nimport { LIBRARY_IDS } from '../types/index.js';\nimport { cachedFetch, cacheKey } from '../utils/cache.js';\nimport { APIError } from '../utils/error.js';\nimport { createAuthenticatedClient } from './http.js';\n\nconst CONTEXT7_BASE_URL = 'https://context7.com/api/v2';\n\n/**\n * Context7 API client for documentation lookup\n */\nexport class Context7Client {\n private client: Got;\n\n constructor(apiKey: string) {\n this.client = createAuthenticatedClient(CONTEXT7_BASE_URL, apiKey);\n }\n\n /**\n * Resolve a library name to its Context7 library ID\n */\n async resolveLibrary(libraryName: string, query: string): Promise<string> {\n // Check if we have a known mapping\n const normalizedName = libraryName.toLowerCase().replace(/-/g, '_');\n if (LIBRARY_IDS[normalizedName]) {\n return LIBRARY_IDS[normalizedName] as string;\n }\n\n // Search for the library\n try {\n const response = await this.client\n .get('libs/search', {\n searchParams: {\n libraryName,\n query,\n },\n })\n .json<{ results?: Array<{ libraryId: string; name: string }> }>();\n\n if (response.results && response.results.length > 0 && response.results[0]) {\n return response.results[0].libraryId;\n }\n\n // Fallback: try to construct a likely ID\n return `/${libraryName}/${libraryName}`;\n } catch (_error) {\n // If search fails, try the fallback pattern\n return `/${libraryName}/${libraryName}`;\n }\n }\n\n /**\n * Query documentation for a specific library\n */\n async queryDocs(libraryId: string, query: string): Promise<string> {\n try {\n const response = await this.client\n .get('context', {\n searchParams: {\n libraryId,\n query,\n tokens: 8000,\n },\n })\n .text();\n\n // API returns markdown text directly\n if (!response || response.trim() === '') {\n return 'No documentation found for this query.';\n }\n\n return response;\n } catch (error) {\n if (error && typeof error === 'object' && 'response' in error) {\n const response = (error as { response?: { statusCode?: number } }).response;\n const statusCode = response?.statusCode;\n\n if (statusCode === 202) {\n throw new APIError(\n 'Library is being indexed',\n 'Context7',\n 202,\n 'The library is being indexed. Please try again in a few minutes.',\n );\n }\n\n if (statusCode === 404) {\n throw new APIError(\n 'Library not found',\n 'Context7',\n 404,\n `Could not find library: ${libraryId}. Try a different package name.`,\n );\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Search for documentation (combines resolve + query)\n */\n async search(library: string, query: string): Promise<string> {\n const key = cacheKey('context7', library, query);\n\n return cachedFetch(\n key,\n async () => {\n const libraryId = await this.resolveLibrary(library, query);\n return this.queryDocs(libraryId, query);\n },\n 3600 * 1000, // 1 hour cache\n );\n }\n}\n\n// Singleton instance cache\nlet clientInstance: Context7Client | null = null;\nlet currentApiKey: string | null = null;\n\n/**\n * Get or create a Context7 client instance\n */\nexport function getContext7Client(apiKey: string): Context7Client {\n if (!clientInstance || currentApiKey !== apiKey) {\n clientInstance = new Context7Client(apiKey);\n currentApiKey = apiKey;\n }\n return clientInstance;\n}\n"],"mappings":";;;;;;;;;;;;;AAMA,IAAM,oBAAoB;AAKnB,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,SAAS,0BAA0B,mBAAmB,MAAM;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,aAAqB,OAAgC;AAExE,UAAM,iBAAiB,YAAY,YAAY,EAAE,QAAQ,MAAM,GAAG;AAClE,QAAI,YAAY,cAAc,GAAG;AAC/B,aAAO,YAAY,cAAc;AAAA,IACnC;AAGA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OACzB,IAAI,eAAe;AAAA,QAClB,cAAc;AAAA,UACZ;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC,EACA,KAA+D;AAElE,UAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,KAAK,SAAS,QAAQ,CAAC,GAAG;AAC1E,eAAO,SAAS,QAAQ,CAAC,EAAE;AAAA,MAC7B;AAGA,aAAO,IAAI,WAAW,IAAI,WAAW;AAAA,IACvC,SAAS,QAAQ;AAEf,aAAO,IAAI,WAAW,IAAI,WAAW;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,WAAmB,OAAgC;AACjE,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OACzB,IAAI,WAAW;AAAA,QACd,cAAc;AAAA,UACZ;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF,CAAC,EACA,KAAK;AAGR,UAAI,CAAC,YAAY,SAAS,KAAK,MAAM,IAAI;AACvC,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,SAAS,OAAO,UAAU,YAAY,cAAc,OAAO;AAC7D,cAAM,WAAY,MAAiD;AACnE,cAAM,aAAa,UAAU;AAE7B,YAAI,eAAe,KAAK;AACtB,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,YAAI,eAAe,KAAK;AACtB,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,2BAA2B,SAAS;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,SAAiB,OAAgC;AAC5D,UAAM,MAAM,SAAS,YAAY,SAAS,KAAK;AAE/C,WAAO;AAAA,MACL;AAAA,MACA,YAAY;AACV,cAAM,YAAY,MAAM,KAAK,eAAe,SAAS,KAAK;AAC1D,eAAO,KAAK,UAAU,WAAW,KAAK;AAAA,MACxC;AAAA,MACA,OAAO;AAAA;AAAA,IACT;AAAA,EACF;AACF;AAGA,IAAI,iBAAwC;AAC5C,IAAI,gBAA+B;AAK5B,SAAS,kBAAkB,QAAgC;AAChE,MAAI,CAAC,kBAAkB,kBAAkB,QAAQ;AAC/C,qBAAiB,IAAI,eAAe,MAAM;AAC1C,oBAAgB;AAAA,EAClB;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConfigError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JTMQREZ6.js";
|
|
4
4
|
|
|
5
5
|
// src/utils/config.ts
|
|
6
6
|
import { existsSync } from "fs";
|
|
@@ -193,4 +193,4 @@ export {
|
|
|
193
193
|
formatTable,
|
|
194
194
|
formatBox
|
|
195
195
|
};
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
196
|
+
//# sourceMappingURL=chunk-T7ZSH2YP.js.map
|