@asad_dev/leo-generator 1.6.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/CHANGELOG.md +194 -0
- package/COMMAND_REFERENCE.md +412 -0
- package/README.md +486 -0
- package/dist/app/modules/imagemodule/imagemodule.constants.js +18 -0
- package/dist/app/modules/imagemodule/imagemodule.controller.js +98 -0
- package/dist/app/modules/imagemodule/imagemodule.interface.js +2 -0
- package/dist/app/modules/imagemodule/imagemodule.model.js +10 -0
- package/dist/app/modules/imagemodule/imagemodule.route.js +20 -0
- package/dist/app/modules/imagemodule/imagemodule.service.js +137 -0
- package/dist/app/modules/imagemodule/imagemodule.validation.js +12 -0
- package/dist/app/modules/skiptest/skiptest.controller.js +81 -0
- package/dist/app/modules/skiptest/skiptest.route.js +19 -0
- package/dist/app/modules/skiptest/skiptest.service.js +129 -0
- package/dist/app/modules/skiptest/skiptest.validation.js +12 -0
- package/dist/app/modules/testmodule/testmodule.constants.js +18 -0
- package/dist/app/modules/testmodule/testmodule.controller.js +81 -0
- package/dist/app/modules/testmodule/testmodule.interface.js +2 -0
- package/dist/app/modules/testmodule/testmodule.model.js +11 -0
- package/dist/app/modules/testmodule/testmodule.route.js +19 -0
- package/dist/app/modules/testmodule/testmodule.service.js +129 -0
- package/dist/app/modules/testmodule/testmodule.validation.js +14 -0
- package/dist/helpers/fileHelper.js +44 -0
- package/dist/index.js +586 -0
- package/dist/templates/constants.template.js +24 -0
- package/dist/templates/controller.template.js +108 -0
- package/dist/templates/route.template.js +68 -0
- package/dist/templates/service.template.js +184 -0
- package/dist/types.js +2 -0
- package/dist/utils/documentationUpdater.js +430 -0
- package/dist/utils/fieldParser.js +163 -0
- package/dist/utils/helperGenerator.js +87 -0
- package/dist/utils/interfaceGenerator.js +158 -0
- package/dist/utils/modelGenerator.js +140 -0
- package/dist/utils/postmanApi.js +113 -0
- package/dist/utils/postmanGenerator.js +283 -0
- package/dist/utils/swaggerGenerator.js +444 -0
- package/dist/utils/validationGenerator.js +170 -0
- package/package.json +58 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateInterfaceContent = generateInterfaceContent;
|
|
4
|
+
function generateInterfaceContent(camelCaseName, fields) {
|
|
5
|
+
let interfaceContent = `import { Model, Types } from 'mongoose';\n\n`;
|
|
6
|
+
// Generate nested interfaces for array of objects
|
|
7
|
+
fields.forEach((field) => {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
if (field.type.toLowerCase() === "array" &&
|
|
10
|
+
((_a = field.ref) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "object" &&
|
|
11
|
+
((_b = field.objectProperties) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
12
|
+
const nestedInterfaceName = `${toCamelCase(field.name)}Item`;
|
|
13
|
+
interfaceContent += `export interface ${nestedInterfaceName} {\n`;
|
|
14
|
+
field.objectProperties.forEach((prop) => {
|
|
15
|
+
// Skip _id field
|
|
16
|
+
if (prop.name.toLowerCase() === "_id") {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const optionalMarker = prop.isOptional ? "?" : "";
|
|
20
|
+
const tsType = mapToTypeScriptType(prop);
|
|
21
|
+
interfaceContent += ` ${prop.name}${optionalMarker}: ${tsType};\n`;
|
|
22
|
+
});
|
|
23
|
+
interfaceContent += `}\n\n`;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// Generate enum types
|
|
27
|
+
fields.forEach((field) => {
|
|
28
|
+
if (field.type.toLowerCase() === "enum" &&
|
|
29
|
+
field.enumValues &&
|
|
30
|
+
field.enumValues.length > 0) {
|
|
31
|
+
const enumName = `${toCamelCase(field.name)}Enum`;
|
|
32
|
+
interfaceContent += `export enum ${enumName} {\n`;
|
|
33
|
+
field.enumValues.forEach(value => {
|
|
34
|
+
// Handle special characters in enum keys if necessary, simplified for now
|
|
35
|
+
const key = value.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
36
|
+
interfaceContent += ` ${key} = '${value}',\n`;
|
|
37
|
+
});
|
|
38
|
+
interfaceContent += `}\n\n`;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// Generate filterable interface
|
|
42
|
+
const filterableFields = fields.filter(f => f.type.toLowerCase() === "string" || f.type.toLowerCase() === "enum");
|
|
43
|
+
if (filterableFields.length > 0) {
|
|
44
|
+
interfaceContent += `export interface I${camelCaseName}Filterables {\n`;
|
|
45
|
+
interfaceContent += ` searchTerm?: string;\n`;
|
|
46
|
+
filterableFields.forEach((field) => {
|
|
47
|
+
let tsType = mapToTypeScriptType(field);
|
|
48
|
+
// Use enum type if applicable
|
|
49
|
+
if (field.type.toLowerCase() === "enum" &&
|
|
50
|
+
field.enumValues &&
|
|
51
|
+
field.enumValues.length > 0) {
|
|
52
|
+
tsType = `${toCamelCase(field.name)}Enum`;
|
|
53
|
+
}
|
|
54
|
+
interfaceContent += ` ${field.name}?: ${tsType};\n`;
|
|
55
|
+
});
|
|
56
|
+
interfaceContent += `}\n\n`;
|
|
57
|
+
}
|
|
58
|
+
// Generate main interface
|
|
59
|
+
interfaceContent += `export interface I${camelCaseName} {\n`;
|
|
60
|
+
interfaceContent += ` _id: Types.ObjectId;\n`;
|
|
61
|
+
if (fields.length > 0) {
|
|
62
|
+
fields.forEach((field) => {
|
|
63
|
+
// Skip _id field as it's already included
|
|
64
|
+
if (field.name.toLowerCase() === "_id") {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const optionalMarker = field.isOptional ? "?" : "";
|
|
68
|
+
let tsType = mapToTypeScriptType(field);
|
|
69
|
+
// Use enum type if applicable
|
|
70
|
+
if (field.type.toLowerCase() === "enum" &&
|
|
71
|
+
field.enumValues &&
|
|
72
|
+
field.enumValues.length > 0) {
|
|
73
|
+
tsType = `${toCamelCase(field.name)}Enum`;
|
|
74
|
+
}
|
|
75
|
+
interfaceContent += ` ${field.name}${optionalMarker}: ${tsType};\n`;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
interfaceContent += ` // Define interface properties here\n`;
|
|
80
|
+
}
|
|
81
|
+
interfaceContent += `}\n\n`;
|
|
82
|
+
// Generate model interface
|
|
83
|
+
interfaceContent += `export type ${camelCaseName}Model = Model<I${camelCaseName}, {}, {}>;\n`;
|
|
84
|
+
return interfaceContent;
|
|
85
|
+
}
|
|
86
|
+
// Helper function to convert to camelCase
|
|
87
|
+
function toCamelCase(str) {
|
|
88
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
89
|
+
}
|
|
90
|
+
// Helper function to map field definitions to TypeScript types
|
|
91
|
+
function mapToTypeScriptType(field) {
|
|
92
|
+
var _a, _b, _c;
|
|
93
|
+
switch (field.type.toLowerCase()) {
|
|
94
|
+
case "string":
|
|
95
|
+
return "string";
|
|
96
|
+
case "number":
|
|
97
|
+
return "number";
|
|
98
|
+
case "boolean":
|
|
99
|
+
return "boolean";
|
|
100
|
+
case "date":
|
|
101
|
+
return "Date";
|
|
102
|
+
case "enum":
|
|
103
|
+
if (field.enumValues && field.enumValues.length > 0) {
|
|
104
|
+
return `${toCamelCase(field.name)}Enum`;
|
|
105
|
+
}
|
|
106
|
+
return "string";
|
|
107
|
+
case "array":
|
|
108
|
+
if (((_a = field.ref) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "object" &&
|
|
109
|
+
((_b = field.objectProperties) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
110
|
+
// Array of objects with defined structure
|
|
111
|
+
const nestedInterfaceName = `${toCamelCase(field.name)}Item`;
|
|
112
|
+
return `${nestedInterfaceName}[]`;
|
|
113
|
+
}
|
|
114
|
+
else if (field.arrayItemType) {
|
|
115
|
+
// Array with specified item type
|
|
116
|
+
switch (field.arrayItemType.toLowerCase()) {
|
|
117
|
+
case "string":
|
|
118
|
+
return "string[]";
|
|
119
|
+
case "number":
|
|
120
|
+
return "number[]";
|
|
121
|
+
case "boolean":
|
|
122
|
+
return "boolean[]";
|
|
123
|
+
case "date":
|
|
124
|
+
return "Date[]";
|
|
125
|
+
case "objectid":
|
|
126
|
+
case "id":
|
|
127
|
+
return "Types.ObjectId[]";
|
|
128
|
+
default:
|
|
129
|
+
return "string[]"; // Default to string[] instead of any[]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (field.ref && field.type.toLowerCase() === "array") {
|
|
133
|
+
// Handle array of references (e.g., products:array:objectid:Product)
|
|
134
|
+
return "Types.ObjectId[]";
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
return "string[]"; // Default to string[] instead of any[]
|
|
138
|
+
}
|
|
139
|
+
case "object":
|
|
140
|
+
if ((_c = field.objectProperties) === null || _c === void 0 ? void 0 : _c.length) {
|
|
141
|
+
// Object with defined properties
|
|
142
|
+
return `{ ${field.objectProperties
|
|
143
|
+
.map((prop) => {
|
|
144
|
+
const optionalMarker = prop.isOptional ? "?" : "";
|
|
145
|
+
return `${prop.name}${optionalMarker}: ${mapToTypeScriptType(prop)}`;
|
|
146
|
+
})
|
|
147
|
+
.join("; ")} }`;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
return "Record<string, any>";
|
|
151
|
+
}
|
|
152
|
+
case "objectid":
|
|
153
|
+
case "id":
|
|
154
|
+
return "Types.ObjectId";
|
|
155
|
+
default:
|
|
156
|
+
return "string"; // Default to string instead of any
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateModelContent = generateModelContent;
|
|
4
|
+
function generateModelContent(camelCaseName, folderName, fields) {
|
|
5
|
+
let modelContent = `import { Schema, model } from 'mongoose';\nimport { I${camelCaseName}, ${camelCaseName}Model } from './${folderName}.interface';\n\n`;
|
|
6
|
+
// Generate nested schemas
|
|
7
|
+
const nestedSchemas = generateNestedSchemas(fields);
|
|
8
|
+
modelContent += nestedSchemas;
|
|
9
|
+
modelContent += `const ${folderName}Schema = new Schema<I${camelCaseName}, ${camelCaseName}Model>({\n`;
|
|
10
|
+
// Add fields to schema
|
|
11
|
+
if (fields.length > 0) {
|
|
12
|
+
fields.forEach((field) => {
|
|
13
|
+
// Skip _id field as it's automatically handled by MongoDB
|
|
14
|
+
if (field.name.toLowerCase() === "_id") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let schemaType = mapToMongooseType(field);
|
|
18
|
+
if (!schemaType)
|
|
19
|
+
return; // Skip if empty (like for _id)
|
|
20
|
+
let additionalProps = "";
|
|
21
|
+
// Add required property if marked as required
|
|
22
|
+
if (field.isRequired) {
|
|
23
|
+
additionalProps += ", required: true";
|
|
24
|
+
}
|
|
25
|
+
// Add default value for enum if it has values
|
|
26
|
+
if (field.type.toLowerCase() === "enum" &&
|
|
27
|
+
field.enumValues &&
|
|
28
|
+
field.enumValues.length > 0) {
|
|
29
|
+
additionalProps += `, default: '${field.enumValues[0]}'`;
|
|
30
|
+
}
|
|
31
|
+
modelContent += ` ${field.name}: ${schemaType}${additionalProps},\n`;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
modelContent += " // Define schema fields here\n";
|
|
36
|
+
}
|
|
37
|
+
modelContent += `}, {\n timestamps: true\n});\n\nexport const ${camelCaseName} = model<I${camelCaseName}, ${camelCaseName}Model>('${camelCaseName}', ${folderName}Schema);\n`;
|
|
38
|
+
return modelContent;
|
|
39
|
+
}
|
|
40
|
+
// Helper function to generate nested schemas for complex types
|
|
41
|
+
function generateNestedSchemas(fields) {
|
|
42
|
+
let nestedSchemas = "";
|
|
43
|
+
fields.forEach((field) => {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
if (field.type.toLowerCase() === "array" &&
|
|
46
|
+
((_a = field.ref) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "object" &&
|
|
47
|
+
((_b = field.objectProperties) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
48
|
+
const nestedSchemaName = `${field.name}ItemSchema`;
|
|
49
|
+
nestedSchemas += `const ${nestedSchemaName} = new Schema({\n`;
|
|
50
|
+
field.objectProperties.forEach((prop) => {
|
|
51
|
+
// Skip _id field
|
|
52
|
+
if (prop.name.toLowerCase() === "_id") {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
let schemaType = mapToMongooseType(prop);
|
|
56
|
+
let additionalProps = "";
|
|
57
|
+
if (prop.isRequired) {
|
|
58
|
+
additionalProps += ", required: true";
|
|
59
|
+
}
|
|
60
|
+
nestedSchemas += ` ${prop.name}: ${schemaType}${additionalProps},\n`;
|
|
61
|
+
});
|
|
62
|
+
nestedSchemas += `}, { _id: false });\n\n`;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return nestedSchemas;
|
|
66
|
+
}
|
|
67
|
+
// Helper function to map field definitions to Mongoose schema types
|
|
68
|
+
function mapToMongooseType(field) {
|
|
69
|
+
var _a, _b, _c;
|
|
70
|
+
// Skip _id field as it's automatically handled by MongoDB
|
|
71
|
+
if (field.name.toLowerCase() === "_id") {
|
|
72
|
+
return ""; // Skip this field
|
|
73
|
+
}
|
|
74
|
+
switch (field.type.toLowerCase()) {
|
|
75
|
+
case "string":
|
|
76
|
+
return "{ type: String }";
|
|
77
|
+
case "number":
|
|
78
|
+
return "{ type: Number }";
|
|
79
|
+
case "boolean":
|
|
80
|
+
return "{ type: Boolean }";
|
|
81
|
+
case "date":
|
|
82
|
+
return "{ type: Date }";
|
|
83
|
+
case "enum":
|
|
84
|
+
if (field.enumValues && field.enumValues.length > 0) {
|
|
85
|
+
return `{ type: String, enum: ['${field.enumValues.join("', '")}'] }`;
|
|
86
|
+
}
|
|
87
|
+
return "{ type: String }";
|
|
88
|
+
case "array":
|
|
89
|
+
if (((_a = field.ref) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "object" &&
|
|
90
|
+
((_b = field.objectProperties) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
91
|
+
// Array of objects with defined structure
|
|
92
|
+
const nestedSchemaName = `${field.name}ItemSchema`;
|
|
93
|
+
return `[${nestedSchemaName}]`;
|
|
94
|
+
}
|
|
95
|
+
else if (field.arrayItemType) {
|
|
96
|
+
// Array with specified item type
|
|
97
|
+
switch (field.arrayItemType.toLowerCase()) {
|
|
98
|
+
case "string":
|
|
99
|
+
return "{ type: [String] }";
|
|
100
|
+
case "number":
|
|
101
|
+
return "{ type: [Number] }";
|
|
102
|
+
case "boolean":
|
|
103
|
+
return "{ type: [Boolean] }";
|
|
104
|
+
case "date":
|
|
105
|
+
return "{ type: [Date] }";
|
|
106
|
+
case "objectid":
|
|
107
|
+
case "id":
|
|
108
|
+
return `{ type: [Schema.Types.ObjectId], ref: '${field.ref || "Document"}' }`;
|
|
109
|
+
default:
|
|
110
|
+
return "{ type: [String] }"; // Default to String instead of Mixed
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (field.ref) {
|
|
114
|
+
// Handle array of references (e.g., products:array:objectid:Product)
|
|
115
|
+
return `{ type: [Schema.Types.ObjectId], ref: '${field.ref}' }`;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
return "{ type: [String] }"; // Default to String instead of Mixed
|
|
119
|
+
}
|
|
120
|
+
case "object":
|
|
121
|
+
if ((_c = field.objectProperties) === null || _c === void 0 ? void 0 : _c.length) {
|
|
122
|
+
// Object with defined properties
|
|
123
|
+
return `{ ${field.objectProperties
|
|
124
|
+
.map((prop) => {
|
|
125
|
+
return `${prop.name}: ${mapToMongooseType(prop)}`;
|
|
126
|
+
})
|
|
127
|
+
.join(", ")} }`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return "{ type: Schema.Types.Mixed }";
|
|
131
|
+
}
|
|
132
|
+
case "objectid":
|
|
133
|
+
case "id":
|
|
134
|
+
return field.ref
|
|
135
|
+
? `{ type: Schema.Types.ObjectId, ref: '${field.ref}' }`
|
|
136
|
+
: "{ type: Schema.Types.ObjectId }";
|
|
137
|
+
default:
|
|
138
|
+
return "{ type: String }"; // Default to String instead of Mixed
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.updatePostmanCollectionViaApi = updatePostmanCollectionViaApi;
|
|
13
|
+
/**
|
|
14
|
+
* Updates an existing Postman collection via the Postman API.
|
|
15
|
+
* It fetches the existing collection, finds the folder for the current module,
|
|
16
|
+
* and replaces it or adds it to the collection.
|
|
17
|
+
*/
|
|
18
|
+
function updatePostmanCollectionViaApi(moduleName, newCollectionData, config) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const { apiKey, collectionId } = config;
|
|
21
|
+
const url = `https://api.getpostman.com/collections/${collectionId}`;
|
|
22
|
+
try {
|
|
23
|
+
console.log(`đ Connecting to Postman API for collection: ${collectionId}...`);
|
|
24
|
+
// 1. Fetch current collection
|
|
25
|
+
const getResponse = yield fetch(url, {
|
|
26
|
+
headers: {
|
|
27
|
+
"X-Api-Key": apiKey
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
if (!getResponse.ok) {
|
|
31
|
+
const errorData = yield getResponse.json();
|
|
32
|
+
throw new Error(`Failed to fetch collection: ${JSON.stringify(errorData)}`);
|
|
33
|
+
}
|
|
34
|
+
const currentData = yield getResponse.json();
|
|
35
|
+
const collection = currentData.collection;
|
|
36
|
+
console.log(`đĻ Collection Keys: ${Object.keys(collection).join(", ")}`);
|
|
37
|
+
// Handle variables - Postman API is very strict about variable structure
|
|
38
|
+
if (collection.variable) {
|
|
39
|
+
console.log(`đ Found ${collection.variable.length} variables in collection.`);
|
|
40
|
+
if (collection.variable.length > 0) {
|
|
41
|
+
console.log(`đ Sample Variable [0]: ${JSON.stringify(collection.variable[0])}`);
|
|
42
|
+
}
|
|
43
|
+
const allowedTypes = ["string", "secret", "boolean", "number", "any"];
|
|
44
|
+
// Filter and sanitize variables
|
|
45
|
+
const validVariables = collection.variable
|
|
46
|
+
.map((v) => {
|
|
47
|
+
var _a;
|
|
48
|
+
const currentType = (_a = v.type) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
49
|
+
if (!currentType || !allowedTypes.includes(currentType)) {
|
|
50
|
+
// Force to 'string' if invalid or missing
|
|
51
|
+
const newType = "string";
|
|
52
|
+
console.log(` đ§ Variable '${v.key}' has invalid/missing type: '${v.type || "N/A"}'. Setting to '${newType}'.`);
|
|
53
|
+
return Object.assign(Object.assign({}, v), { type: newType });
|
|
54
|
+
}
|
|
55
|
+
return v;
|
|
56
|
+
})
|
|
57
|
+
.filter((v) => v.key && v.type); // Remove any variables without key or type
|
|
58
|
+
// Only keep variable array if it has valid entries
|
|
59
|
+
if (validVariables.length > 0) {
|
|
60
|
+
collection.variable = validVariables;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.log(" đī¸ Removing empty/invalid variable array");
|
|
64
|
+
delete collection.variable;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log("âšī¸ No variables found in retrieved collection.");
|
|
69
|
+
}
|
|
70
|
+
// 2. Prepare the new folder for this module
|
|
71
|
+
// The generator creates a collection where 'item' is the list of requests
|
|
72
|
+
const moduleFolderName = `${moduleName} API`;
|
|
73
|
+
const newModuleFolder = {
|
|
74
|
+
name: moduleFolderName,
|
|
75
|
+
item: newCollectionData.item
|
|
76
|
+
};
|
|
77
|
+
// 3. Update or Add the folder in the existing collection
|
|
78
|
+
if (!collection.item) {
|
|
79
|
+
collection.item = [];
|
|
80
|
+
}
|
|
81
|
+
const existingFolderIndex = collection.item.findIndex((item) => item.name === moduleFolderName);
|
|
82
|
+
if (existingFolderIndex !== -1) {
|
|
83
|
+
console.log(`đ Updating existing folder: ${moduleFolderName} in Postman collection`);
|
|
84
|
+
collection.item[existingFolderIndex] = newModuleFolder;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.log(`â Adding new folder: ${moduleFolderName} to Postman collection`);
|
|
88
|
+
collection.item.push(newModuleFolder);
|
|
89
|
+
}
|
|
90
|
+
// Debug: Log a snippet of what we are sending
|
|
91
|
+
console.log(`đ¤ Sending PUT request to Postman API...`);
|
|
92
|
+
// console.log(`đ¤ Variable snippet: ${JSON.stringify(collection.variable?.slice(0, 1))}`);
|
|
93
|
+
// 4. Send the updated collection back to Postman
|
|
94
|
+
const putResponse = yield fetch(url, {
|
|
95
|
+
method: "PUT",
|
|
96
|
+
headers: {
|
|
97
|
+
"X-Api-Key": apiKey,
|
|
98
|
+
"Content-Type": "application/json"
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({ collection })
|
|
101
|
+
});
|
|
102
|
+
if (!putResponse.ok) {
|
|
103
|
+
const errorData = yield putResponse.json();
|
|
104
|
+
throw new Error(`Failed to update collection: ${JSON.stringify(errorData)}`);
|
|
105
|
+
}
|
|
106
|
+
console.log(`â
Postman collection updated successfully via API!`);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error("â Error updating Postman collection via API:", error instanceof Error ? error.message : String(error));
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|