@ketrics/ketrics-cli 0.2.3 → 0.4.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.
Files changed (35) hide show
  1. package/README.md +623 -607
  2. package/dist/src/version.d.ts +1 -1
  3. package/dist/src/version.js +1 -1
  4. package/package.json +1 -1
  5. package/templates/HelloWorld/README.md +83 -106
  6. package/templates/HelloWorld/backend/package.json +1 -1
  7. package/templates/HelloWorld/backend/src/database.ts +108 -0
  8. package/templates/HelloWorld/backend/src/excel.ts +118 -0
  9. package/templates/HelloWorld/backend/src/http.ts +22 -0
  10. package/templates/HelloWorld/backend/src/index.ts +105 -29
  11. package/templates/HelloWorld/backend/src/jobs.ts +47 -0
  12. package/templates/HelloWorld/backend/src/messages.ts +59 -0
  13. package/templates/HelloWorld/backend/src/pdf.ts +212 -0
  14. package/templates/HelloWorld/backend/src/secrets.ts +21 -14
  15. package/templates/HelloWorld/backend/src/volumes.ts +107 -0
  16. package/templates/HelloWorld/frontend/package.json +1 -3
  17. package/templates/HelloWorld/frontend/src/App.css +62 -37
  18. package/templates/HelloWorld/frontend/src/App.tsx +131 -111
  19. package/templates/HelloWorld/frontend/src/mocks/handlers.ts +149 -0
  20. package/templates/HelloWorld/frontend/src/mocks/mock-client.ts +45 -0
  21. package/templates/HelloWorld/frontend/src/services/index.ts +38 -20
  22. package/templates/HelloWorld/frontend/src/vite-env.d.ts +1 -0
  23. package/templates/HelloWorld/tests/test.createInvoicePdf.json +18 -0
  24. package/templates/HelloWorld/tests/{test.getSecretWithoutGrant.json → test.createSimplePdf.json} +4 -2
  25. package/templates/HelloWorld/tests/test.createSpreadsheet.json +11 -0
  26. package/templates/HelloWorld/tests/test.echo.json +2 -2
  27. package/templates/HelloWorld/tests/test.fetchExternalApi.json +13 -0
  28. package/templates/HelloWorld/tests/test.getSecret.json +5 -1
  29. package/templates/HelloWorld/tests/test.info.json +3 -1
  30. package/templates/HelloWorld/tests/test.listFiles.json +13 -0
  31. package/templates/HelloWorld/tests/{test.echo2.json → test.queryUsers.json} +3 -3
  32. package/templates/HelloWorld/tests/{test.greet.json → test.readFile.json} +2 -2
  33. package/templates/HelloWorld/tests/{test.testWriteFileWithoutVolumeGrant.json → test.saveFile.json} +4 -2
  34. package/templates/HelloWorld/tests/test.sendNotification.json +14 -0
  35. package/templates/HelloWorld/backend/src/volume.ts +0 -55
package/README.md CHANGED
@@ -1,746 +1,762 @@
1
1
  # Ketrics CLI
2
2
 
3
- Command-line interface for scaffolding, building, and deploying applications to the Ketrics platform.
3
+ A command-line tool for creating, building, validating, and deploying applications to the Ketrics serverless platform.
4
4
 
5
- ## 1. Overview
5
+ ## Overview
6
6
 
7
- ### Purpose
8
-
9
- The Ketrics CLI (`@ketrics/ketrics-cli`) is a developer tool that streamlines the full lifecycle of Ketrics tenant applications—from project scaffolding to production deployment. It abstracts the complexity of packaging frontend and backend code into deployment bundles and handles authentication with the Ketrics Tenant API API.
10
-
11
- ### Architecture Position
12
-
13
- ```
14
- ┌──────────────────────────────────────────────────────────────────┐
15
- │ Developer Workstation │
16
- │ ┌─────────────┐ ┌────────────────┐ ┌────────────────┐ │
17
- │ │ Application │────▶│ Ketrics CLI │────▶│ Tenant API │ │
18
- │ │ Source │ │ (build & zip) │ │ API │ │
19
- │ └─────────────┘ └────────────────┘ └────────────────┘ │
20
- └──────────────────────────────────────────────────────────────────┘
21
-
22
- │ Presigned URL
23
-
24
- ┌──────────────┐
25
- │ S3 │
26
- │ (code-bundle)│
27
- └──────────────┘
28
-
29
- │ S3 Event Trigger
30
-
31
- ┌──────────────┐ ┌──────────────┐
32
- │ Deployment │────▶│ EFS │
33
- │ Lambda │ │ (extracted) │
34
- └──────────────┘ └──────────────┘
35
-
36
-
37
- ┌──────────────┐
38
- │ Data Plane │
39
- │ (runtime) │
40
- └──────────────┘
41
- ```
42
-
43
- The CLI sits at the beginning of the deployment pipeline:
44
-
45
- 1. Developers write frontend (React) and backend (TypeScript handlers) code
46
- 2. CLI builds both, packages them into a single ZIP archive
47
- 3. CLI uploads the ZIP to S3 via a presigned URL obtained from Tenant API API
48
- 4. Downstream systems (Deployment Lambda) extract the bundle to EFS for Data Plane execution
7
+ The Ketrics CLI (`@ketrics/ketrics-cli`) is a TypeScript-based command-line interface that enables developers to manage their Ketrics applications across the complete application lifecycle. It fits into the Ketrics platform ecosystem as the primary interface for local development and deployment workflows.
49
8
 
50
9
  ### Key Responsibilities
51
10
 
