nest-scramble 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 +304 -0
- package/dist/NestScrambleModule.d.ts +16 -0
- package/dist/NestScrambleModule.d.ts.map +1 -0
- package/dist/NestScrambleModule.js +73 -0
- package/dist/NestScrambleModule.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +77 -0
- package/dist/cli.js.map +1 -0
- package/dist/controllers/DemoController.d.ts +53 -0
- package/dist/controllers/DemoController.d.ts.map +1 -0
- package/dist/controllers/DemoController.js +91 -0
- package/dist/controllers/DemoController.js.map +1 -0
- package/dist/controllers/DocsController.d.ts +7 -0
- package/dist/controllers/DocsController.d.ts.map +1 -0
- package/dist/controllers/DocsController.js +69 -0
- package/dist/controllers/DocsController.js.map +1 -0
- package/dist/generators/PostmanCollectionGenerator.d.ts +61 -0
- package/dist/generators/PostmanCollectionGenerator.d.ts.map +1 -0
- package/dist/generators/PostmanCollectionGenerator.js +97 -0
- package/dist/generators/PostmanCollectionGenerator.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/MockMiddleware.d.ts +15 -0
- package/dist/middleware/MockMiddleware.d.ts.map +1 -0
- package/dist/middleware/MockMiddleware.js +94 -0
- package/dist/middleware/MockMiddleware.js.map +1 -0
- package/dist/scanner/ScannerService.d.ts +34 -0
- package/dist/scanner/ScannerService.d.ts.map +1 -0
- package/dist/scanner/ScannerService.js +114 -0
- package/dist/scanner/ScannerService.js.map +1 -0
- package/dist/utils/DtoAnalyzer.d.ts +25 -0
- package/dist/utils/DtoAnalyzer.d.ts.map +1 -0
- package/dist/utils/DtoAnalyzer.js +93 -0
- package/dist/utils/DtoAnalyzer.js.map +1 -0
- package/dist/utils/MockGenerator.d.ts +18 -0
- package/dist/utils/MockGenerator.d.ts.map +1 -0
- package/dist/utils/MockGenerator.js +135 -0
- package/dist/utils/MockGenerator.js.map +1 -0
- package/dist/utils/OpenApiTransformer.d.ts +38 -0
- package/dist/utils/OpenApiTransformer.d.ts.map +1 -0
- package/dist/utils/OpenApiTransformer.js +182 -0
- package/dist/utils/OpenApiTransformer.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DocsController = void 0;
|
|
16
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
let DocsController = class DocsController {
|
|
19
|
+
constructor(openApiSpec) {
|
|
20
|
+
this.openApiSpec = openApiSpec;
|
|
21
|
+
}
|
|
22
|
+
getDocs() {
|
|
23
|
+
return `
|
|
24
|
+
<!DOCTYPE html>
|
|
25
|
+
<html>
|
|
26
|
+
<head>
|
|
27
|
+
<title>Nest-Scramble API Docs</title>
|
|
28
|
+
<meta charset="utf-8" />
|
|
29
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
30
|
+
<style>
|
|
31
|
+
body { margin: 0; }
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<div id="scalar-container"></div>
|
|
36
|
+
<script>
|
|
37
|
+
window.onload = function() {
|
|
38
|
+
// Simple mock of Scalar API Reference
|
|
39
|
+
const container = document.getElementById('scalar-container');
|
|
40
|
+
container.innerHTML = '<h1>Nest-Scramble API Documentation</h1><p>OpenAPI spec available at <a href="/docs/spec">/docs/spec</a></p>';
|
|
41
|
+
};
|
|
42
|
+
</script>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
getOpenApiSpec() {
|
|
48
|
+
return this.openApiSpec;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.DocsController = DocsController;
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, common_1.Get)('docs'),
|
|
54
|
+
__metadata("design:type", Function),
|
|
55
|
+
__metadata("design:paramtypes", []),
|
|
56
|
+
__metadata("design:returntype", void 0)
|
|
57
|
+
], DocsController.prototype, "getDocs", null);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, common_1.Get)('docs/spec'),
|
|
60
|
+
__metadata("design:type", Function),
|
|
61
|
+
__metadata("design:paramtypes", []),
|
|
62
|
+
__metadata("design:returntype", void 0)
|
|
63
|
+
], DocsController.prototype, "getOpenApiSpec", null);
|
|
64
|
+
exports.DocsController = DocsController = __decorate([
|
|
65
|
+
(0, common_1.Controller)(),
|
|
66
|
+
__param(0, (0, common_1.Inject)('NEST_SCRAMBLE_OPENAPI')),
|
|
67
|
+
__metadata("design:paramtypes", [Object])
|
|
68
|
+
], DocsController);
|
|
69
|
+
//# sourceMappingURL=DocsController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocsController.js","sourceRoot":"","sources":["../../src/controllers/DocsController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,2CAAyD;AAGlD,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAC2C,WAAgB;QAAhB,gBAAW,GAAX,WAAW,CAAK;IACxD,CAAC;IAGJ,OAAO;QACL,OAAO;;;;;;;;;;;;;;;;;;;;;;KAsBN,CAAC;IACJ,CAAC;IAGD,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF,CAAA;AApCY,wCAAc;AAMzB;IADC,IAAA,YAAG,EAAC,MAAM,CAAC;;;;6CAyBX;AAGD;IADC,IAAA,YAAG,EAAC,WAAW,CAAC;;;;oDAGhB;yBAnCU,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,uBAAuB,CAAC,CAAA;;GAFvB,cAAc,CAoC1B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
2
|
+
import { ControllerInfo } from '../scanner/ScannerService';
|
|
3
|
+
interface PostmanCollection {
|
|
4
|
+
info: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
schema: string;
|
|
8
|
+
};
|
|
9
|
+
item: PostmanItem[];
|
|
10
|
+
variable?: PostmanVariable[];
|
|
11
|
+
}
|
|
12
|
+
interface PostmanItem {
|
|
13
|
+
name: string;
|
|
14
|
+
item?: PostmanItem[];
|
|
15
|
+
request?: PostmanRequest;
|
|
16
|
+
}
|
|
17
|
+
interface PostmanRequest {
|
|
18
|
+
method: string;
|
|
19
|
+
header: PostmanHeader[];
|
|
20
|
+
body?: {
|
|
21
|
+
mode: string;
|
|
22
|
+
raw?: string;
|
|
23
|
+
};
|
|
24
|
+
url: {
|
|
25
|
+
raw: string;
|
|
26
|
+
host: string[];
|
|
27
|
+
path: string[];
|
|
28
|
+
query?: PostmanQuery[];
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
interface PostmanHeader {
|
|
32
|
+
key: string;
|
|
33
|
+
value: string;
|
|
34
|
+
type?: string;
|
|
35
|
+
}
|
|
36
|
+
interface PostmanQuery {
|
|
37
|
+
key: string;
|
|
38
|
+
value: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
}
|
|
41
|
+
interface PostmanVariable {
|
|
42
|
+
key: string;
|
|
43
|
+
value: string;
|
|
44
|
+
type: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class PostmanCollectionGenerator {
|
|
47
|
+
private baseUrl;
|
|
48
|
+
constructor(baseUrl?: string);
|
|
49
|
+
/**
|
|
50
|
+
* Generates a Postman Collection from scanned controllers
|
|
51
|
+
* @param controllers Array of controller information
|
|
52
|
+
* @param collectionName Name of the collection
|
|
53
|
+
* @returns Postman Collection JSON
|
|
54
|
+
*/
|
|
55
|
+
generateCollection(controllers: ControllerInfo[], collectionName?: string): PostmanCollection;
|
|
56
|
+
private createRequest;
|
|
57
|
+
private buildPath;
|
|
58
|
+
private parseUrl;
|
|
59
|
+
}
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=PostmanCollectionGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostmanCollectionGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/PostmanCollectionGenerator.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,cAAc,EAAc,MAAM,2BAA2B,CAAC;AAGvE,UAAU,iBAAiB;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,GAAG,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;KACxB,CAAC;CACH;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,eAAe;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,SAAgB;IAInC;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,cAAc,SAAe,GAAG,iBAAiB;IAqCnG,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,QAAQ;CAWjB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostmanCollectionGenerator = void 0;
|
|
4
|
+
const MockGenerator_1 = require("../utils/MockGenerator");
|
|
5
|
+
class PostmanCollectionGenerator {
|
|
6
|
+
constructor(baseUrl = '{{baseUrl}}') {
|
|
7
|
+
this.baseUrl = baseUrl;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generates a Postman Collection from scanned controllers
|
|
11
|
+
* @param controllers Array of controller information
|
|
12
|
+
* @param collectionName Name of the collection
|
|
13
|
+
* @returns Postman Collection JSON
|
|
14
|
+
*/
|
|
15
|
+
generateCollection(controllers, collectionName = 'NestJS API') {
|
|
16
|
+
const items = [];
|
|
17
|
+
for (const controller of controllers) {
|
|
18
|
+
const folder = {
|
|
19
|
+
name: controller.name,
|
|
20
|
+
item: [],
|
|
21
|
+
};
|
|
22
|
+
for (const method of controller.methods) {
|
|
23
|
+
const request = this.createRequest(controller, method);
|
|
24
|
+
folder.item.push({
|
|
25
|
+
name: `${method.httpMethod} ${method.name}`,
|
|
26
|
+
request,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
items.push(folder);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
info: {
|
|
33
|
+
name: collectionName,
|
|
34
|
+
description: 'Generated from NestJS controllers using nest-scramble',
|
|
35
|
+
schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',
|
|
36
|
+
},
|
|
37
|
+
item: items,
|
|
38
|
+
variable: [
|
|
39
|
+
{
|
|
40
|
+
key: 'baseUrl',
|
|
41
|
+
value: 'http://localhost:3000',
|
|
42
|
+
type: 'string',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
createRequest(controller, method) {
|
|
48
|
+
const fullPath = this.buildPath(controller.path, method.route);
|
|
49
|
+
const url = this.parseUrl(fullPath);
|
|
50
|
+
const request = {
|
|
51
|
+
method: method.httpMethod,
|
|
52
|
+
header: [
|
|
53
|
+
{
|
|
54
|
+
key: 'Content-Type',
|
|
55
|
+
value: 'application/json',
|
|
56
|
+
type: 'text',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
url,
|
|
60
|
+
};
|
|
61
|
+
// Add body if there's a @Body parameter
|
|
62
|
+
const bodyParam = method.parameters.find(p => p.decorator?.includes('@Body'));
|
|
63
|
+
if (bodyParam && bodyParam.type.properties) {
|
|
64
|
+
const mockData = MockGenerator_1.MockGenerator.generateMock(bodyParam.type);
|
|
65
|
+
request.body = {
|
|
66
|
+
mode: 'raw',
|
|
67
|
+
raw: JSON.stringify(mockData, null, 2),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Add query params if there's a @Query parameter
|
|
71
|
+
const queryParam = method.parameters.find(p => p.decorator?.includes('@Query'));
|
|
72
|
+
if (queryParam && queryParam.type.properties) {
|
|
73
|
+
const mockData = MockGenerator_1.MockGenerator.generateMock(queryParam.type);
|
|
74
|
+
request.url.query = Object.entries(mockData).map(([key, value]) => ({
|
|
75
|
+
key,
|
|
76
|
+
value: String(value),
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
return request;
|
|
80
|
+
}
|
|
81
|
+
buildPath(controllerPath, methodRoute) {
|
|
82
|
+
const parts = [controllerPath, methodRoute].filter(p => p);
|
|
83
|
+
return parts.join('/').replace(/\/+/g, '/');
|
|
84
|
+
}
|
|
85
|
+
parseUrl(path) {
|
|
86
|
+
const segments = path.split('/').filter(s => s);
|
|
87
|
+
const host = [this.baseUrl];
|
|
88
|
+
const pathArray = segments;
|
|
89
|
+
return {
|
|
90
|
+
raw: `${this.baseUrl}/${segments.join('/')}`,
|
|
91
|
+
host,
|
|
92
|
+
path: pathArray,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.PostmanCollectionGenerator = PostmanCollectionGenerator;
|
|
97
|
+
//# sourceMappingURL=PostmanCollectionGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostmanCollectionGenerator.js","sourceRoot":"","sources":["../../src/generators/PostmanCollectionGenerator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
2
|
+
export * from './generators/PostmanCollectionGenerator';
|
|
3
|
+
export * from './NestScrambleModule';
|
|
4
|
+
export * from './scanner/ScannerService';
|
|
5
|
+
export * from './utils/DtoAnalyzer';
|
|
6
|
+
export * from './utils/MockGenerator';
|
|
7
|
+
export * from './utils/OpenApiTransformer';
|
|
8
|
+
export * from './middleware/MockMiddleware';
|
|
9
|
+
export * from './controllers/DocsController';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,yCAAyC,CAAC;AACxD,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
18
|
+
__exportStar(require("./generators/PostmanCollectionGenerator"), exports);
|
|
19
|
+
__exportStar(require("./NestScrambleModule"), exports);
|
|
20
|
+
__exportStar(require("./scanner/ScannerService"), exports);
|
|
21
|
+
__exportStar(require("./utils/DtoAnalyzer"), exports);
|
|
22
|
+
__exportStar(require("./utils/MockGenerator"), exports);
|
|
23
|
+
__exportStar(require("./utils/OpenApiTransformer"), exports);
|
|
24
|
+
__exportStar(require("./middleware/MockMiddleware"), exports);
|
|
25
|
+
__exportStar(require("./controllers/DocsController"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,0EAAwD;AACxD,uDAAqC;AACrC,2DAAyC;AACzC,sDAAoC;AACpC,wDAAsC;AACtC,6DAA2C;AAC3C,8DAA4C;AAC5C,+DAA6C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
2
|
+
import { NestMiddleware } from '@nestjs/common';
|
|
3
|
+
import { ControllerInfo } from '../scanner/ScannerService';
|
|
4
|
+
import { MockGenerator } from '../utils/MockGenerator';
|
|
5
|
+
export declare class MockMiddleware implements NestMiddleware {
|
|
6
|
+
private controllers;
|
|
7
|
+
private mockGenerator;
|
|
8
|
+
constructor(controllers: ControllerInfo[], mockGenerator: MockGenerator);
|
|
9
|
+
use(req: any, res: any, next: any): any;
|
|
10
|
+
private findMatchingRoute;
|
|
11
|
+
private buildPath;
|
|
12
|
+
private matchPath;
|
|
13
|
+
private getStatusCode;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=MockMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/MockMiddleware.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAc,cAAc,EAAU,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAc,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,qBACa,cAAe,YAAW,cAAc;IAEZ,OAAO,CAAC,WAAW;IACxD,OAAO,CAAC,aAAa;gBADwB,WAAW,EAAE,cAAc,EAAE,EAClE,aAAa,EAAE,aAAa;IAGtC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;IA0BjC,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,aAAa;CAUtB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.MockMiddleware = void 0;
|
|
16
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const MockGenerator_1 = require("../utils/MockGenerator");
|
|
19
|
+
let MockMiddleware = class MockMiddleware {
|
|
20
|
+
constructor(controllers, mockGenerator) {
|
|
21
|
+
this.controllers = controllers;
|
|
22
|
+
this.mockGenerator = mockGenerator;
|
|
23
|
+
}
|
|
24
|
+
use(req, res, next) {
|
|
25
|
+
const path = req.path;
|
|
26
|
+
// Check if path starts with /scramble-mock/
|
|
27
|
+
if (!path.startsWith('/scramble-mock/')) {
|
|
28
|
+
return next();
|
|
29
|
+
}
|
|
30
|
+
// Remove /scramble-mock/ prefix
|
|
31
|
+
const apiPath = path.replace('/scramble-mock', '');
|
|
32
|
+
// Find matching route
|
|
33
|
+
const match = this.findMatchingRoute(apiPath, req.method);
|
|
34
|
+
if (!match) {
|
|
35
|
+
return res.status(404).json({ error: 'Route not found in scanned controllers' });
|
|
36
|
+
}
|
|
37
|
+
// Generate mock response
|
|
38
|
+
const mockData = MockGenerator_1.MockGenerator.generateMock(match.method.returnType);
|
|
39
|
+
// Set appropriate status code (default to 200)
|
|
40
|
+
const statusCode = this.getStatusCode(match.method.httpMethod);
|
|
41
|
+
res.status(statusCode).json(mockData);
|
|
42
|
+
}
|
|
43
|
+
findMatchingRoute(path, method) {
|
|
44
|
+
for (const controller of this.controllers) {
|
|
45
|
+
for (const methodInfo of controller.methods) {
|
|
46
|
+
if (methodInfo.httpMethod !== method)
|
|
47
|
+
continue;
|
|
48
|
+
const fullPath = this.buildPath(controller.path, methodInfo.route);
|
|
49
|
+
if (this.matchPath(fullPath, path)) {
|
|
50
|
+
return { controller, method: methodInfo };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
buildPath(controllerPath, methodRoute) {
|
|
57
|
+
const parts = [controllerPath, methodRoute].filter(p => p);
|
|
58
|
+
return '/' + parts.join('/').replace(/\/+/g, '/');
|
|
59
|
+
}
|
|
60
|
+
matchPath(routePath, requestPath) {
|
|
61
|
+
// Simple path matching - could be enhanced with parameter extraction
|
|
62
|
+
// For now, exact match or with path params like :id
|
|
63
|
+
const routeParts = routePath.split('/').filter(p => p);
|
|
64
|
+
const requestParts = requestPath.split('/').filter(p => p);
|
|
65
|
+
if (routeParts.length !== requestParts.length)
|
|
66
|
+
return false;
|
|
67
|
+
for (let i = 0; i < routeParts.length; i++) {
|
|
68
|
+
const routePart = routeParts[i];
|
|
69
|
+
const requestPart = requestParts[i];
|
|
70
|
+
if (routePart.startsWith(':'))
|
|
71
|
+
continue; // Path parameter
|
|
72
|
+
if (routePart !== requestPart)
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
getStatusCode(httpMethod) {
|
|
78
|
+
switch (httpMethod) {
|
|
79
|
+
case 'POST':
|
|
80
|
+
return 201;
|
|
81
|
+
case 'DELETE':
|
|
82
|
+
return 204;
|
|
83
|
+
default:
|
|
84
|
+
return 200;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
exports.MockMiddleware = MockMiddleware;
|
|
89
|
+
exports.MockMiddleware = MockMiddleware = __decorate([
|
|
90
|
+
(0, common_1.Injectable)(),
|
|
91
|
+
__param(0, (0, common_1.Inject)('NEST_SCRAMBLE_CONTROLLERS')),
|
|
92
|
+
__metadata("design:paramtypes", [Array, MockGenerator_1.MockGenerator])
|
|
93
|
+
], MockMiddleware);
|
|
94
|
+
//# sourceMappingURL=MockMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockMiddleware.js","sourceRoot":"","sources":["../../src/middleware/MockMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AnalyzedType } from '../utils/DtoAnalyzer';
|
|
2
|
+
export interface ControllerInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
methods: MethodInfo[];
|
|
6
|
+
}
|
|
7
|
+
export interface MethodInfo {
|
|
8
|
+
name: string;
|
|
9
|
+
httpMethod: string;
|
|
10
|
+
route: string;
|
|
11
|
+
parameters: ParameterInfo[];
|
|
12
|
+
returnType: AnalyzedType;
|
|
13
|
+
}
|
|
14
|
+
export interface ParameterInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
type: AnalyzedType;
|
|
17
|
+
decorator?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class ScannerService {
|
|
20
|
+
private project;
|
|
21
|
+
private dtoAnalyzer;
|
|
22
|
+
constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Scans the source directory for controllers and their methods
|
|
25
|
+
* @param sourcePath Path to the source directory (e.g., 'src')
|
|
26
|
+
* @returns Array of ControllerInfo
|
|
27
|
+
*/
|
|
28
|
+
scanControllers(sourcePath: string): ControllerInfo[];
|
|
29
|
+
private hasControllerDecorator;
|
|
30
|
+
private extractControllerInfo;
|
|
31
|
+
private extractDecoratorArgument;
|
|
32
|
+
private extractMethodInfo;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ScannerService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScannerService.d.ts","sourceRoot":"","sources":["../../src/scanner/ScannerService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAe,MAAM,sBAAsB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAqB;;IAQxC;;;;OAIG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAqBrD,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,iBAAiB;CAiC1B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScannerService = void 0;
|
|
4
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
5
|
+
const ts_morph_1 = require("ts-morph");
|
|
6
|
+
const DtoAnalyzer_1 = require("../utils/DtoAnalyzer");
|
|
7
|
+
class ScannerService {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.dtoAnalyzer = new DtoAnalyzer_1.DtoAnalyzer();
|
|
10
|
+
this.project = new ts_morph_1.Project({
|
|
11
|
+
tsConfigFilePath: 'tsconfig.json', // Assume tsconfig.json exists
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Scans the source directory for controllers and their methods
|
|
16
|
+
* @param sourcePath Path to the source directory (e.g., 'src')
|
|
17
|
+
* @returns Array of ControllerInfo
|
|
18
|
+
*/
|
|
19
|
+
scanControllers(sourcePath) {
|
|
20
|
+
// Add source files to the project
|
|
21
|
+
this.project.addSourceFilesAtPaths(`${sourcePath}/**/*.ts`);
|
|
22
|
+
const controllers = [];
|
|
23
|
+
// Find all classes decorated with @Controller
|
|
24
|
+
const controllerClasses = this.project.getSourceFiles()
|
|
25
|
+
.flatMap(file => file.getClasses())
|
|
26
|
+
.filter(cls => this.hasControllerDecorator(cls));
|
|
27
|
+
for (const controllerClass of controllerClasses) {
|
|
28
|
+
const controllerInfo = this.extractControllerInfo(controllerClass);
|
|
29
|
+
if (controllerInfo) {
|
|
30
|
+
controllers.push(controllerInfo);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return controllers;
|
|
34
|
+
}
|
|
35
|
+
hasControllerDecorator(cls) {
|
|
36
|
+
return cls.getDecorators().some(decorator => {
|
|
37
|
+
const callExpression = decorator.getCallExpression();
|
|
38
|
+
if (!callExpression)
|
|
39
|
+
return false;
|
|
40
|
+
const expression = callExpression.getExpression();
|
|
41
|
+
return ts_morph_1.Node.isIdentifier(expression) && expression.getText() === 'Controller';
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
extractControllerInfo(cls) {
|
|
45
|
+
const controllerDecorator = cls.getDecorators().find(decorator => {
|
|
46
|
+
const callExpression = decorator.getCallExpression();
|
|
47
|
+
if (!callExpression)
|
|
48
|
+
return false;
|
|
49
|
+
const expression = callExpression.getExpression();
|
|
50
|
+
return ts_morph_1.Node.isIdentifier(expression) && expression.getText() === 'Controller';
|
|
51
|
+
});
|
|
52
|
+
if (!controllerDecorator)
|
|
53
|
+
return null;
|
|
54
|
+
const controllerPath = this.extractDecoratorArgument(controllerDecorator) || '';
|
|
55
|
+
const methods = [];
|
|
56
|
+
for (const method of cls.getMethods()) {
|
|
57
|
+
const methodInfo = this.extractMethodInfo(method);
|
|
58
|
+
if (methodInfo) {
|
|
59
|
+
methods.push(methodInfo);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
name: cls.getName() || 'UnknownController',
|
|
64
|
+
path: controllerPath,
|
|
65
|
+
methods,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
extractDecoratorArgument(decorator) {
|
|
69
|
+
const callExpression = decorator.getCallExpression();
|
|
70
|
+
if (!callExpression)
|
|
71
|
+
return undefined;
|
|
72
|
+
const args = callExpression.getArguments();
|
|
73
|
+
if (args.length === 0)
|
|
74
|
+
return '';
|
|
75
|
+
const firstArg = args[0];
|
|
76
|
+
if (ts_morph_1.Node.isStringLiteral(firstArg)) {
|
|
77
|
+
return firstArg.getLiteralValue();
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
extractMethodInfo(method) {
|
|
82
|
+
const httpDecorator = method.getDecorators().find(decorator => {
|
|
83
|
+
const callExpression = decorator.getCallExpression();
|
|
84
|
+
if (!callExpression)
|
|
85
|
+
return false;
|
|
86
|
+
const expression = callExpression.getExpression();
|
|
87
|
+
if (!ts_morph_1.Node.isIdentifier(expression))
|
|
88
|
+
return false;
|
|
89
|
+
const decoratorName = expression.getText();
|
|
90
|
+
return ['Get', 'Post', 'Put', 'Delete', 'Patch'].includes(decoratorName);
|
|
91
|
+
});
|
|
92
|
+
if (!httpDecorator)
|
|
93
|
+
return null;
|
|
94
|
+
const callExpression = httpDecorator.getCallExpression();
|
|
95
|
+
const expression = callExpression.getExpression();
|
|
96
|
+
const httpMethod = expression.getText().toUpperCase();
|
|
97
|
+
const route = this.extractDecoratorArgument(httpDecorator) || '';
|
|
98
|
+
const parameters = method.getParameters().map(param => ({
|
|
99
|
+
name: param.getName(),
|
|
100
|
+
type: this.dtoAnalyzer.analyzeType(param.getType()),
|
|
101
|
+
decorator: param.getDecorators().map(d => d.getText()).join(' '),
|
|
102
|
+
}));
|
|
103
|
+
const returnType = this.dtoAnalyzer.analyzeType(method.getReturnType());
|
|
104
|
+
return {
|
|
105
|
+
name: method.getName(),
|
|
106
|
+
httpMethod,
|
|
107
|
+
route,
|
|
108
|
+
parameters,
|
|
109
|
+
returnType,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.ScannerService = ScannerService;
|
|
114
|
+
//# sourceMappingURL=ScannerService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScannerService.js","sourceRoot":"","sources":["../../src/scanner/ScannerService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Nest-Scramble | Developed by Mohamed Mustafa | MIT License **/
|
|
2
|
+
import { Type } from 'ts-morph';
|
|
3
|
+
export interface AnalyzedType {
|
|
4
|
+
type: string;
|
|
5
|
+
isArray: boolean;
|
|
6
|
+
isOptional: boolean;
|
|
7
|
+
properties?: PropertyInfo[];
|
|
8
|
+
unionTypes?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface PropertyInfo {
|
|
11
|
+
name: string;
|
|
12
|
+
type: AnalyzedType;
|
|
13
|
+
}
|
|
14
|
+
export declare class DtoAnalyzer {
|
|
15
|
+
private visited;
|
|
16
|
+
/**
|
|
17
|
+
* Analyzes a TypeScript type and returns detailed information
|
|
18
|
+
* @param type The TypeScript type to analyze
|
|
19
|
+
* @param isOptional Whether the type is optional
|
|
20
|
+
* @returns AnalyzedType with full type information
|
|
21
|
+
*/
|
|
22
|
+
analyzeType(type: Type, isOptional?: boolean): AnalyzedType;
|
|
23
|
+
private extractProperties;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=DtoAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DtoAnalyzer.d.ts","sourceRoot":"","sources":["../../src/utils/DtoAnalyzer.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAgD,IAAI,EAAE,MAAM,UAAU,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAqB;IAEpC;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,UAAQ,GAAG,YAAY;IAmEzD,OAAO,CAAC,iBAAiB;CAkB1B"}
|