@veloxts/cli 0.1.0 → 0.2.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 +7 -5
- package/dist/commands/dev.js +35 -9
- package/dist/commands/dev.js.map +1 -1
- package/dist/utils/paths.d.ts +14 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +42 -0
- package/dist/utils/paths.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @veloxts/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Alpha Release** - This framework is in early development. APIs may change between versions. Not recommended for production use yet.
|
|
4
|
+
|
|
5
|
+
Command-line interface for the VeloxTS Framework.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -31,14 +33,14 @@ velox dev
|
|
|
31
33
|
|
|
32
34
|
**Options:**
|
|
33
35
|
|
|
34
|
-
- `-p, --port <port>` - Port to listen on (default:
|
|
36
|
+
- `-p, --port <port>` - Port to listen on (default: 3210)
|
|
35
37
|
- `-H, --host <host>` - Host to bind to (default: localhost)
|
|
36
38
|
- `-e, --entry <file>` - Entry point file (auto-detected if not specified)
|
|
37
39
|
|
|
38
40
|
**Examples:**
|
|
39
41
|
|
|
40
42
|
```bash
|
|
41
|
-
# Start on default port
|
|
43
|
+
# Start on default port 3210
|
|
42
44
|
velox dev
|
|
43
45
|
|
|
44
46
|
# Start on custom port
|
|
@@ -94,7 +96,7 @@ pnpm type-check
|
|
|
94
96
|
- Automatic entry point detection
|
|
95
97
|
- Graceful shutdown handling (Ctrl+C)
|
|
96
98
|
- Helpful error messages with suggestions
|
|
97
|
-
-
|
|
99
|
+
- Intuitive command design
|
|
98
100
|
- Built with Commander.js and Clack
|
|
99
101
|
|
|
100
102
|
## Architecture
|
|
@@ -124,7 +126,7 @@ Or ensure your project has one of these files:
|
|
|
124
126
|
### Port Already in Use
|
|
125
127
|
|
|
126
128
|
```
|
|
127
|
-
Error: Port
|
|
129
|
+
Error: Port 3210 is already in use
|
|
128
130
|
```
|
|
129
131
|
|
|
130
132
|
**Solution:** Use a different port:
|
package/dist/commands/dev.js
CHANGED
|
@@ -8,14 +8,14 @@ import * as p from '@clack/prompts';
|
|
|
8
8
|
import { Command } from 'commander';
|
|
9
9
|
import pc from 'picocolors';
|
|
10
10
|
import { error, formatCommand, formatPath, info, instruction, printBanner, } from '../utils/output.js';
|
|
11
|
-
import { findEntryPoint, isVeloxProject } from '../utils/paths.js';
|
|
11
|
+
import { findEntryPoint, isVeloxProject, validateEntryPath } from '../utils/paths.js';
|
|
12
12
|
/**
|
|
13
13
|
* Create the dev command
|
|
14
14
|
*/
|
|
15
15
|
export function createDevCommand(version) {
|
|
16
16
|
return new Command('dev')
|
|
17
17
|
.description('Start the development server with hot reload')
|
|
18
|
-
.option('-p, --port <port>', 'Port to listen on', '
|
|
18
|
+
.option('-p, --port <port>', 'Port to listen on', '3210')
|
|
19
19
|
.option('-H, --host <host>', 'Host to bind to', 'localhost')
|
|
20
20
|
.option('-e, --entry <file>', 'Entry point file (auto-detected if not specified)')
|
|
21
21
|
.action(async (options) => {
|
|
@@ -38,9 +38,23 @@ async function runDevServer(options, version) {
|
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
s.stop('Project validated');
|
|
41
|
-
// Find entry point
|
|
42
|
-
let entryPoint
|
|
43
|
-
if (
|
|
41
|
+
// Find and validate entry point
|
|
42
|
+
let entryPoint;
|
|
43
|
+
if (options.entry) {
|
|
44
|
+
// User specified an entry point - validate it
|
|
45
|
+
s.start('Validating entry point...');
|
|
46
|
+
try {
|
|
47
|
+
entryPoint = validateEntryPath(options.entry);
|
|
48
|
+
s.stop(`Entry point: ${formatPath(entryPoint)}`);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
s.stop('Invalid entry point');
|
|
52
|
+
error(err instanceof Error ? err.message : 'Invalid entry point');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Auto-detect entry point
|
|
44
58
|
s.start('Detecting entry point...');
|
|
45
59
|
const detected = findEntryPoint();
|
|
46
60
|
if (!detected) {
|
|
@@ -53,13 +67,25 @@ async function runDevServer(options, version) {
|
|
|
53
67
|
entryPoint = detected;
|
|
54
68
|
s.stop(`Entry point: ${formatPath(entryPoint)}`);
|
|
55
69
|
}
|
|
70
|
+
// Validate port and host
|
|
71
|
+
const port = options.port || '3210';
|
|
72
|
+
const host = options.host || 'localhost';
|
|
73
|
+
// Validate port is a valid number
|
|
74
|
+
const portNum = Number.parseInt(port, 10);
|
|
75
|
+
if (Number.isNaN(portNum) || portNum < 1 || portNum > 65535) {
|
|
76
|
+
error(`Invalid port: ${port}. Port must be a number between 1 and 65535.`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
// Validate host doesn't contain dangerous characters
|
|
80
|
+
const validHostPattern = /^[a-zA-Z0-9.-]+$/;
|
|
81
|
+
if (!validHostPattern.test(host)) {
|
|
82
|
+
error(`Invalid host: ${host}. Host should only contain alphanumeric characters, dots, and dashes.`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
56
85
|
// Print startup banner
|
|
57
86
|
printBanner(version);
|
|
58
87
|
info('Starting development server...');
|
|
59
88
|
console.log('');
|
|
60
|
-
// Start the development server with tsx watch
|
|
61
|
-
const port = options.port || '3000';
|
|
62
|
-
const host = options.host || 'localhost';
|
|
63
89
|
// Set environment variables for the app
|
|
64
90
|
const env = {
|
|
65
91
|
...process.env,
|
|
@@ -115,7 +141,7 @@ async function runDevServer(options, version) {
|
|
|
115
141
|
// Provide helpful suggestions based on error
|
|
116
142
|
if (err.message.includes('EADDRINUSE')) {
|
|
117
143
|
instruction(`Port ${options.port} is already in use. Try a different port:`);
|
|
118
|
-
console.log(` ${formatCommand(`velox dev --port ${Number(options.port ||
|
|
144
|
+
console.log(` ${formatCommand(`velox dev --port ${Number(options.port || 3210) + 1}`)}`);
|
|
119
145
|
}
|
|
120
146
|
else if (err.message.includes('EACCES')) {
|
|
121
147
|
instruction('Permission denied. Try using a port above 1024.');
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EACL,KAAK,EACL,aAAa,EACb,UAAU,EACV,IAAI,EACJ,WAAW,EACX,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -14,6 +14,20 @@ export declare function fileExists(filePath: string): boolean;
|
|
|
14
14
|
* Get the absolute path from a relative path
|
|
15
15
|
*/
|
|
16
16
|
export declare function getAbsolutePath(relativePath: string, cwd?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Validate that a path is safe for use in shell commands
|
|
19
|
+
*
|
|
20
|
+
* This prevents command injection attacks by ensuring:
|
|
21
|
+
* 1. Path is within the current working directory (no path traversal)
|
|
22
|
+
* 2. Path doesn't contain shell metacharacters
|
|
23
|
+
* 3. File exists and is a TypeScript/JavaScript file
|
|
24
|
+
*
|
|
25
|
+
* @param filePath - The path to validate
|
|
26
|
+
* @param cwd - The current working directory
|
|
27
|
+
* @returns The normalized, validated path
|
|
28
|
+
* @throws Error if the path is invalid or unsafe
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateEntryPath(filePath: string, cwd?: string): string;
|
|
17
31
|
/**
|
|
18
32
|
* Check if we're in a VeloxTS project
|
|
19
33
|
* Looks for package.json with @veloxts dependencies
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAWzE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEzF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBlF"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAWzE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAuCvF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBlF"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -29,6 +29,48 @@ export function fileExists(filePath) {
|
|
|
29
29
|
export function getAbsolutePath(relativePath, cwd = process.cwd()) {
|
|
30
30
|
return path.isAbsolute(relativePath) ? relativePath : path.join(cwd, relativePath);
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Validate that a path is safe for use in shell commands
|
|
34
|
+
*
|
|
35
|
+
* This prevents command injection attacks by ensuring:
|
|
36
|
+
* 1. Path is within the current working directory (no path traversal)
|
|
37
|
+
* 2. Path doesn't contain shell metacharacters
|
|
38
|
+
* 3. File exists and is a TypeScript/JavaScript file
|
|
39
|
+
*
|
|
40
|
+
* @param filePath - The path to validate
|
|
41
|
+
* @param cwd - The current working directory
|
|
42
|
+
* @returns The normalized, validated path
|
|
43
|
+
* @throws Error if the path is invalid or unsafe
|
|
44
|
+
*/
|
|
45
|
+
export function validateEntryPath(filePath, cwd = process.cwd()) {
|
|
46
|
+
// Normalize the path to resolve any .. or . segments
|
|
47
|
+
const absolutePath = path.isAbsolute(filePath)
|
|
48
|
+
? path.normalize(filePath)
|
|
49
|
+
: path.normalize(path.join(cwd, filePath));
|
|
50
|
+
// Ensure the path is within the current working directory
|
|
51
|
+
const normalizedCwd = path.normalize(cwd);
|
|
52
|
+
if (!absolutePath.startsWith(normalizedCwd)) {
|
|
53
|
+
throw new Error(`Entry path must be within the project directory. ` +
|
|
54
|
+
`Got: ${filePath}, which resolves to: ${absolutePath}`);
|
|
55
|
+
}
|
|
56
|
+
// Check for dangerous shell characters that could enable command injection
|
|
57
|
+
const dangerousChars = /[;&|`$(){}[\]<>!#*?\\'"\n\r\t]/;
|
|
58
|
+
if (dangerousChars.test(filePath)) {
|
|
59
|
+
throw new Error(`Entry path contains invalid characters. ` +
|
|
60
|
+
`Path should only contain alphanumeric characters, slashes, dots, and dashes.`);
|
|
61
|
+
}
|
|
62
|
+
// Verify the file exists
|
|
63
|
+
if (!existsSync(absolutePath)) {
|
|
64
|
+
throw new Error(`Entry point file not found: ${absolutePath}`);
|
|
65
|
+
}
|
|
66
|
+
// Verify it's a TypeScript or JavaScript file
|
|
67
|
+
const ext = path.extname(absolutePath).toLowerCase();
|
|
68
|
+
const validExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs', '.cts', '.cjs'];
|
|
69
|
+
if (!validExtensions.includes(ext)) {
|
|
70
|
+
throw new Error(`Entry point must be a TypeScript or JavaScript file. Got: ${ext || 'no extension'}`);
|
|
71
|
+
}
|
|
72
|
+
return absolutePath;
|
|
73
|
+
}
|
|
32
74
|
/**
|
|
33
75
|
* Check if we're in a VeloxTS project
|
|
34
76
|
* Looks for package.json with @veloxts dependencies
|
package/dist/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACxD,MAAM,UAAU,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAExF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC3C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IAC/E,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACrF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAEvD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEhC,qDAAqD;QACrD,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Developer tooling and CLI commands for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"@clack/prompts": "0.11.0",
|
|
24
24
|
"picocolors": "1.1.1",
|
|
25
25
|
"tsx": "4.21.0",
|
|
26
|
-
"@veloxts/core": "0.
|
|
27
|
-
"@veloxts/router": "0.
|
|
28
|
-
"@veloxts/validation": "0.
|
|
29
|
-
"@veloxts/orm": "0.
|
|
30
|
-
"@veloxts/auth": "0.
|
|
26
|
+
"@veloxts/core": "0.2.2",
|
|
27
|
+
"@veloxts/router": "0.2.2",
|
|
28
|
+
"@veloxts/validation": "0.2.2",
|
|
29
|
+
"@veloxts/orm": "0.2.2",
|
|
30
|
+
"@veloxts/auth": "0.2.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "24.10.1",
|