delimit-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +157 -0
- package/bin/delimit.js +2 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +106 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +39 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/api.d.ts +3 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +64 -0
- package/dist/utils/api.js.map +1 -0
- package/dist/utils/file.d.ts +7 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +69 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +28 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/masker.d.ts +14 -0
- package/dist/utils/masker.d.ts.map +1 -0
- package/dist/utils/masker.js +89 -0
- package/dist/utils/masker.js.map +1 -0
- package/package.json +50 -0
- package/src/commands/validate.ts +150 -0
- package/src/index.ts +80 -0
- package/src/types/index.ts +41 -0
- package/src/utils/api.ts +68 -0
- package/src/utils/file.ts +71 -0
- package/src/utils/logger.ts +27 -0
- package/src/utils/masker.ts +101 -0
- package/test-sensitive.yaml +109 -0
- package/tsconfig.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# delimit-cli
|
|
2
|
+
|
|
3
|
+
Official CLI tool for [Delimit API Governance Platform](https://delimit.ai) with built-in Privacy Shield™ technology.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🛡️ **Privacy Shield™**: Automatically masks sensitive data before sending to API
|
|
8
|
+
- ✅ **OpenAPI Validation**: Validate specs against governance rules
|
|
9
|
+
- 🎨 **Beautiful Output**: Color-coded terminal output for easy reading
|
|
10
|
+
- 🚀 **Fast & Lightweight**: Built with TypeScript for performance
|
|
11
|
+
- 🔒 **Secure by Design**: Your sensitive API data never leaves your machine
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g delimit-cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or with yarn:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn global add delimit-cli
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
1. Get your API key from [RapidAPI](https://rapidapi.com/delimit/api/openapi-diff-api)
|
|
28
|
+
|
|
29
|
+
2. Set your API key as an environment variable:
|
|
30
|
+
```bash
|
|
31
|
+
export DELIMIT_API_KEY="your-api-key-here"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
3. Validate your OpenAPI specification:
|
|
35
|
+
```bash
|
|
36
|
+
delimit validate api-spec.yaml
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
### `validate`
|
|
42
|
+
|
|
43
|
+
Validate an OpenAPI specification against governance rules.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
delimit validate <filepath>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Options:**
|
|
50
|
+
- `--verbose` - Show detailed validation output
|
|
51
|
+
- `--output <format>` - Output format: `text` (default) or `json`
|
|
52
|
+
|
|
53
|
+
**Example:**
|
|
54
|
+
```bash
|
|
55
|
+
# Validate a YAML spec
|
|
56
|
+
delimit validate openapi.yaml
|
|
57
|
+
|
|
58
|
+
# Validate a JSON spec with verbose output
|
|
59
|
+
delimit validate api.json --verbose
|
|
60
|
+
|
|
61
|
+
# Get JSON output for CI/CD integration
|
|
62
|
+
delimit validate spec.yaml --output json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Coming Soon
|
|
66
|
+
|
|
67
|
+
- `diff` - Compare two API versions for breaking changes
|
|
68
|
+
- `analyze` - Analyze API changes for risks and soft breaks
|
|
69
|
+
- `recommend` - Get version recommendations based on changes
|
|
70
|
+
- `gate` - CI/CD release gate checks
|
|
71
|
+
|
|
72
|
+
## Privacy Shield™
|
|
73
|
+
|
|
74
|
+
The CLI includes built-in Privacy Shield technology that automatically removes sensitive information from your OpenAPI specifications before sending them for validation:
|
|
75
|
+
|
|
76
|
+
**What gets masked:**
|
|
77
|
+
- API descriptions and summaries
|
|
78
|
+
- Example values and responses
|
|
79
|
+
- Server URLs
|
|
80
|
+
- Contact information
|
|
81
|
+
- License and terms of service
|
|
82
|
+
|
|
83
|
+
**What stays intact:**
|
|
84
|
+
- API structure and schemas
|
|
85
|
+
- Endpoints and methods
|
|
86
|
+
- Parameters and types
|
|
87
|
+
- Required fields and validations
|
|
88
|
+
|
|
89
|
+
This ensures your proprietary business logic and sensitive documentation never leave your local environment.
|
|
90
|
+
|
|
91
|
+
## CI/CD Integration
|
|
92
|
+
|
|
93
|
+
### GitHub Actions
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
- name: Validate API Spec
|
|
97
|
+
run: |
|
|
98
|
+
npm install -g delimit-cli
|
|
99
|
+
export DELIMIT_API_KEY=${{ secrets.DELIMIT_API_KEY }}
|
|
100
|
+
delimit validate openapi.yaml
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Jenkins
|
|
104
|
+
|
|
105
|
+
```groovy
|
|
106
|
+
stage('API Validation') {
|
|
107
|
+
steps {
|
|
108
|
+
sh '''
|
|
109
|
+
npm install -g delimit-cli
|
|
110
|
+
export DELIMIT_API_KEY=${DELIMIT_API_KEY}
|
|
111
|
+
delimit validate openapi.yaml
|
|
112
|
+
'''
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### GitLab CI
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
validate-api:
|
|
121
|
+
script:
|
|
122
|
+
- npm install -g delimit-cli
|
|
123
|
+
- export DELIMIT_API_KEY=$DELIMIT_API_KEY
|
|
124
|
+
- delimit validate openapi.yaml
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Exit Codes
|
|
128
|
+
|
|
129
|
+
- `0` - Validation passed
|
|
130
|
+
- `1` - Validation failed or error occurred
|
|
131
|
+
|
|
132
|
+
## Environment Variables
|
|
133
|
+
|
|
134
|
+
- `DELIMIT_API_KEY` - Your RapidAPI key (required)
|
|
135
|
+
- `DELIMIT_API_URL` - Override API URL (optional, for testing)
|
|
136
|
+
|
|
137
|
+
## Support
|
|
138
|
+
|
|
139
|
+
- **Documentation**: https://api.delimit.ai/docs
|
|
140
|
+
- **Issues**: https://github.com/delimit-ai/delimit-cli/issues
|
|
141
|
+
- **Email**: support@delimit.ai
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT © Delimit.ai
|
|
146
|
+
|
|
147
|
+
## Contributing
|
|
148
|
+
|
|
149
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
150
|
+
|
|
151
|
+
## Security
|
|
152
|
+
|
|
153
|
+
Found a security issue? Please email security@delimit.ai directly.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
Built with ❤️ by the Delimit team
|
package/bin/delimit.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAuBA,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,GAAQ,iBA8HxE"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateCommand = validateCommand;
|
|
4
|
+
const file_1 = require("../utils/file");
|
|
5
|
+
const masker_1 = require("../utils/masker");
|
|
6
|
+
const api_1 = require("../utils/api");
|
|
7
|
+
const logger_1 = require("../utils/logger");
|
|
8
|
+
async function validateCommand(filepath, options = {}) {
|
|
9
|
+
try {
|
|
10
|
+
// Check if JSON output is requested
|
|
11
|
+
const jsonOutput = options.output === 'json';
|
|
12
|
+
if (!jsonOutput) {
|
|
13
|
+
logger_1.logger.title('🚀 Delimit API Governance Validator');
|
|
14
|
+
}
|
|
15
|
+
// Step 1: Read file
|
|
16
|
+
if (!jsonOutput) {
|
|
17
|
+
logger_1.logger.info(`Reading file: ${filepath}`);
|
|
18
|
+
const fileInfo = (0, file_1.getFileInfo)(filepath);
|
|
19
|
+
logger_1.logger.dim(` File: ${fileInfo.name} (${fileInfo.size})`);
|
|
20
|
+
}
|
|
21
|
+
const rawData = (0, file_1.readOpenApiFile)(filepath);
|
|
22
|
+
// Step 2: Apply Privacy Shield
|
|
23
|
+
if (!jsonOutput) {
|
|
24
|
+
logger_1.logger.info('Applying Privacy Shield™ - masking sensitive data...');
|
|
25
|
+
}
|
|
26
|
+
const maskedData = (0, masker_1.maskSensitiveData)(rawData);
|
|
27
|
+
// Show masking stats if verbose mode
|
|
28
|
+
if (options.verbose && !jsonOutput) {
|
|
29
|
+
const stats = (0, masker_1.getMaskingStats)(rawData, maskedData);
|
|
30
|
+
logger_1.logger.dim(` Removed ${stats.fieldsRemoved} fields (${stats.percentReduced}% size reduction)`);
|
|
31
|
+
}
|
|
32
|
+
// Step 3: Validate with API
|
|
33
|
+
if (!jsonOutput) {
|
|
34
|
+
logger_1.logger.loading('Validating with Delimit governance engine...');
|
|
35
|
+
}
|
|
36
|
+
const response = await api_1.delimitApi.post('/validate', {
|
|
37
|
+
spec: maskedData
|
|
38
|
+
});
|
|
39
|
+
const result = response.data;
|
|
40
|
+
// Step 4: Display results
|
|
41
|
+
if (jsonOutput) {
|
|
42
|
+
// Output JSON for machine parsing
|
|
43
|
+
console.log(JSON.stringify(result));
|
|
44
|
+
process.exit(result.valid ? 0 : 1);
|
|
45
|
+
}
|
|
46
|
+
// Human-readable output
|
|
47
|
+
console.log(''); // Empty line for spacing
|
|
48
|
+
if (result.valid) {
|
|
49
|
+
logger_1.logger.success('✨ Validation PASSED - Your API specification is compliant!');
|
|
50
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
51
|
+
console.log('');
|
|
52
|
+
logger_1.logger.warn(`Found ${result.warnings.length} warning(s):`);
|
|
53
|
+
result.warnings.forEach(warning => {
|
|
54
|
+
logger_1.logger.validationWarning(warning.path || 'general', warning.message);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Show summary
|
|
58
|
+
if (result.summary) {
|
|
59
|
+
console.log('');
|
|
60
|
+
logger_1.logger.info('Summary:');
|
|
61
|
+
logger_1.logger.dim(` • Errors: ${result.summary.error_count}`);
|
|
62
|
+
logger_1.logger.dim(` • Warnings: ${result.summary.warning_count}`);
|
|
63
|
+
}
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
logger_1.logger.error('❌ Validation FAILED - Your API specification has issues');
|
|
68
|
+
if (result.errors && result.errors.length > 0) {
|
|
69
|
+
console.log('');
|
|
70
|
+
logger_1.logger.error(`Found ${result.errors.length} error(s):`);
|
|
71
|
+
result.errors.forEach(error => {
|
|
72
|
+
logger_1.logger.validationError(error.path || 'general', error.message);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
76
|
+
console.log('');
|
|
77
|
+
logger_1.logger.warn(`Found ${result.warnings.length} warning(s):`);
|
|
78
|
+
result.warnings.forEach(warning => {
|
|
79
|
+
logger_1.logger.validationWarning(warning.path || 'general', warning.message);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// Show summary
|
|
83
|
+
if (result.summary) {
|
|
84
|
+
console.log('');
|
|
85
|
+
logger_1.logger.info('Summary:');
|
|
86
|
+
logger_1.logger.dim(` • Errors: ${result.summary.error_count}`);
|
|
87
|
+
logger_1.logger.dim(` • Warnings: ${result.summary.warning_count}`);
|
|
88
|
+
}
|
|
89
|
+
console.log('');
|
|
90
|
+
logger_1.logger.info('💡 Fix the errors above and run validation again.');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.log(''); // Empty line for spacing
|
|
96
|
+
logger_1.logger.error('Validation failed with error:');
|
|
97
|
+
logger_1.logger.error(error.message);
|
|
98
|
+
if (error.message.includes('DELIMIT_API_KEY')) {
|
|
99
|
+
console.log('');
|
|
100
|
+
logger_1.logger.info('📝 Get your free API key at:');
|
|
101
|
+
logger_1.logger.info(' https://rapidapi.com/delimit/api/openapi-diff-api');
|
|
102
|
+
}
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const validate_1 = require("./commands/validate");
|
|
6
|
+
const logger_1 = require("./utils/logger");
|
|
7
|
+
// Create the main program
|
|
8
|
+
const program = new commander_1.Command();
|
|
9
|
+
program
|
|
10
|
+
.name('delimit')
|
|
11
|
+
.description('CLI tool for Delimit API governance with built-in Privacy Shield™')
|
|
12
|
+
.version('1.0.0')
|
|
13
|
+
.option('-v, --verbose', 'Show detailed output')
|
|
14
|
+
.option('--api-url <url>', 'Override API URL (for testing)');
|
|
15
|
+
// Command: delimit validate <filepath>
|
|
16
|
+
program
|
|
17
|
+
.command('validate')
|
|
18
|
+
.description('Validate a local OpenAPI specification against governance rules')
|
|
19
|
+
.argument('<filepath>', 'Path to the OpenAPI specification file (JSON or YAML)')
|
|
20
|
+
.option('--verbose', 'Show detailed validation output')
|
|
21
|
+
.option('--output <format>', 'Output format: text or json', 'text')
|
|
22
|
+
.action(async (filepath, options) => {
|
|
23
|
+
// Merge global and command options
|
|
24
|
+
const globalOptions = program.opts();
|
|
25
|
+
const mergedOptions = { ...globalOptions, ...options };
|
|
26
|
+
// Set API URL if provided
|
|
27
|
+
if (mergedOptions.apiUrl) {
|
|
28
|
+
process.env.DELIMIT_API_URL = mergedOptions.apiUrl;
|
|
29
|
+
}
|
|
30
|
+
await (0, validate_1.validateCommand)(filepath, mergedOptions);
|
|
31
|
+
});
|
|
32
|
+
// Future commands placeholder
|
|
33
|
+
program
|
|
34
|
+
.command('diff')
|
|
35
|
+
.description('Compare two OpenAPI specifications (coming soon)')
|
|
36
|
+
.argument('<old>', 'Path to the old/previous OpenAPI spec')
|
|
37
|
+
.argument('<new>', 'Path to the new/current OpenAPI spec')
|
|
38
|
+
.action(() => {
|
|
39
|
+
logger_1.logger.info('The diff command is coming soon in v1.1.0!');
|
|
40
|
+
logger_1.logger.info('It will detect breaking changes between API versions.');
|
|
41
|
+
process.exit(0);
|
|
42
|
+
});
|
|
43
|
+
program
|
|
44
|
+
.command('analyze')
|
|
45
|
+
.description('Analyze API changes for risks (coming soon)')
|
|
46
|
+
.argument('<old>', 'Path to the old OpenAPI spec')
|
|
47
|
+
.argument('<new>', 'Path to the new OpenAPI spec')
|
|
48
|
+
.action(() => {
|
|
49
|
+
logger_1.logger.info('The analyze command is coming soon in v1.1.0!');
|
|
50
|
+
logger_1.logger.info('It will identify risky changes and soft breaks.');
|
|
51
|
+
process.exit(0);
|
|
52
|
+
});
|
|
53
|
+
// Handle unknown commands
|
|
54
|
+
program.on('command:*', () => {
|
|
55
|
+
logger_1.logger.error(`Invalid command: ${program.args.join(' ')}`);
|
|
56
|
+
logger_1.logger.info('Run "delimit --help" for a list of available commands.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
});
|
|
59
|
+
// Catch unhandled rejections
|
|
60
|
+
process.on('unhandledRejection', (reason) => {
|
|
61
|
+
logger_1.logger.error('Unexpected error occurred:');
|
|
62
|
+
logger_1.logger.error(reason?.message || reason);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
65
|
+
// Parse arguments
|
|
66
|
+
program.parse(process.argv);
|
|
67
|
+
// Show help if no arguments provided
|
|
68
|
+
if (!process.argv.slice(2).length) {
|
|
69
|
+
program.outputHelp();
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface OpenApiSpec {
|
|
2
|
+
openapi?: string;
|
|
3
|
+
swagger?: string;
|
|
4
|
+
info?: {
|
|
5
|
+
title?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
paths?: Record<string, any>;
|
|
11
|
+
components?: Record<string, any>;
|
|
12
|
+
servers?: Array<any>;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export interface ValidationError {
|
|
16
|
+
path?: string;
|
|
17
|
+
message: string;
|
|
18
|
+
severity?: 'error' | 'warning' | 'info';
|
|
19
|
+
code?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ValidationResult {
|
|
22
|
+
valid: boolean;
|
|
23
|
+
errors: ValidationError[];
|
|
24
|
+
warnings: ValidationError[];
|
|
25
|
+
summary: {
|
|
26
|
+
error_count: number;
|
|
27
|
+
warning_count: number;
|
|
28
|
+
};
|
|
29
|
+
metadata?: {
|
|
30
|
+
engine_version?: string;
|
|
31
|
+
validation_time?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface CliOptions {
|
|
35
|
+
verbose?: boolean;
|
|
36
|
+
output?: 'json' | 'text';
|
|
37
|
+
quiet?: boolean;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG7C,eAAO,MAAM,UAAU,EAAE,aAOvB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.delimitApi = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
// Create axios instance with default config
|
|
9
|
+
exports.delimitApi = axios_1.default.create({
|
|
10
|
+
baseURL: process.env.DELIMIT_API_URL || 'https://api.delimit.ai/v1',
|
|
11
|
+
timeout: 30000, // 30 second timeout
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
'User-Agent': 'delimit-cli/1.0.0'
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
// Request interceptor to add API key
|
|
18
|
+
exports.delimitApi.interceptors.request.use((config) => {
|
|
19
|
+
const apiKey = process.env.DELIMIT_API_KEY;
|
|
20
|
+
if (!apiKey) {
|
|
21
|
+
throw new Error('DELIMIT_API_KEY environment variable is not set.\n' +
|
|
22
|
+
'Please set it using: export DELIMIT_API_KEY="your-api-key"\n' +
|
|
23
|
+
'Get your API key at: https://rapidapi.com/delimit/api/schema-diff');
|
|
24
|
+
}
|
|
25
|
+
// Use RapidAPI header format
|
|
26
|
+
config.headers['X-RapidAPI-Key'] = apiKey;
|
|
27
|
+
config.headers['X-RapidAPI-Host'] = 'api.delimit.ai';
|
|
28
|
+
return config;
|
|
29
|
+
}, (error) => {
|
|
30
|
+
return Promise.reject(error);
|
|
31
|
+
});
|
|
32
|
+
// Response interceptor for error handling
|
|
33
|
+
exports.delimitApi.interceptors.response.use((response) => response, (error) => {
|
|
34
|
+
// Enhance error messages
|
|
35
|
+
if (error.response) {
|
|
36
|
+
// Server responded with error
|
|
37
|
+
const status = error.response.status;
|
|
38
|
+
const data = error.response.data;
|
|
39
|
+
if (status === 401) {
|
|
40
|
+
error.message = 'Invalid API key. Please check your DELIMIT_API_KEY.';
|
|
41
|
+
}
|
|
42
|
+
else if (status === 429) {
|
|
43
|
+
error.message = 'Rate limit exceeded. Please try again later.';
|
|
44
|
+
}
|
|
45
|
+
else if (status === 422) {
|
|
46
|
+
error.message = 'Invalid OpenAPI specification format.';
|
|
47
|
+
if (data?.error?.message) {
|
|
48
|
+
error.message += `\n${data.error.message}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (status >= 500) {
|
|
52
|
+
error.message = 'Delimit API server error. Please try again later.';
|
|
53
|
+
}
|
|
54
|
+
else if (data?.error?.message) {
|
|
55
|
+
error.message = data.error.message;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (error.request) {
|
|
59
|
+
// Request was made but no response
|
|
60
|
+
error.message = 'Could not connect to Delimit API. Please check your internet connection.';
|
|
61
|
+
}
|
|
62
|
+
return Promise.reject(error);
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA6C;AAE7C,4CAA4C;AAC/B,QAAA,UAAU,GAAkB,eAAK,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,2BAA2B;IACnE,OAAO,EAAE,KAAK,EAAE,oBAAoB;IACpC,OAAO,EAAE;QACP,cAAc,EAAE,kBAAkB;QAClC,YAAY,EAAE,mBAAmB;KAClC;CACF,CAAC,CAAC;AAEH,qCAAqC;AACrC,kBAAU,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CACjC,CAAC,MAAM,EAAE,EAAE;IACT,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAE3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,oDAAoD;YACpD,8DAA8D;YAC9D,mEAAmE,CACpE,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC;IAC1C,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,gBAAgB,CAAC;IAErD,OAAO,MAAM,CAAC;AAChB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CACF,CAAC;AAEF,0CAA0C;AAC1C,kBAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAClC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,CAAC,KAAK,EAAE,EAAE;IACR,yBAAyB;IACzB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,8BAA8B;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAEjC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,KAAK,CAAC,OAAO,GAAG,qDAAqD,CAAC;QACxE,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,KAAK,CAAC,OAAO,GAAG,8CAA8C,CAAC;QACjE,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,KAAK,CAAC,OAAO,GAAG,uCAAuC,CAAC;YACxD,IAAI,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBACzB,KAAK,CAAC,OAAO,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACzB,KAAK,CAAC,OAAO,GAAG,mDAAmD,CAAC;QACtE,CAAC;aAAM,IAAI,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YAChC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QACrC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACzB,mCAAmC;QACnC,KAAK,CAAC,OAAO,GAAG,0EAA0E,CAAC;IAC7F,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CA6CrD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CASA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.readOpenApiFile = readOpenApiFile;
|
|
7
|
+
exports.getFileInfo = getFileInfo;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
11
|
+
function readOpenApiFile(filepath) {
|
|
12
|
+
// Resolve to absolute path
|
|
13
|
+
const absolutePath = path_1.default.resolve(filepath);
|
|
14
|
+
if (!fs_1.default.existsSync(absolutePath)) {
|
|
15
|
+
throw new Error(`File not found: ${absolutePath}`);
|
|
16
|
+
}
|
|
17
|
+
const stats = fs_1.default.statSync(absolutePath);
|
|
18
|
+
if (!stats.isFile()) {
|
|
19
|
+
throw new Error(`Path is not a file: ${absolutePath}`);
|
|
20
|
+
}
|
|
21
|
+
// Check file size (limit to 10MB for safety)
|
|
22
|
+
const maxSize = 10 * 1024 * 1024; // 10MB
|
|
23
|
+
if (stats.size > maxSize) {
|
|
24
|
+
throw new Error(`File too large (${Math.round(stats.size / 1024 / 1024)}MB). Maximum size is 10MB.`);
|
|
25
|
+
}
|
|
26
|
+
const content = fs_1.default.readFileSync(absolutePath, 'utf8');
|
|
27
|
+
// Determine file type by extension
|
|
28
|
+
const ext = path_1.default.extname(absolutePath).toLowerCase();
|
|
29
|
+
try {
|
|
30
|
+
if (ext === '.json') {
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
else if (ext === '.yaml' || ext === '.yml') {
|
|
34
|
+
return js_yaml_1.default.load(content);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Try to parse as YAML first (it can handle JSON too)
|
|
38
|
+
try {
|
|
39
|
+
return js_yaml_1.default.load(content);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Fall back to JSON
|
|
43
|
+
return JSON.parse(content);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw new Error(`Failed to parse file as ${ext === '.json' ? 'JSON' : 'YAML'}.\n` +
|
|
49
|
+
`Please ensure the file is valid OpenAPI specification.\n` +
|
|
50
|
+
`Parser error: ${err.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function getFileInfo(filepath) {
|
|
54
|
+
const absolutePath = path_1.default.resolve(filepath);
|
|
55
|
+
const stats = fs_1.default.statSync(absolutePath);
|
|
56
|
+
return {
|
|
57
|
+
name: path_1.default.basename(absolutePath),
|
|
58
|
+
size: formatFileSize(stats.size),
|
|
59
|
+
extension: path_1.default.extname(absolutePath).toLowerCase()
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function formatFileSize(bytes) {
|
|
63
|
+
if (bytes < 1024)
|
|
64
|
+
return `${bytes} bytes`;
|
|
65
|
+
if (bytes < 1024 * 1024)
|
|
66
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
67
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const logger: {
|
|
2
|
+
info: (msg: string) => void;
|
|
3
|
+
success: (msg: string) => void;
|
|
4
|
+
error: (msg: string) => void;
|
|
5
|
+
warn: (msg: string) => void;
|
|
6
|
+
title: (msg: string) => void;
|
|
7
|
+
validationError: (path: string, message: string) => void;
|
|
8
|
+
validationWarning: (path: string, message: string) => void;
|
|
9
|
+
dim: (msg: string) => void;
|
|
10
|
+
loading: (msg: string) => void;
|
|
11
|
+
bold: (msg: string) => string;
|
|
12
|
+
underline: (msg: string) => string;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;gBACL,MAAM;mBACH,MAAM;iBACR,MAAM;gBACP,MAAM;iBACL,MAAM;4BAGK,MAAM,WAAW,MAAM;8BAIrB,MAAM,WAAW,MAAM;eAItC,MAAM;mBAGF,MAAM;gBAGT,MAAM;qBACD,MAAM;CACxB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logger = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
exports.logger = {
|
|
9
|
+
info: (msg) => console.log(chalk_1.default.blue('ℹ'), msg),
|
|
10
|
+
success: (msg) => console.log(chalk_1.default.green('✔'), chalk_1.default.green(msg)),
|
|
11
|
+
error: (msg) => console.log(chalk_1.default.red('✖'), chalk_1.default.red(msg)),
|
|
12
|
+
warn: (msg) => console.log(chalk_1.default.yellow('⚠'), chalk_1.default.yellow(msg)),
|
|
13
|
+
title: (msg) => console.log('\n' + chalk_1.default.bold.magenta(msg) + '\n'),
|
|
14
|
+
// Additional helpers for validation output
|
|
15
|
+
validationError: (path, message) => {
|
|
16
|
+
console.log(chalk_1.default.red(` ✖ ${path}: ${message}`));
|
|
17
|
+
},
|
|
18
|
+
validationWarning: (path, message) => {
|
|
19
|
+
console.log(chalk_1.default.yellow(` ⚠ ${path}: ${message}`));
|
|
20
|
+
},
|
|
21
|
+
dim: (msg) => console.log(chalk_1.default.dim(msg)),
|
|
22
|
+
// Progress indicators
|
|
23
|
+
loading: (msg) => console.log(chalk_1.default.cyan('⟳'), chalk_1.default.cyan(msg)),
|
|
24
|
+
// Formatting helpers
|
|
25
|
+
bold: (msg) => chalk_1.default.bold(msg),
|
|
26
|
+
underline: (msg) => chalk_1.default.underline(msg),
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAEb,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACxD,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,eAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzE,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnE,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,eAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACxE,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,eAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAE1E,2CAA2C;IAC3C,eAAe,EAAE,CAAC,IAAY,EAAE,OAAe,EAAE,EAAE;QACjD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,iBAAiB,EAAE,CAAC,IAAY,EAAE,OAAe,EAAE,EAAE;QACnD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEjD,sBAAsB;IACtB,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEvE,qBAAqB;IACrB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACtC,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,eAAK,CAAC,SAAS,CAAC,GAAG,CAAC;CACjD,CAAC"}
|