52
- - **Project scaffolding**: Generate new applications from bundled templates
53
- - **Configuration validation**: Validate `ketrics.config.json` and `.env` files using Zod schemas
54
- - **Build orchestration**: Execute `npm run build` for both frontend and backend
55
- - **Deployment packaging**: Create ZIP archives with frontend/backend in a flat structure
56
- - **API communication**: Authenticate with Tenant API and obtain presigned upload URLs
57
- - **S3 upload**: Push deployment bundles to the platform
58
- - **Runtime testing**: Execute API requests against deployed applications via `ketrics run`
59
-
60
- ### Boundaries
61
-
62
- The CLI does **not**:
63
-
64
- - Execute application code (that's the Data Plane's role)
65
- - Manage infrastructure (handled by Terraform)
66
- - Handle tenant/user management (Tenant API API's domain)
67
- - Extract bundles to EFS (Deployment Lambda's responsibility)
68
-
69
- ---
70
-
71
- ## 2. Business Logic
72
-
73
- ### Problem Statement
74
-
75
- Developers building Ketrics applications need a consistent, reliable way to:
76
-
77
- 1. Bootstrap new projects with correct structure and configuration
78
- 2. Build and package both frontend and backend code
79
- 3. Deploy code bundles to the platform with proper authentication
80
- 4. Test deployed functions without building custom HTTP clients
81
-
82
- ### Core Workflows
83
-
84
- #### Scaffold Workflow (`ketrics create`)
85
-
86
- ```
87
- 1. Validate app name (alphanumeric, starts with letter)
88
- 2. Check destination directory doesn't exist
89
- 3. List available templates from bundled /templates directory
90
- 4. Interactive template selection (or use --template flag)
91
- 5. Copy template files to new directory
92
- 6. Update app name in ketrics.config.json, frontend/package.json, backend/package.json
93
- ```
94
-
95
- #### Build Workflow (`ketrics build`)
96
-
97
- ```
98
- 1. Validate frontend/ directory exists with node_modules
99
- 2. Validate backend/ directory exists with node_modules
100
- 3. Run `npm run build` in frontend/ (expects dist/ output)
101
- 4. Run `npm run build` in backend/ (expects dist/ output)
102
- 5. Verify both dist/ directories were created
103
- ```
104
-
105
- #### Deploy Workflow (`ketrics deploy`)
106
-
107
- ```
108
- 1. Load .env file and validate required KETRICS_* variables
109
- 2. Validate deployment token format (must start with "ktd_")
110
- 3. Execute full build workflow (frontend + backend)
111
- 4. Create ZIP archive:
112
- - frontend/ folder containing frontend/dist/* contents
113
- - backend/ folder containing backend/dist/* contents
114
- 5. Call Tenant API API: POST /tenants/{tenantId}/applications/{appId}/deploy
115
- 6. Receive presigned S3 URL with deploymentId
116
- 7. PUT ZIP buffer to presigned URL
117
- 8. Display success with deploymentId, file count, size, duration
118
- ```
119
-
120
- #### Validate Workflow (`ketrics validate`)
121
-
122
- ```
123
- 1. Check ketrics.config.json exists and is valid JSON
124
- 2. Validate against ketricsConfigSchema (Zod)
125
- 3. Check .env file exists
126
- 4. Validate KETRICS_* variables against envConfigSchema
127
- 5. Report errors and warnings (e.g., token format, empty exclude patterns)
128
- ```
129
-
130
- #### Run Workflow (`ketrics run <json-file>`)
131
-
132
- ```
133
- 1. Load .env file (requires KETRICS_AUTH_TOKEN and KETRICS_RUNTIME_URL)
134
- 2. Parse JSON file against runFileSchema
135
- 3. Interpolate template variables: {{tenantId}}, {{applicationId}}, {{token}}
136
- 4. Construct full URL: KETRICS_RUNTIME_URL + interpolated endpoint
137
- 5. Execute HTTP request (GET/POST/PUT/DELETE/PATCH)
138
- 6. Display formatted response with status and body
139
- ```
140
-
141
- ### Business Rules
142
-
143
- | Rule | Implementation |
144
- | ------------------------------------------ | ----------------------------------------------- |
145
- | App names must be valid identifiers | Regex: `^[a-zA-Z][a-zA-Z0-9_-]*$` |
146
- | Deployment tokens must have correct prefix | Token must start with `ktd_` |
147
- | Tenant/Application IDs must be UUIDs | Zod `.uuid()` validation |
148
- | API URL must be valid HTTPS URL | Zod `.url()` validation |
149
- | Both frontend and backend must build | Both `dist/` directories must exist after build |
150
- | Templates must have ketrics.config.json | Templates without config are skipped |
151
-
152
- ### Input/Output Expectations
153
-
154
- **Deploy Input:**
155
-
156
- - `.env` file with `KETRICS_TOKEN`, `KETRICS_API_URL`, `KETRICS_TENANT_ID`, `KETRICS_APPLICATION_ID`
157
- - `frontend/` directory with `package.json` and `node_modules`
158
- - `backend/` directory with `package.json` and `node_modules`
159
-
160
- **Deploy Output:**
161
-
162
- - ZIP file uploaded to S3 with structure:
163
- ```
164
- bundle.zip
165
- ├── frontend/
166
- │ ├── index.html
167
- │ └── assets/
168
- │ ├── index-*.js
169
- │ └── index-*.css
170
- └── backend/
171
- ├── index.js
172
- └── index.d.ts
173
- ```
174
-
175
- ### Edge Cases Handled
11
+ - **Application Creation**: Bootstrap new projects from predefined templates
12
+ - **Build Orchestration**: Compile frontend and backend applications before deployment
13
+ - **Configuration Management**: Load and validate project configuration and environment variables
14
+ - **Package Bundling**: Create optimized ZIP archives with proper file structure and compression
15
+ - **Deployment Automation**: Coordinate the deploy process including API communication and S3 uploads
16
+ - **Configuration Validation**: Verify configuration files and environment setup before operations
17
+ - **Request Execution**: Execute HTTP API requests with variable interpolation and templating
176
18
 
177
- - **Destination folder exists**: `ketrics create` fails early with clear error
178
- - **node_modules missing**: Build command detects and prompts user to run `npm install`
179
- - **Empty dist directories**: Error thrown if no files found after build
180
- - **Network failures**: Axios timeout (30s API, 5min upload) with specific error messages
181
- - **Expired presigned URL**: Clear error message on 403/400 from S3
182
- - **Invalid JSON in config files**: Parse errors with file path and position
19
+ ### Architecture Boundaries
183
20
 
184
- ---
21
+ This component operates as a standalone CLI tool that:
22
+ - Does NOT handle cloud infrastructure provisioning (delegated to Ketrics backend)
23
+ - Does NOT manage authentication beyond token validation (relies on KETRICS_TOKEN format)
24
+ - Does NOT execute or monitor running applications (delegated to Ketrics platform)
25
+ - Focuses exclusively on local operations and integration with Ketrics deployment APIs
185
26
 
186
- ## 3. Technical Details
187
-
188
- ### Technology Stack
189
-
190
- | Component | Technology | Version |
191
- | --------------------- | ----------------- | -------- |
192
- | Runtime | Node.js | >=24.0.0 |
193
- | Language | TypeScript | ^5.3.3 |
194
- | CLI Framework | Commander.js | ^12.0.0 |
195
- | HTTP Client | Axios | ^1.6.0 |
196
- | Schema Validation | Zod | ^3.22.4 |
197
- | ZIP Creation | Archiver | ^6.0.1 |
198
- | File Patterns | glob | ^10.3.0 |
199
- | Interactive Prompts | @inquirer/prompts | ^7.10.1 |
200
- | Console Styling | Chalk | ^4.1.2 |
201
- | Loading Spinners | ora | ^5.4.1 |
202
- | Environment Variables | dotenv | ^16.3.1 |
203
-
204
- ### File Structure
27
+ ### Project Structure
205
28
 
206
29
  ```
207
30
  ketrics-cli/
208
31
  ├── bin/
209
- │ └── ketrics.ts # CLI entry point (shebang executable)
32
+ │ └── ketrics.ts # CLI entry point
210
33
  ├── src/
211
- │ ├── cli.ts # Commander program setup, command registration
212
- │ ├── index.ts # Programmatic exports for library usage
34
+ │ ├── cli.ts # Commander.js setup and command definitions
35
+ │ ├── index.ts # Public API exports
36
+ │ ├── version.ts # Auto-generated version
37
+ │ ├── types/
38
+ │ │ └── index.ts # Zod schemas and TypeScript interfaces
213
39
  │ ├── commands/
214
- │ │ ├── create.ts # ketrics create - project scaffolding
215
- │ │ ├── build.ts # ketrics build - compile without deploy
216
- │ │ ├── deploy.ts # ketrics deploy - build + package + upload
217
- │ │ ├── validate.ts # ketrics validate - config validation
218
- │ │ └── run.ts # ketrics run - execute API requests
40
+ │ │ ├── create.ts # Bootstrap new project from template
41
+ │ │ ├── build.ts # Build frontend/backend
42
+ │ │ ├── deploy.ts # Deploy application
43
+ │ │ ├── validate.ts # Validate configuration
44
+ │ │ └── run.ts # Execute API requests
219
45
  │ ├── services/
220
- │ │ ├── api-client.ts # HTTP client for Tenant API API
221
- │ │ ├── build-service.ts # npm build execution and validation
222
46
  │ │ ├── config-service.ts # Load/validate ketrics.config.json and .env
223
- │ │ ├── template-service.ts # Template discovery, copying, name updates
224
- │ │ ├── upload-service.ts # S3 presigned URL upload
225
- │ │ └── zip-service.ts # ZIP archive creation from dist directories
226
- │ ├── types/
227
- │ │ └── index.ts # Zod schemas and TypeScript interfaces
47
+ │ │ ├── build-service.ts # Orchestrate npm build for frontend/backend
48
+ │ │ ├── api-client.ts # HTTP communication with Ketrics API
49
+ │ │ ├── zip-service.ts # ZIP archive creation and compression
50
+ ├── upload-service.ts # S3 upload via presigned URLs
51
+ │ │ └── template-service.ts # Template discovery and copying
228
52
  │ └── utils/
229
- │ ├── logger.ts # Colored console output (chalk wrapper)
230
- │ └── spinner.ts # Loading spinner wrapper (ora)
53
+ │ ├── logger.ts # Colored console output
54
+ │ └── spinner.ts # Loading indicators
231
55
  ├── templates/
232
- │ └── ketrics-app-v1/ # Bundled project template
233
- ├── ketrics.config.json
234
- ├── frontend/ # React + Vite starter
235
- │ ├── backend/ # TypeScript handlers starter
236
- │ └── tests/ # Sample run files for ketrics run
237
- ├── package.json
238
- └── tsconfig.json
56
+ │ └── HelloWorld/ # Example template for project scaffolding
57
+ ├── package.json # NPM package configuration
58
+ ├── tsconfig.json # TypeScript configuration
59
+ └── dist/ # Compiled JavaScript (generated)
239
60
  ```
240
61
 
241
- ### Key Functions and Classes
242
-
243
- #### `src/cli.ts`
62
+ ## Business Logic
244
63
 
245
- ```typescript
246
- export function createCLI(): Command;
247
- ```
64
+ ### Problem Statement
248
65
 
249
- Creates the Commander program with all commands registered. Each command is defined with options, descriptions, and action handlers.
66
+ Developers need a consistent way to:
67
+ 1. Create new Ketrics applications with proper structure
68
+ 2. Build applications locally before deployment
69
+ 3. Package and upload applications to Ketrics infrastructure
70
+ 4. Test API integrations without manual HTTP requests
71
+ 5. Validate configuration before attempting deployments
250
72
 
251
- #### `src/services/config-service.ts`
73
+ ### Core Workflows
252
74
 
253
- ```typescript
254
- export function loadKetricsConfig(configPath?: string): KetricsConfig;
255
- ```
75
+ #### 1. Application Creation (`ketrics create`)
76
+
77
+ **Inputs**: Application name, optional template name
78
+ **Process**:
79
+ 1. Validate app name (alphanumeric, hyphens, underscores; must start with letter)
80
+ 2. Discover available templates from the `templates/` directory
81
+ 3. Prompt for template selection (interactive or via `--template` flag)
82
+ 4. Create application directory
83
+ 5. Copy template files recursively
84
+ 6. Update app name in `ketrics.config.json`, `frontend/package.json`, and `backend/package.json`
85
+
86
+ **Outputs**: New project directory with template structure
87
+ **Exit on Error**: Name validation failure, template not found, directory exists
88
+
89
+ #### 2. Build Process (`ketrics build`)
90
+
91
+ **Inputs**: Current working directory must contain `frontend/` and `backend/` subdirectories
92
+ **Process**:
93
+ 1. Validate both directories exist with `node_modules` installed
94
+ 2. Execute `npm run build` in `frontend/` directory
95
+ 3. Validate `frontend/dist/` was created
96
+ 4. Execute `npm run build` in `backend/` directory
97
+ 5. Validate `backend/dist/` was created
98
+ 6. Report dist paths to user
99
+
100
+ **Outputs**: Built artifacts in `frontend/dist/` and `backend/dist/`
101
+ **Exit on Error**: Missing directories, missing node_modules, build failure, missing dist output
102
+
103
+ #### 3. Deployment Process (`ketrics deploy`)
104
+
105
+ **Inputs**: Working directory with built `frontend/dist/` and `backend/dist/`, `.env` with credentials
106
+ **Process**:
107
+ 1. Load and validate environment configuration
108
+ 2. Validate token format (must start with `ktd_`)
109
+ 3. Build frontend and backend (calls buildAll)
110
+ 4. Collect files from both dist directories into a structured ZIP
111
+ 5. Create presigned S3 URL via Ketrics API (`POST /tenants/{id}/applications/{id}/deploy`)
112
+ 6. Upload ZIP buffer to S3 via presigned URL
113
+ 7. Return deployment ID and summary
114
+
115
+ **Outputs**: Deployment confirmation with ID, file count, and timing
116
+ **Special Mode - Dry Run** (`--dry-run`): Shows files to be deployed without uploading
117
+ **Exit on Error**: Config loading failure, token validation, build failure, API error, upload failure
118
+
119
+ #### 4. Configuration Validation (`ketrics validate`)
120
+
121
+ **Inputs**: Optional paths to `ketrics.config.json` and `.env`
122
+ **Process**:
123
+ 1. Check file existence
124
+ 2. Parse JSON and validate against schemas
125
+ 3. Check token format (warning only)
126
+ 4. Collect all errors and warnings
127
+ 5. Report validation results
128
+
129
+ **Outputs**: List of errors (blocking) and warnings (informational)
130
+ **Exit on Error**: Any validation errors present
131
+
132
+ #### 5. API Request Execution (`ketrics run`)
133
+
134
+ **Inputs**: JSON configuration file with endpoint, method, headers, body
135
+ **Process**:
136
+ 1. Load environment configuration (requires `KETRICS_AUTH_TOKEN` and `KETRICS_RUNTIME_URL`)
137
+ 2. Parse JSON run file (validates schema)
138
+ 3. Create variable map from environment (tenantId, applicationId, token)
139
+ 4. Interpolate all template variables: `{{tenantId}}`, `{{applicationId}}`, `{{token}}`
140
+ 5. Construct full URL from runtime URL + interpolated endpoint
141
+ 6. Execute HTTP request with interpolated headers/body
142
+ 7. Display request and response details
143
+
144
+ **Outputs**: HTTP response status and body
145
+ **Exit on Error**: Missing env vars, invalid JSON, connection refused, timeout
256
146
 
257
- Loads and validates `ketrics.config.json` against the Zod schema. Throws descriptive errors for missing files or validation failures.
147
+ ### Business Rules
258
148
 
259
- ```typescript
260
- export function loadEnvConfig(envPath?: string): EnvConfig;
261
- ```
149
+ - **Token Format**: Deployment tokens must start with `ktd_` (validated before API calls)
150
+ - **App Name Format**: Must start with letter, contain only alphanumeric/hyphens/underscores
151
+ - **Build Prerequisites**: Both frontend and backend must have `node_modules` before building
152
+ - **Dist Structure**: Frontend builds to `frontend/dist/`, backend builds to `backend/dist/`
153
+ - **File Patterns**: Include/exclude patterns use glob syntax for flexible file selection
154
+ - **ZIP Compression**: Level 9 compression (maximum) used for all deployments
155
+ - **Request Timeout**: API calls timeout at 30 seconds, S3 uploads at 5 minutes
156
+ - **Variable Interpolation**: All string values in run JSON are scanned for `{{varName}}` patterns
262
157
 
263
- Loads `.env` file using dotenv, extracts `KETRICS_*` variables, and validates against schema.
158
+ ### Input/Output Expectations
264
159
 
265
- ```typescript
266
- export function validateConfig(configPath?: string, envPath?: string): ValidationResult;
267
- ```
160
+ **Configuration Files**:
161
+ - `ketrics.config.json`: JSON with name, version, actions, entry, include/exclude patterns
162
+ - `.env`: Key=value format with KETRICS_* variables
163
+ - Run JSON: POST/PUT/DELETE/PATCH/GET requests with endpoint, headers, body
268
164
 
269
- Non-throwing validation that returns `{ valid: boolean, errors: string[], warnings: string[] }`.
165
+ **Exit Codes**:
166
+ - `0`: Successful execution
167
+ - `1`: Any error condition (validation failure, build failure, API error, etc.)
270
168
 
271
- #### `src/services/build-service.ts`
169
+ ## Technical Details
272
170
 
273
- ```typescript
274
- export function buildAll(projectDir: string): BuildResult;
275
- ```
171
+ ### Technology Stack
276
172
 
277
- Orchestrates building both frontend and backend. Returns paths to both `dist/` directories. Executes `npm run build` via `child_process.execSync` with `stdio: 'inherit'` to show build output.
173
+ - **Runtime**: Node.js 24.0.0+ (specified in package.json engines)
174
+ - **Language**: TypeScript 5.3.3 with strict type checking
175
+ - **CLI Framework**: Commander.js 12.0.0 (argument parsing and command structure)
176
+ - **HTTP Client**: Axios 1.6.0 (with timeout and error handling)
177
+ - **Validation**: Zod 3.22.4 (schema validation for configs and responses)
178
+ - **UI/UX**:
179
+ - Chalk 4.1.2 (colored terminal output)
180
+ - Ora 5.4.1 (loading spinners)
181
+ - @inquirer/prompts 7.10.1 (interactive prompts)
182
+ - **File Operations**: Native Node.js fs and path modules
183
+ - **Compression**: Archiver 6.0.1 (ZIP creation with streaming)
184
+ - **Pattern Matching**: Glob 10.3.0 (file selection with include/exclude)
185
+ - **Environment Loading**: dotenv 16.3.1 (.env file parsing)
186
+ - **Process Execution**: Native Node.js child_process (execSync for npm commands)
187
+
188
+ ### Dependencies Analysis
278
189
 
279
- ```typescript
280
- export function validateBuildDirectory(dir: string, name: string): BuildValidation;
190
+ ```json
191
+ {
192
+ "core-cli": ["commander@12.0.0"],
193
+ "validation": ["zod@3.22.4"],
194
+ "http": ["axios@1.6.0"],
195
+ "compression": ["archiver@6.0.1"],
196
+ "file-patterns": ["glob@10.3.0"],
197
+ "environment": ["dotenv@16.3.1"],
198
+ "ui": ["chalk@4.1.2", "ora@5.4.1", "@inquirer/prompts@7.10.1"],
199
+ "dev-dependencies": ["typescript@5.3.3", "ts-node@1.7.1", "@types/*"]
200
+ }
281
201
  ```
282
202
 
283
- Checks that a directory exists, has `node_modules`, and has `package.json`.
284
-
285
- #### `src/services/zip-service.ts`
286
-
287
- ```typescript
288
- export async function createDeploymentZipBundle(
289
- frontendDistPath: string,
290
- backendDistPath: string,
291
- ): Promise<{ buffer: Buffer; files: FileInfo[]; totalSourceSize: number; zipSize: number }>;
292
- ```
203
+ ### File Descriptions
293
204
 
294
- Creates a ZIP buffer from frontend and backend dist directories. Uses archiver with `zlib: { level: 9 }` for maximum compression. Files are organized under `frontend/` and `backend/` prefixes.
205
+ **bin/ketrics.ts**
206
+ - Entry point executable (shebang for direct CLI usage)
207
+ - Instantiates CLI via `createCLI()` and parses process.argv
208
+ - Results in `dist/bin/ketrics.js` which is referenced in package.json bin field
295
209
 
296
- #### `src/services/api-client.ts`
210
+ **src/cli.ts**
211
+ - Configures Commander.js program with CLI name, version, and help text
212
+ - Defines 5 commands: create, build, deploy, validate, run
213
+ - Maps command arguments/options to handler functions
214
+ - Exported as `createCLI()` function
297
215
 
298
- ```typescript
299
- export async function initiateDeploy(envConfig: EnvConfig): Promise<DeployResponse>;
300
- ```
216
+ **src/commands/*.ts**
217
+ - Each file exports single command handler function
218
+ - Validates inputs, orchestrates service layer calls
219
+ - Handles errors and formats output via logger
220
+ - No business logic—purely orchestration and user interaction
301
221
 
302
- Calls `POST /tenants/{tenantId}/applications/{appId}/deploy` with Bearer token authentication. Returns presigned URL, deploymentId, and S3 key. Handles 401/403/404 with user-friendly error messages.
222
+ **src/services/*.ts**
303
223
 
304
- #### `src/services/upload-service.ts`
224
+ - **config-service.ts**: Zod validation, dotenv parsing, schema enforcement. Functions: `loadEnvConfig()`, `loadKetricsConfig()`, `validateConfig()`
225
+ - **build-service.ts**: npm script execution via child_process. Functions: `buildAll()`, `runBuild()`, `validateBuildDirectory()`, `validateDistDirectory()`
226
+ - **api-client.ts**: Axios POST to `/tenants/{id}/applications/{id}/deploy`. Returns presigned URL and deployment ID. Error handling for 401/403/404 status codes.
227
+ - **zip-service.ts**: Archiver for ZIP creation, glob for file collection, streaming compression. Dual functions for config-based and directory-based bundling.
228
+ - **upload-service.ts**: Axios PUT to S3 presigned URL with binary data. 5-minute timeout for large uploads. Error handling for 400/403/413 status codes.
229
+ - **template-service.ts**: Directory traversal to discover templates, recursive copying, JSON field updates. Functions: `getAvailableTemplates()`, `copyTemplate()`, `updateAppName()`
305
230
 
306
- ```typescript
307
- export async function uploadToS3(presignedUrl: string, zipBuffer: Buffer): Promise<void>;
308
- ```
231
+ **src/types/index.ts**
232
+ - Zod schemas for runtime validation: `ketricsConfigSchema`, `envConfigSchema`, `runFileSchema`, `runEnvConfigSchema`
233
+ - TypeScript interfaces derived from schemas via `z.infer<T>`
234
+ - API response types: `DeployResponse` (presigned URL data)
235
+ - Supporting types: `FileInfo`, `ValidationResult`, `TemplateInfo`
309
236
 
310
- Uploads ZIP buffer to S3 via presigned URL using PUT with `Content-Type: application/zip`. 5-minute timeout for large uploads.
237
+ **src/utils/logger.ts**
238
+ - Singleton object with named methods: `info()`, `success()`, `warn()`, `error()`, `log()`, `newline()`, `header()`, `keyValue()`, `indent()`, `file()`, `box()`
239
+ - Uses chalk for ANSI color codes
240
+ - Replaces raw `console.log()` throughout codebase
311
241
 
312
- #### `src/services/template-service.ts`
242
+ **src/utils/spinner.ts**
243
+ - `createSpinner(text)`: Ora spinner instance
244
+ - `withSpinner<T>(text, operation, successText)`: Wraps async operation with spinner, handles errors, returns result
245
+ - Provides visual feedback for long-running operations
313
246
 
314
- ```typescript
315
- export function getAvailableTemplates(): TemplateInfo[];
316
- ```
247
+ **src/version.ts**
248
+ - Single auto-generated export: `VERSION = "0.2.3"`
249
+ - Generated by `scripts/generate-version.js` during build
250
+ - Referenced in cli.ts for `--version` flag
317
251
 
318
- Scans the `templates/` directory for subdirectories containing `ketrics.config.json`.
252
+ ### Configuration Options and Environment Variables
319
253
 
254
+ **ketrics.config.json Schema** (Zod validation):
320
255
  ```typescript
321
- export function copyTemplate(template: TemplateInfo, destDir: string): void;
256
+ {
257
+ name: string, // Project name (required, min 1 char)
258
+ version: string, // Semver format e.g. "1.0.0" (required)
259
+ description?: string, // Optional project description
260
+ runtime: "nodejs18" | "nodejs20" | "static", // Default: "nodejs18"
261
+ actions: string[], // At least 1 action name (required)
262
+ entry: string, // Entry point file (required)
263
+ include: string[], // Glob patterns to include (required, min 1)
264
+ exclude: string[] // Glob patterns to exclude (default: [])
265
+ }
322
266
  ```
323
267
 
324
- Recursively copies template files to destination directory.
325
-
326
- ```typescript
327
- export function updateAppName(projectDir: string, appName: string): void;
268
+ **Environment Variables** (loaded from .env):
328
269
  ```
329
-
330
- Updates the `name` field in `ketrics.config.json`, `frontend/package.json`, and `backend/package.json`.
331
-
332
- ### Configuration Options
333
-
334
- #### `ketrics.config.json` Schema
335
-
336
- ```typescript
337
- const ketricsConfigSchema = z.object({
338
- name: z.string().min(1),
339
- version: z.string().regex(/^\d+\.\d+\.\d+$/), // semver
340
- description: z.string().optional(),
341
- runtime: z.enum(["nodejs18", "nodejs20", "static"]).default("nodejs18"),
342
- actions: z.array(z.string()).min(1),
343
- entry: z.string().min(1),
344
- include: z.array(z.string()).min(1),
345
- exclude: z.array(z.string()).default([]),
346
- });
270
+ KETRICS_TOKEN # Deploy token starting with "ktd_" (required)
271
+ KETRICS_API_URL # Ketrics API base URL (required, must be valid URL)
272
+ KETRICS_TENANT_ID # Tenant UUID (required, UUID format)
273
+ KETRICS_APPLICATION_ID # Application UUID (required, UUID format)
274
+ KETRICS_AUTH_TOKEN # Runtime auth token (optional, required for run command)
275
+ KETRICS_RUNTIME_URL # Runtime API URL (optional, required for run command, must be URL)
347
276
  ```
348
277
 
349
- #### Environment Variables
350
-
351
- | Variable | Required | Description |
352
- | ------------------------ | --------- | ------------------------------------------------------------- |
353
- | `KETRICS_TOKEN` | Yes | Deployment token (format: `ktd_{id}_{secret}`) |
354
- | `KETRICS_API_URL` | Yes | Tenant API API URL (e.g., `https://api.ketrics.io/api/v1`) |
355
- | `KETRICS_TENANT_ID` | Yes | Tenant UUID |
356
- | `KETRICS_APPLICATION_ID` | Yes | Application UUID |
357
- | `KETRICS_AUTH_TOKEN` | For `run` | User auth token for runtime API calls |
358
- | `KETRICS_RUNTIME_URL` | For `run` | Data Plane runtime URL |
359
-
360
278
  ### External Integrations
361
279
 
362
- 1. **Tenant API API**:
363
- - Endpoint: `POST /tenants/{tenantId}/applications/{applicationId}/deploy`
364
- - Auth: Bearer token (`KETRICS_TOKEN`)
365
- - Response: Presigned S3 URL, deployment ID
366
-
367
- 2. **AWS S3**:
368
- - Upload method: HTTP PUT to presigned URL
369
- - Content-Type: `application/zip`
370
- - Max upload timeout: 5 minutes
371
-
372
- 3. **Data Plane API** (via `ketrics run`):
373
- - Endpoint: User-defined in JSON config files
374
- - Auth: Bearer token (`KETRICS_AUTH_TOKEN`)
375
-
376
- ---
377
-
378
- ## 4. Data Flow
379
-
380
- ### Create Command Flow
381
-
382
- ```
383
- User Input (app name)
384
-
385
-
386
- ┌───────────────────┐
387
- │ Validate Name │ ── Invalid ──▶ Exit with error
388
- └───────────────────┘
389
- Valid
390
-
391
- ┌───────────────────┐
392
- │ Check Dest Dir │ ── Exists ──▶ Exit with error
393
- └───────────────────┘
394
- │ OK
395
-
396
- ┌───────────────────┐
397
- List Templates │ ◀── Scan templates/ directory
398
- └───────────────────┘
399
-
400
-
401
- ┌───────────────────┐
402
- │ Select Template │ ◀── Interactive prompt or --template flag
403
- └───────────────────┘
404
-
405
-
406
- ┌───────────────────┐
407
- │ Copy Files │ ── Recursive copy to dest dir
408
- └───────────────────┘
409
-
410
-
411
- ┌───────────────────┐
412
- │ Update App Name │ ── Modify JSON files in-place
413
- └───────────────────┘
414
-
415
-
416
- Success message with next steps
417
- ```
418
-
419
- ### Deploy Command Flow
280
+ **Ketrics Tenant API**
281
+ - Endpoint: `POST /tenants/{KETRICS_TENANT_ID}/applications/{KETRICS_APPLICATION_ID}/deploy`
282
+ - Authentication: Bearer token (KETRICS_TOKEN)
283
+ - Request: Empty POST body
284
+ - Response: `{ success: boolean, data: { uploadUrl, deploymentId, s3Key, expiresAt, expiresInSeconds } }`
285
+ - Errors: 401 (bad token), 403 (no access), 404 (app not found)
286
+
287
+ **AWS S3** (via presigned URL)
288
+ - Method: PUT request to presigned URL from deploy response
289
+ - Headers: `Content-Type: application/zip`, `Content-Length: <bytes>`
290
+ - Body: Raw ZIP buffer (binary)
291
+ - Timeout: 300 seconds (5 minutes)
292
+ - Errors: 400 (expired URL), 403 (URL reused), 413 (file too large)
293
+
294
+ **Ketrics Runtime API** (for run command)
295
+ - Base URL: KETRICS_RUNTIME_URL from .env
296
+ - Endpoint: User-specified path in run JSON
297
+ - Authentication: Bearer token (KETRICS_AUTH_TOKEN in Authorization header)
298
+ - Methods: GET, POST, PUT, DELETE, PATCH
299
+ - Timeout: 30 seconds
300
+ - Response: Any JSON/text (no validation)
301
+
302
+ ## Data Flow
303
+
304
+ ### Deploy Command Data Flow
305
+
306
+ ```
307
+ User Input (--env flag, working directory)
308
+
309
+ Load .env → dotenv.parse() → Zod validation → EnvConfig object
310
+
311
+ Build frontend → execSync('npm run build') → frontend/dist/
312
+
313
+ Build backend → execSync('npm run build') → backend/dist/
314
+
315
+ Collect files fs.readdirSync() recursive FileInfo[] array
316
+
317
+ Create ZIP → Archiver stream + glob + compression → Buffer
318
+
319
+ API Call → axios.post() → Ketrics /deploy endpoint → DeployResponse
320
+
321
+ S3 Upload → axios.put() → presigned URL + ZIP buffer → AWS S3
322
+
323
+ Result → logger.box() → Deployment ID displayed to user
324
+ ```
325
+
326
+ ### Create Command Data Flow
327
+
328
+ ```
329
+ User Input (app name, optional --template)
330
+
331
+ Validate name → Regex check → boolean result
332
+
333
+ Discover templates → fs.readdirSync(templates/) → TemplateInfo[]
334
+
335
+ Prompt selection → inquirer.select() → User choice or --template flag
336
+
337
+ Copy template Recursive fs.copyFileSync() → New directory tree
338
+
339
+ Update names → JSON.parse/stringify → Update name field in 3 files
340
+
341
+ Result → logger.success() → Next steps printed to user
342
+ ```
343
+
344
+ ### Run Command Data Flow
345
+
346
+ ```
347
+ User Input (JSON file path, optional --env flag)
348
+
349
+ Load .env → dotenv.parse() → EnvConfig validation
350
+
351
+ Load JSON file → fs.readFileSync() → JSON.parse() → Zod validation → RunFileConfig
352
+
353
+ Create variables → Map EnvConfig to VariableMap { tenantId, applicationId, token }
354
+
355
+ Interpolate strings → Regex replace {{varName}} → Fully resolved endpoint/headers/body
356
+
357
+ Build full URL → KETRICS_RUNTIME_URL + endpoint → Full HTTP URL
358
+
359
+ HTTP Request → axios() → Method/headers/body from interpolated config → AxiosResponse
360
+
361
+ Display response → JSON.stringify(response.data) → Pretty-printed to console
362
+ ```
363
+
364
+ ### Configuration Validation Data Flow
365
+
366
+ ```
367
+ User Input (optional --config and --env paths)
368
+
369
+ Read ketrics.config.json → fs.readFileSync() → JSON.parse() → Zod parse
370
+
371
+ Collect errors/warnings → Zod error messages + custom checks
372
+
373
+ Read .env → dotenv.config() → Extract KETRICS_* vars → Zod parse
374
+
375
+ Token format check → Regex /^ktd_/ → Warning if doesn't match
376
+
377
+ Return ValidationResult → { valid: boolean, errors: [], warnings: [] }
378
+
379
+ Display results → logger.error() or logger.success()
380
+ ```
381
+
382
+ ## Error Handling
383
+
384
+ ### Error Scenarios and Handling
385
+
386
+ **Configuration Loading Errors**
387
+ - File not found: "Configuration file not found: {path}\nRun 'ketrics init' to create one."
388
+ - Invalid JSON: "Invalid JSON in configuration file: {path}"
389
+ - Zod validation: Field-by-field error messages with paths
390
+ - Recovery: Exit with code 1, display errors before exit
391
+
392
+ **Build Errors**
393
+ - Directory missing: "frontend/ directory not found"
394
+ - Missing node_modules: "Missing node_modules in {name}/. Run 'cd {name} && npm install' first."
395
+ - Build command failure: "{name} build failed. Check the output above for errors."
396
+ - Missing dist: "{name} build did not produce dist/ directory"
397
+ - Recovery: execSync() inherits stdio (shows npm output), thrown Error caught by command handler
398
+
399
+ **API/Network Errors**
400
+ - 401 Unauthorized: "Authentication failed: Invalid or expired deployment token.\nPlease check your KETRICS_TOKEN in the .env file."
401
+ - 403 Forbidden: "Authorization failed: Token does not have access to this application.\nPlease verify KETRICS_TENANT_ID and KETRICS_APPLICATION_ID."
402
+ - 404 Not Found: "Application not found. Please verify KETRICS_APPLICATION_ID."
403
+ - Network unreachable: "Network error: Could not connect to {url}\nPlease check your internet connection and KETRICS_API_URL."
404
+ - S3 upload 400: "Upload failed: Invalid request. The presigned URL may have expired."
405
+ - S3 upload 403: "Upload failed: Access denied. The presigned URL may have expired or been used."
406
+ - S3 upload 413: "Upload failed: File too large. Maximum upload size exceeded."
407
+ - Recovery: Error message logged, process exit(1)
408
+
409
+ **Input Validation Errors**
410
+ - Invalid app name: "App name must start with a letter and contain only letters, numbers, hyphens, and underscores"
411
+ - Missing template: "Template not found: {name}" with list of available templates
412
+ - Directory exists: "Folder '{appName}' already exists."
413
+ - Invalid run JSON: "Invalid run file format:" with detailed Zod path and message
414
+ - Recovery: Error logged, process exit(1)
420
415
 
421
- ```
422
- .env file
423
-
424
-
425
- ┌───────────────────┐
426
- │ Load & Validate │ ── Invalid ──▶ Exit with error
427
- │ Environment │
428
- └───────────────────┘
429
-
430
-
431
- ┌───────────────────┐
432
- │ Validate Token │ ── Not ktd_ ──▶ Exit with error
433
- └───────────────────┘
434
-
435
-
436
- ┌───────────────────────────────────────────┐
437
- │ Build Phase │
438
- │ ┌─────────────────┐ ┌─────────────────┐ │
439
- │ │ npm run build │ │ npm run build │ │
440
- │ │ (frontend) │ │ (backend) │ │
441
- │ └────────┬────────┘ └────────┬────────┘ │
442
- │ │ │ │
443
- │ ▼ ▼ │
444
- │ frontend/dist/ backend/dist/ │
445
- └───────────────────────────────────────────┘
446
-
447
-
448
- ┌───────────────────┐
449
- │ Create ZIP │
450
- │ - frontend/* │
451
- │ - backend/* │
452
- │ (level 9 zlib) │
453
- └───────────────────┘
454
- │ Buffer
455
-
456
- ┌───────────────────┐ ┌───────────────────┐
457
- │ Tenant API API │ ──────────────────▶│ DeployResponse │
458
- │ POST .../deploy │ │ - uploadUrl │
459
- │ Bearer ktd_... │ │ - deploymentId │
460
- └───────────────────┘ │ - s3Key │
461
- └───────────────────┘
462
- │ uploadUrl
463
-
464
- ┌───────────────────┐
465
- │ PUT to S3 │
466
- │ presigned URL │
467
- │ Content-Type: │
468
- │ application/zip │
469
- └───────────────────┘
470
-
471
-
472
- Success box with deploymentId
473
- ```
474
-
475
- ### Run Command Flow
476
-
477
- ```
478
- JSON config file (e.g., test.greet.json)
479
-
480
- │ {
481
- │ "endpoint": "/tenants/{{tenantId}}/apps/{{appId}}/functions/greet",
482
- │ "method": "POST",
483
- │ "headers": { "Authorization": "Bearer {{token}}" },
484
- │ "body": { "name": "World" }
485
- │ }
486
-
487
-
488
- ┌───────────────────┐
489
- │ Load .env │
490
- │ (KETRICS_AUTH_ │
491
- │ TOKEN required) │
492
- └───────────────────┘
493
-
494
-
495
- ┌───────────────────┐
496
- │ Parse & Validate │ ── Zod runFileSchema
497
- │ JSON File │
498
- └───────────────────┘
499
-
500
-
501
- ┌───────────────────┐
502
- │ Interpolate Vars │ ── Replace {{tenantId}}, {{applicationId}}, {{token}}
503
- └───────────────────┘
504
-
505
-
506
- ┌───────────────────┐
507
- │ Execute Request │ ── axios({ method, url, headers, data })
508
- │ KETRICS_RUNTIME_ │
509
- │ URL + endpoint │
510
- └───────────────────┘
511
-
512
-
513
- Formatted response (status + JSON body)
514
- ```
416
+ ### Retry Logic
515
417
 
516
- ---
517
-
518
- ## 5. Error Handling
519
-
520
- ### Error Scenarios
521
-
522
- | Scenario | Detection | User Message |
523
- | ---------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------- |
524
- | Missing .env file | `fs.existsSync()` check | "Environment file not found: {path}" |
525
- | Invalid JSON in config | JSON.parse throws | "Invalid JSON in configuration file: {path}" |
526
- | Zod validation failure | `safeParse().success === false` | "Invalid configuration:\n - {field}: {message}" |
527
- | Invalid token format | String prefix check | "Invalid token format. Token should start with 'ktd\_'" |
528
- | Missing node_modules | Directory check | "Missing node_modules in {dir}/. Run 'cd {dir} && npm install' first." |
529
- | Build failure | execSync throws | "{name} build failed. Check the output above for errors." |
530
- | No dist directory | Post-build directory check | "{name} build did not produce dist/ directory" |
531
- | API 401 | HTTP status check | "Authentication failed: Invalid or expired deployment token." |
532
- | API 403 | HTTP status check | "Authorization failed: Token does not have access to this application." |
533
- | API 404 | HTTP status check | "Application not found. Please verify KETRICS_APPLICATION_ID." |
534
- | Network error | axios.isAxiosError + no response | "Network error: Could not connect to {url}" |
535
- | S3 upload 403 | HTTP status check | "Upload failed: Access denied. The presigned URL may have expired or been used." |
536
- | S3 upload 413 | HTTP status check | "Upload failed: File too large. Maximum upload size exceeded." |
537
- | Upload timeout | axios timeout | "Upload failed: Network error. Please check your internet connection." |
538
- | Folder already exists | `fs.existsSync()` | "Folder '{name}' already exists." |
539
- | Invalid app name | Regex test | "App name must start with a letter and contain only letters, numbers, hyphens, and underscores" |
418
+ - **Explicit Retries**: None implemented—all operations are single-attempt
419
+ - **Presigned URL Expiration**: 15 minutes (expiresInSeconds from API response)
420
+ - **Timeout Handling**:
421
+ - API calls: 30 second timeout
422
+ - S3 uploads: 300 second timeout (5 minutes)
423
+ - User can re-run command if timeout occurs
540
424
 
541
- ### Retry Logic
425
+ ### Fallback Mechanisms
542
426
 
543
- The CLI does **not** implement automatic retry for API calls. Network failures result in immediate error and process exit. This is intentional—deployments are explicit actions where the developer should understand and resolve any connectivity issues before retrying.
427
+ - **Template Selection**: If multiple templates exist, interactive selection via inquirer; if one template exists, auto-select; if none exist, error with instructions
428
+ - **Build Validation**: Checks for node_modules and package.json before running npm build
429
+ - **Token Format**: Validates token format (`ktd_` prefix) before API call, providing early feedback
430
+ - **Variable Interpolation**: Unknown variables in run JSON remain as-is with warning logged
544
431
 
545
432
  ### Logging Approach
546
433
 
547
- All user-facing output goes through `src/utils/logger.ts`:
548
-
549
- ```typescript
550
- logger.info(message) // Blue prefix
551
- logger.success(message) // Green prefix
552
- logger.warn(message) // Yellow prefix
553
- logger.error(message) // Red prefix
554
- logger.keyValue(k, v) // Formatted key: value pairs
555
- logger.file(path, size) // Cyan file path with optional size
556
- logger.box(title, [...])// Green success box with details
557
- ```
434
+ **Logger Levels** (not severity-based, visual categorization):
435
+ - `info()`: Blue "ℹ" icon + message (informational)
436
+ - `success()`: Green "✔" icon + message (operation succeeded)
437
+ - `warn()`: Yellow "⚠" icon + message (non-blocking issues)
438
+ - `error()`: Red "✖" icon + message (operation failed)
439
+ - `log()`: Plain text (neutral output)
440
+ - `header()`: Bold text with newlines (section markers)
441
+ - `keyValue()`: Gray key + value (structured data)
442
+ - `box()`: Green checkmark box (success summary)
558
443
 
559
- Long-running operations use spinners (`src/utils/spinner.ts`):
444
+ **Log Points**:
445
+ 1. Command start: `logger.header()` with command name
446
+ 2. Major operation start: `withSpinner()` text
447
+ 3. Operation completion: `spinner.succeed()` text
448
+ 4. Data summaries: `logger.keyValue()` for important values
449
+ 5. Errors: `logger.error()` before exit or throw
450
+ 6. Success: `logger.box()` or `logger.success()` at end
560
451
 
561
- ```typescript
562
- await withSpinner(
563
- "Loading environment configuration", // Shown during operation
564
- async () => loadEnvConfig(options.env),
565
- "Loaded environment configuration", // Shown on success
566
- );
452
+ **Example Deploy Logging**:
453
+ ```
454
+ Ketrics CLI v1.0.0 [header]
455
+ Loading environment... [spinner start]
456
+ Loaded environment [spinner succeed]
457
+ Building frontend... [info]
458
+ Building backend... [info]
459
+ ✔ Build completed [success]
460
+ Frontend dist: ... [keyValue]
567
461
  ```
568
462
 
569
- Build output is passed through to the terminal via `stdio: 'inherit'` in `execSync`, so developers see native npm/Vite/TypeScript output.
570
-
571
- ---
572
-
573
- ## 6. Usage
463
+ ## Usage
574
464
 
575
- ### Installation
465
+ ### Installation and Setup
576
466
 
577
467
  ```bash
578
- # Global installation
468
+ # Install globally
579
469
  npm install -g @ketrics/ketrics-cli
580
470
 
581
- # Or run directly with npx
582
- npx @ketrics/ketrics-cli deploy
471
+ # Or use as dev dependency
472
+ npm install --save-dev @ketrics/ketrics-cli
583
473
 
584
- # Development installation (from source)
585
- cd ketrics-cli
586
- npm install
587
- npm run build
588
- npm link
474
+ # Verify installation
475
+ ketrics --version
589
476
  ```
590
477
 
591
- ### Commands
478
+ ### Running Commands
592
479
 
593
- #### Create New Application
480
+ #### Create a New Application
594
481
 
595
482
  ```bash
596
483
  # Interactive template selection
597
484
  ketrics create my-app
598
485
 
599
- # Use specific template
600
- ketrics create my-app --template ketrics-app-v1
486
+ # Specify template directly
487
+ ketrics create my-app --template HelloWorld
601
488
  ```
602
489
 
603
- #### Build Without Deploying
490
+ **Output**:
491
+ - New directory `my-app/` with template structure
492
+ - Console instructions for next steps
493
+ - Pre-configured `ketrics.config.json` and package.json files
494
+
495
+ **Prerequisites**: None (discovers templates from bundled templates/)
496
+
497
+ #### Build Application
604
498
 
605
499
  ```bash
500
+ cd my-app
606
501
  ketrics build
607
502
  ```
608
503
 
609
- #### Deploy to Platform
504
+ **Output**:
505
+ - Compiled `frontend/dist/` directory
506
+ - Compiled `backend/dist/` directory
507
+ - Console summary with paths
508
+
509
+ **Prerequisites**:
510
+ - Current directory contains `frontend/` and `backend/` subdirectories
511
+ - Both directories have `node_modules/` installed
512
+ - Both directories have `package.json` with `build` script
513
+
514
+ #### Deploy Application
610
515
 
611
516
  ```bash
612
517
  # Standard deployment
613
518
  ketrics deploy
614
519
 
615
- # Use specific .env file
616
- ketrics deploy --env /path/to/.env
520
+ # Custom .env path
521
+ ketrics deploy --env ./config/.env.production
617
522
 
618
- # Preview what would be deployed (no upload)
523
+ # Dry run (see what would deploy without uploading)
619
524
  ketrics deploy --dry-run
620
525
  ```
621
526
 
527
+ **Output**:
528
+ - Deployment ID
529
+ - File count and total size
530
+ - Processing confirmation
531
+
532
+ **Prerequisites**:
533
+ - `.env` file with KETRICS_TOKEN, KETRICS_API_URL, KETRICS_TENANT_ID, KETRICS_APPLICATION_ID
534
+ - Built `frontend/dist/` and `backend/dist/` directories
535
+ - Valid deployment token (starts with `ktd_`)
536
+
622
537
  #### Validate Configuration
623
538
 
624
539
  ```bash
625
- # Validate default files
540
+ # Validate with defaults
626
541
  ketrics validate
627
542
 
628
- # Validate specific files
629
- ketrics validate --config ./custom.config.json --env ./custom.env
543
+ # Custom paths
544
+ ketrics validate --config ./config/ketrics.config.json --env ./.env.staging
630
545
  ```
631
546
 
632
- #### Execute API Request
633
-
634
- ```bash
635
- # Run test request from JSON file
636
- ketrics run tests/test.greet.json
637
-
638
- # With custom .env and verbose output
639
- ketrics run tests/test.echo.json --env .env.local --verbose
640
- ```
547
+ **Output**:
548
+ - List of errors (if any)
549
+ - List of warnings (if any)
550
+ - Success/failure status
641
551
 
642
- ### Example Run File
552
+ **Prerequisites**: None (creates validation report even if files don't exist)
643
553
 
644
- `tests/test.greet.json`:
554
+ #### Execute API Requests
645
555
 
646
- ```json
556
+ ```bash
557
+ # Create request file: request.json
647
558
  {
648
- "endpoint": "/tenants/{{tenantId}}/applications/{{applicationId}}/functions/greet",
649
- "method": "POST",
559
+ "endpoint": "/users/{{tenantId}}/profile",
560
+ "method": "GET",
650
561
  "headers": {
651
- "Authorization": "Bearer {{token}}",
652
- "Content-Type": "application/json"
653
- },
654
- "body": {
655
- "name": "World"
562
+ "Authorization": "Bearer {{token}}"
656
563
  }
657
564
  }
565
+
566
+ # Execute request
567
+ ketrics run request.json
568
+
569
+ # Verbose output
570
+ ketrics run request.json --verbose
571
+
572
+ # Custom .env
573
+ ketrics run request.json --env ./.env.dev
658
574
  ```
659
575
 
660
- ### Development Commands
576
+ **Output**:
577
+ - Formatted HTTP request (method, URL, headers, body)
578
+ - Formatted HTTP response (status, body)
579
+ - Duration in seconds
580
+
581
+ **Prerequisites**:
582
+ - `.env` file with KETRICS_AUTH_TOKEN and KETRICS_RUNTIME_URL
583
+ - Valid JSON request file
661
584
 
585
+ ### Example Invocations
586
+
587
+ **Full Deployment Workflow**:
662
588
  ```bash
663
- # Build TypeScript to dist/
664
- npm run build
589
+ # Create new project
590
+ ketrics create my-todo-app --template HelloWorld
665
591
 
666
- # Run CLI in development mode (ts-node)
667
- npm run dev -- create my-app
668
- npm run dev -- deploy --dry-run
592
+ # Navigate to project
593
+ cd my-todo-app
669
594
 
670
- # Clean build artifacts
671
- npm run clean
672
- ```
595
+ # Install dependencies
596
+ cd frontend && npm install
597
+ cd ../backend && npm install
598
+ cd ..
673
599
 
674
- ### Testing Approach
600
+ # Copy .env from template
601
+ cp .env.example .env
602
+ # Edit .env with your credentials
675
603
 
676
- The CLI does not include automated tests in the current implementation. Testing is performed manually:
604
+ # Validate configuration
605
+ ketrics validate
677
606
 
678
- 1. **Unit testing config validation**: Create various `.env` and `ketrics.config.json` files with valid/invalid data, run `ketrics validate`
679
- 2. **Integration testing deployment**:
680
- - `ketrics create test-app`
681
- - `cd test-app/frontend && npm install && cd ../backend && npm install`
682
- - Configure `.env` with real credentials
683
- - `ketrics deploy --dry-run` to verify packaging
684
- - `ketrics deploy` to test full flow
685
- 3. **Runtime testing**: Use `ketrics run tests/test.*.json` against deployed application
607
+ # Build application
608
+ ketrics build
686
609
 
687
- ### Example Session
610
+ # Deploy to Ketrics
611
+ ketrics deploy
612
+ ```
688
613
 
614
+ **Testing API Endpoints**:
689
615
  ```bash
690
- # Create a new application
691
- $ ketrics create hello-world
616
+ # Create .env with runtime credentials
617
+ cat > .env.test << EOF
618
+ KETRICS_TENANT_ID=12345678-1234-1234-1234-123456789012
619
+ KETRICS_APPLICATION_ID=87654321-4321-4321-4321-210987654321
620
+ KETRICS_AUTH_TOKEN=your_runtime_token_here
621
+ KETRICS_RUNTIME_URL=https://api.runtime.ketrics.io
622
+ EOF
623
+
624
+ # Create request file
625
+ cat > api-test.json << EOF
626
+ {
627
+ "endpoint": "/health",
628
+ "method": "GET",
629
+ "headers": {
630
+ "Authorization": "Bearer {{token}}"
631
+ }
632
+ }
633
+ EOF
692
634
 
693
- Creating 'hello-world' with template: ketrics-app-v1
635
+ # Execute
636
+ ketrics run api-test.json --env .env.test
637
+ ```
694
638
 
695
- Files to create:
696
- hello-world/ketrics.config.json
697
- hello-world/frontend/package.json
698
- hello-world/backend/package.json
699
- ...
639
+ ### Testing Approach
700
640
 
701
- Created 'hello-world' successfully!
641
+ **Unit Testing** (not included in code):
642
+ - Would test individual service functions: `loadEnvConfig()`, `buildAll()`, `collectFiles()`, etc.
643
+ - Mock file system, axios, child_process
644
+ - Verify schema validation with valid/invalid inputs
645
+ - Test error handling paths
646
+
647
+ **Integration Testing** (not included in code):
648
+ - Test complete command workflows
649
+ - Use temporary directories and files
650
+ - Mock Ketrics API responses
651
+ - Verify file structure creation and modification
652
+
653
+ **Manual Testing** (recommended):
654
+ 1. Create test project with `ketrics create test-app`
655
+ 2. Modify `.env` with test credentials
656
+ 3. Run `ketrics validate` to verify setup
657
+ 4. Run `ketrics build` to verify npm scripts exist
658
+ 5. Run `ketrics deploy --dry-run` to verify packaging
659
+ 6. Run `ketrics run` with test request to verify runtime access
660
+ 7. Full `ketrics deploy` to staging environment
661
+
662
+ **Testing Checklist**:
663
+ - Create command with interactive and flag-based template selection
664
+ - Build command with missing node_modules, missing dist directories
665
+ - Deploy command with invalid token format, network errors, S3 failures
666
+ - Validate command with missing files, invalid JSON, schema violations
667
+ - Run command with missing variables, malformed JSON, API errors
668
+ - Edge cases: empty directories, very large files, special characters in names
669
+
670
+ ## Advanced Topics
671
+
672
+ ### Custom Configuration Patterns
673
+
674
+ The `include`/`exclude` patterns in `ketrics.config.json` use glob syntax:
702
675
 
703
- Next steps:
704
- 1. cd hello-world
705
- 2. cd frontend && npm install
706
- 3. cd ../backend && npm install
707
- 4. Copy .env.example to .env and add your credentials
708
- 5. Run 'ketrics deploy' to deploy your application
676
+ ```json
677
+ {
678
+ "include": [
679
+ "frontend/dist/**/*",
680
+ "backend/dist/**/*"
681
+ ],
682
+ "exclude": [
683
+ "**/*.map",
684
+ "**/node_modules/**",
685
+ "**/.git/**"
686
+ ]
687
+ }
688
+ ```
709
689
 
710
- # Install dependencies
711
- $ cd hello-world
712
- $ cd frontend && npm install && cd ../backend && npm install
690
+ ### Programmatic Usage
713
691
 
714
- # Configure credentials
715
- $ cp .env.example .env
716
- $ vim .env # Add your KETRICS_TOKEN, etc.
692
+ The CLI exports services for use in other Node.js applications:
717
693
 
718
- # Deploy
719
- $ ketrics deploy
694
+ ```typescript
695
+ import {
696
+ loadEnvConfig,
697
+ buildAll,
698
+ createDeploymentZipBundle,
699
+ uploadToS3,
700
+ initiateDeploy
701
+ } from '@ketrics/ketrics-cli';
702
+
703
+ // Load config
704
+ const config = loadEnvConfig('/path/to/.env');
705
+
706
+ // Build application
707
+ const buildResult = buildAll(process.cwd());
708
+
709
+ // Create ZIP
710
+ const zip = await createDeploymentZipBundle(
711
+ buildResult.frontendDistPath,
712
+ buildResult.backendDistPath
713
+ );
720
714
 
721
- Ketrics CLI v1.0.0
715
+ // Upload
716
+ await uploadToS3(presignedUrl, zip.buffer);
717
+ ```
718
+
719
+ ### Environment-Specific Deployments
722
720
 
723
- Loaded environment configuration
724
- ✔ Validated deployment token
721
+ Use different `.env` files for different environments:
725
722
 
726
- Building frontend and backend...
723
+ ```bash
724
+ # Staging
725
+ ketrics deploy --env .env.staging
726
+
727
+ # Production
728
+ ketrics deploy --env .env.production
729
+ ```
727
730
 
728
- > hello-world@1.0.0 build
729
- > vite build
730
- ...
731
+ ### Debugging
731
732
 
732
- Frontend and backend built successfully
733
- ✔ Created deployment ZIP archive
734
- ✔ ZIP archive: 45.2 KB from 6 files
735
- ✔ Initiated deployment
736
- ✔ Uploaded to S3
733
+ Enable verbose output where available:
737
734
 
738
- ✅ Deployment successful!
735
+ ```bash
736
+ # Run command with verbose flag
737
+ ketrics run request.json --verbose
739
738
 
740
- Deployment ID: 550e8400-e29b-41d4-a716-446655440002
741
- Files: 6
742
- Size: 45.2 KB
743
- Duration: 4.1s
739
+ # Build process inherits stdio (shows npm output)
740
+ ketrics build # Shows all npm build output
744
741
 
745
- Your deployment is being processed by Ketrics.
742
+ # API client logs URL before request
743
+ # (Search for "console.log" in api-client.ts for debug points)
746
744
  ```
745
+
746
+ ## Version Information
747
+
748
+ - **CLI Version**: 0.2.3 (auto-generated in `src/version.ts`)
749
+ - **Node.js Requirement**: 24.0.0 or later
750
+ - **TypeScript**: 5.3.3
751
+ - **Last Updated**: 2024-2025
752
+
753
+ ## Contributing
754
+
755
+ When modifying the CLI:
756
+ 1. Follow TypeScript strict mode (tsconfig.json)
757
+ 2. Export types and services from `src/index.ts`
758
+ 3. Add Zod schemas for new configuration options
759
+ 4. Use logger utility instead of console.log
760
+ 5. Wrap async operations with withSpinner for UX
761
+ 6. Run `npm run build` before testing (generates version.ts)
762
+ 7. Test all command paths, especially error scenarios