@postman-enricher/core 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/LICENSE +21 -0
- package/dist/enrichers/descriptions.d.ts +11 -0
- package/dist/enrichers/descriptions.js +88 -0
- package/dist/enrichers/examples.d.ts +11 -0
- package/dist/enrichers/examples.js +122 -0
- package/dist/enrichers/filter.d.ts +11 -0
- package/dist/enrichers/filter.js +54 -0
- package/dist/enrichers/tests.d.ts +11 -0
- package/dist/enrichers/tests.js +82 -0
- package/dist/enrichers/variables.d.ts +11 -0
- package/dist/enrichers/variables.js +101 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +62 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Caio Pizzol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descriptions enricher - Adds rich markdown descriptions to collection, folders, and requests
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, DescriptionConfig } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add descriptions to collection, folders, and requests
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Descriptions configuration
|
|
9
|
+
* @returns Collection with descriptions
|
|
10
|
+
*/
|
|
11
|
+
export declare function addDescriptions(collection: PostmanCollection, config: DescriptionConfig | undefined): PostmanCollection;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descriptions enricher - Adds rich markdown descriptions to collection, folders, and requests
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isFolder, isRequest, getRequestMethod, } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add descriptions to collection, folders, and requests
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Descriptions configuration
|
|
9
|
+
* @returns Collection with descriptions
|
|
10
|
+
*/
|
|
11
|
+
export function addDescriptions(collection, config) {
|
|
12
|
+
if (!config)
|
|
13
|
+
return collection;
|
|
14
|
+
// 1. Update collection-level info
|
|
15
|
+
if (config.collection) {
|
|
16
|
+
const collectionKey = Object.keys(config.collection).find((key) => collection.info.name.includes(key));
|
|
17
|
+
if (collectionKey) {
|
|
18
|
+
const collectionConfig = config.collection[collectionKey];
|
|
19
|
+
if (collectionConfig.name) {
|
|
20
|
+
collection.info.name = collectionConfig.name;
|
|
21
|
+
}
|
|
22
|
+
if (collectionConfig.description) {
|
|
23
|
+
collection.info.description = collectionConfig.description;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 2. Add folder descriptions
|
|
28
|
+
if (config.folders) {
|
|
29
|
+
walkCollection(collection.item, (item) => {
|
|
30
|
+
if (isFolder(item)) {
|
|
31
|
+
const folderKey = item.name?.toLowerCase();
|
|
32
|
+
// Try exact match first
|
|
33
|
+
if (config.folders && config.folders[folderKey]) {
|
|
34
|
+
item.description = config.folders[folderKey];
|
|
35
|
+
}
|
|
36
|
+
// Try without special characters
|
|
37
|
+
else {
|
|
38
|
+
const cleanKey = folderKey?.replace(/[{}:]/g, '');
|
|
39
|
+
if (config.folders && cleanKey && config.folders[cleanKey]) {
|
|
40
|
+
item.description = config.folders[cleanKey];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// 3. Add request descriptions
|
|
47
|
+
if (config.requests) {
|
|
48
|
+
walkCollection(collection.item, (item) => {
|
|
49
|
+
if (isRequest(item) && item.request) {
|
|
50
|
+
const requestName = item.name;
|
|
51
|
+
if (config.requests && config.requests[requestName]) {
|
|
52
|
+
item.request.description = config.requests[requestName];
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Generate generic description if not specified
|
|
56
|
+
item.request.description = generateGenericDescription(getRequestMethod(item), requestName);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return collection;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Generate a description based on HTTP method and name
|
|
65
|
+
* @param method - HTTP method
|
|
66
|
+
* @param name - Request name
|
|
67
|
+
* @returns Generated description
|
|
68
|
+
*/
|
|
69
|
+
function generateGenericDescription(method, name) {
|
|
70
|
+
const descriptions = {
|
|
71
|
+
GET: `Retrieve ${name
|
|
72
|
+
.toLowerCase()
|
|
73
|
+
.replace(/^get\s+/, '')
|
|
74
|
+
.replace(/^list\s+/, '')}`,
|
|
75
|
+
POST: `Create new ${name
|
|
76
|
+
.toLowerCase()
|
|
77
|
+
.replace(/^create\s+/, '')
|
|
78
|
+
.replace(/^add\s+/, '')}`,
|
|
79
|
+
PUT: `Update ${name.toLowerCase().replace(/^update\s+/, '')}`,
|
|
80
|
+
PATCH: `Partially update ${name.toLowerCase().replace(/^update\s+/, '')}`,
|
|
81
|
+
DELETE: `Delete ${name
|
|
82
|
+
.toLowerCase()
|
|
83
|
+
.replace(/^delete\s+/, '')
|
|
84
|
+
.replace(/^remove\s+/, '')}`,
|
|
85
|
+
};
|
|
86
|
+
return (descriptions[method] ||
|
|
87
|
+
`Perform ${method} operation on ${name.toLowerCase()}`);
|
|
88
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Examples enricher - Adds request body examples and response examples
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, ExampleConfig } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add examples to requests and responses
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Examples configuration
|
|
9
|
+
* @returns Collection with examples
|
|
10
|
+
*/
|
|
11
|
+
export declare function addExamples(collection: PostmanCollection, config: ExampleConfig | undefined): PostmanCollection;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Examples enricher - Adds request body examples and response examples
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isRequest, getRequestMethod, } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add examples to requests and responses
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Examples configuration
|
|
9
|
+
* @returns Collection with examples
|
|
10
|
+
*/
|
|
11
|
+
export function addExamples(collection, config) {
|
|
12
|
+
if (!config)
|
|
13
|
+
return collection;
|
|
14
|
+
walkCollection(collection.item, (item) => {
|
|
15
|
+
if (!isRequest(item) || !item.request)
|
|
16
|
+
return;
|
|
17
|
+
const requestName = item.name;
|
|
18
|
+
const method = getRequestMethod(item);
|
|
19
|
+
// Add request body examples
|
|
20
|
+
if (item.request?.body?.raw && config.requests?.[requestName]?.body) {
|
|
21
|
+
try {
|
|
22
|
+
const body = JSON.parse(item.request.body.raw);
|
|
23
|
+
const exampleBody = { ...body, ...config.requests[requestName].body };
|
|
24
|
+
item.request.body.raw = JSON.stringify(exampleBody, null, 2);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Not JSON, skip
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Add response examples
|
|
31
|
+
if (config.responses?.[requestName]) {
|
|
32
|
+
const responseExample = config.responses[requestName];
|
|
33
|
+
item.response = [
|
|
34
|
+
{
|
|
35
|
+
name: responseExample.name || 'Success',
|
|
36
|
+
status: responseExample.status || getDefaultStatus(method),
|
|
37
|
+
code: responseExample.code || getDefaultStatusCode(method),
|
|
38
|
+
_postman_previewlanguage: 'json',
|
|
39
|
+
header: [{ key: 'Content-Type', value: 'application/json' }],
|
|
40
|
+
body: JSON.stringify(responseExample.body, null, 2),
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
else if (!item.response || item.response.length === 0) {
|
|
45
|
+
// Add default response example if none exists
|
|
46
|
+
item.response = [getDefaultResponseExample(method)];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return collection;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get default status text for HTTP method
|
|
53
|
+
* @param method - HTTP method
|
|
54
|
+
* @returns Status text
|
|
55
|
+
*/
|
|
56
|
+
function getDefaultStatus(method) {
|
|
57
|
+
const statuses = {
|
|
58
|
+
GET: 'OK',
|
|
59
|
+
POST: 'Created',
|
|
60
|
+
PUT: 'OK',
|
|
61
|
+
PATCH: 'OK',
|
|
62
|
+
DELETE: 'No Content',
|
|
63
|
+
};
|
|
64
|
+
return statuses[method] || 'OK';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get default status code for HTTP method
|
|
68
|
+
* @param method - HTTP method
|
|
69
|
+
* @returns Status code
|
|
70
|
+
*/
|
|
71
|
+
function getDefaultStatusCode(method) {
|
|
72
|
+
const codes = {
|
|
73
|
+
GET: 200,
|
|
74
|
+
POST: 201,
|
|
75
|
+
PUT: 200,
|
|
76
|
+
PATCH: 200,
|
|
77
|
+
DELETE: 204,
|
|
78
|
+
};
|
|
79
|
+
return codes[method] || 200;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get default response example for HTTP method
|
|
83
|
+
* @param method - HTTP method
|
|
84
|
+
* @returns Response example
|
|
85
|
+
*/
|
|
86
|
+
function getDefaultResponseExample(method) {
|
|
87
|
+
if (method === 'DELETE') {
|
|
88
|
+
return {
|
|
89
|
+
name: 'No Content',
|
|
90
|
+
status: 'No Content',
|
|
91
|
+
code: 204,
|
|
92
|
+
header: [],
|
|
93
|
+
body: '',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (method === 'POST') {
|
|
97
|
+
return {
|
|
98
|
+
name: 'Created',
|
|
99
|
+
status: 'Created',
|
|
100
|
+
code: 201,
|
|
101
|
+
_postman_previewlanguage: 'json',
|
|
102
|
+
header: [{ key: 'Content-Type', value: 'application/json' }],
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
id: '123e4567-e89b-12d3-a456-426614174000',
|
|
105
|
+
message: 'Resource created successfully',
|
|
106
|
+
}, null, 2),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
name: 'Success',
|
|
111
|
+
status: 'OK',
|
|
112
|
+
code: 200,
|
|
113
|
+
_postman_previewlanguage: 'json',
|
|
114
|
+
header: [{ key: 'Content-Type', value: 'application/json' }],
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
id: '123e4567-e89b-12d3-a456-426614174000',
|
|
117
|
+
name: 'Example Resource',
|
|
118
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
119
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
120
|
+
}, null, 2),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter enricher - Removes non-essential endpoints from collection
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, FilterConfig } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Filter collection to only include specified endpoints
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Filter configuration with include/exclude endpoints
|
|
9
|
+
* @returns Filtered collection
|
|
10
|
+
*/
|
|
11
|
+
export declare function filterEndpoints(collection: PostmanCollection, config: FilterConfig): PostmanCollection;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter enricher - Removes non-essential endpoints from collection
|
|
3
|
+
*/
|
|
4
|
+
import { isRequest, getRequestMethod, getUrlPath, shouldIncludeEndpoint, } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Filter collection to only include specified endpoints
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Filter configuration with include/exclude endpoints
|
|
9
|
+
* @returns Filtered collection
|
|
10
|
+
*/
|
|
11
|
+
export function filterEndpoints(collection, config) {
|
|
12
|
+
if (!config?.include) {
|
|
13
|
+
return collection; // No filtering configured
|
|
14
|
+
}
|
|
15
|
+
function filterItems(items) {
|
|
16
|
+
if (!items)
|
|
17
|
+
return [];
|
|
18
|
+
return items
|
|
19
|
+
.map((item) => {
|
|
20
|
+
if (isRequest(item)) {
|
|
21
|
+
// This is a request item
|
|
22
|
+
const method = getRequestMethod(item);
|
|
23
|
+
const path = getUrlPath(item.request.url);
|
|
24
|
+
if (shouldIncludeEndpoint(method, path, config.include, config.normalizationRules || {})) {
|
|
25
|
+
return item;
|
|
26
|
+
}
|
|
27
|
+
return null; // Filter out this endpoint
|
|
28
|
+
}
|
|
29
|
+
else if (item.item) {
|
|
30
|
+
// This is a folder
|
|
31
|
+
const filteredSubItems = filterItems(item.item).filter(Boolean);
|
|
32
|
+
if (filteredSubItems.length > 0) {
|
|
33
|
+
return {
|
|
34
|
+
...item,
|
|
35
|
+
item: filteredSubItems,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return null; // Remove empty folders
|
|
39
|
+
}
|
|
40
|
+
return item;
|
|
41
|
+
})
|
|
42
|
+
.filter((item) => item !== null);
|
|
43
|
+
}
|
|
44
|
+
const filtered = {
|
|
45
|
+
...collection,
|
|
46
|
+
item: filterItems(collection.item),
|
|
47
|
+
};
|
|
48
|
+
// Add note about filtering in description (if provided in config)
|
|
49
|
+
if (filtered.info && config.note) {
|
|
50
|
+
filtered.info.description =
|
|
51
|
+
(filtered.info.description || '') + '\n\n' + config.note;
|
|
52
|
+
}
|
|
53
|
+
return filtered;
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests enricher - Adds basic test scripts to requests
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, TestConfig } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add test scripts to requests
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Tests configuration
|
|
9
|
+
* @returns Collection with test scripts
|
|
10
|
+
*/
|
|
11
|
+
export declare function addTests(collection: PostmanCollection, config: TestConfig | undefined): PostmanCollection;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests enricher - Adds basic test scripts to requests
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isRequest, getRequestMethod, } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Add test scripts to requests
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Tests configuration
|
|
9
|
+
* @returns Collection with test scripts
|
|
10
|
+
*/
|
|
11
|
+
export function addTests(collection, config) {
|
|
12
|
+
if (!config?.auto)
|
|
13
|
+
return collection;
|
|
14
|
+
walkCollection(collection.item, (item) => {
|
|
15
|
+
if (!isRequest(item))
|
|
16
|
+
return;
|
|
17
|
+
const method = getRequestMethod(item);
|
|
18
|
+
const testScript = getTestTemplate(method);
|
|
19
|
+
if (testScript) {
|
|
20
|
+
item.event = item.event || [];
|
|
21
|
+
item.event.push({
|
|
22
|
+
listen: 'test',
|
|
23
|
+
script: {
|
|
24
|
+
type: 'text/javascript',
|
|
25
|
+
exec: testScript,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return collection;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get test template for HTTP method
|
|
34
|
+
* @param method - HTTP method
|
|
35
|
+
* @returns Test script lines or null
|
|
36
|
+
*/
|
|
37
|
+
function getTestTemplate(method) {
|
|
38
|
+
const templates = {
|
|
39
|
+
GET: [
|
|
40
|
+
'pm.test("Status code is 200", () => {',
|
|
41
|
+
' pm.response.to.have.status(200);',
|
|
42
|
+
'});',
|
|
43
|
+
'',
|
|
44
|
+
'pm.test("Response time is less than 1000ms", () => {',
|
|
45
|
+
' pm.expect(pm.response.responseTime).to.be.below(1000);',
|
|
46
|
+
'});',
|
|
47
|
+
],
|
|
48
|
+
POST: [
|
|
49
|
+
'pm.test("Successful creation", () => {',
|
|
50
|
+
' pm.expect(pm.response.code).to.be.oneOf([200, 201]);',
|
|
51
|
+
'});',
|
|
52
|
+
'',
|
|
53
|
+
'pm.test("Response has data", () => {',
|
|
54
|
+
' const jsonData = pm.response.json();',
|
|
55
|
+
' pm.expect(jsonData).to.be.an("object");',
|
|
56
|
+
'});',
|
|
57
|
+
],
|
|
58
|
+
PUT: [
|
|
59
|
+
'pm.test("Successful update", () => {',
|
|
60
|
+
' pm.expect(pm.response.code).to.be.oneOf([200, 204]);',
|
|
61
|
+
'});',
|
|
62
|
+
],
|
|
63
|
+
PATCH: [
|
|
64
|
+
'pm.test("Successful partial update", () => {',
|
|
65
|
+
' pm.expect(pm.response.code).to.be.oneOf([200, 204]);',
|
|
66
|
+
'});',
|
|
67
|
+
'',
|
|
68
|
+
'pm.test("Response has updated data", () => {',
|
|
69
|
+
' if (pm.response.code === 200) {',
|
|
70
|
+
' const jsonData = pm.response.json();',
|
|
71
|
+
' pm.expect(jsonData).to.be.an("object");',
|
|
72
|
+
' }',
|
|
73
|
+
'});',
|
|
74
|
+
],
|
|
75
|
+
DELETE: [
|
|
76
|
+
'pm.test("Successful deletion", () => {',
|
|
77
|
+
' pm.response.to.have.status(204);',
|
|
78
|
+
'});',
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
return templates[method] || null;
|
|
82
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variables enricher - Sets up path variables and environment variables
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, VariableConfig } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Setup variables in the collection
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Variables configuration
|
|
9
|
+
* @returns Collection with variables configured
|
|
10
|
+
*/
|
|
11
|
+
export declare function setupVariables(collection: PostmanCollection, config: VariableConfig | undefined): PostmanCollection;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variables enricher - Sets up path variables and environment variables
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isRequest } from '@postman-enricher/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Setup variables in the collection
|
|
7
|
+
* @param collection - Postman collection
|
|
8
|
+
* @param config - Variables configuration
|
|
9
|
+
* @returns Collection with variables configured
|
|
10
|
+
*/
|
|
11
|
+
export function setupVariables(collection, config) {
|
|
12
|
+
if (!config)
|
|
13
|
+
return collection;
|
|
14
|
+
// 1. Clear collection variables (use environment variables instead)
|
|
15
|
+
collection.variable = [];
|
|
16
|
+
// 2. Setup path variables
|
|
17
|
+
if (config.path) {
|
|
18
|
+
walkCollection(collection.item, (item) => {
|
|
19
|
+
if (!isRequest(item) || !item.request?.url)
|
|
20
|
+
return;
|
|
21
|
+
const url = item.request.url;
|
|
22
|
+
if (!url.path || !Array.isArray(url.path))
|
|
23
|
+
return;
|
|
24
|
+
// Initialize variable array if needed
|
|
25
|
+
if (!url.variable) {
|
|
26
|
+
url.variable = [];
|
|
27
|
+
}
|
|
28
|
+
// Check which path variables are needed
|
|
29
|
+
Object.entries(config.path).forEach(([varName, varValue]) => {
|
|
30
|
+
if (url.path &&
|
|
31
|
+
Array.isArray(url.path) &&
|
|
32
|
+
url.path.includes(`:${varName}`)) {
|
|
33
|
+
// Find existing variable or add new one
|
|
34
|
+
const existingIndex = url.variable.findIndex((v) => v.key === varName);
|
|
35
|
+
const variable = {
|
|
36
|
+
key: varName,
|
|
37
|
+
value: varValue,
|
|
38
|
+
description: config.descriptions?.[varName] || '',
|
|
39
|
+
};
|
|
40
|
+
if (existingIndex >= 0) {
|
|
41
|
+
url.variable[existingIndex] = variable;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
url.variable.push(variable);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// 3. Update host URLs to use environment variables
|
|
51
|
+
const baseUrlVar = config.baseUrlVar || 'baseUrl';
|
|
52
|
+
walkCollection(collection.item, (item) => {
|
|
53
|
+
if (isRequest(item) && item.request?.url) {
|
|
54
|
+
item.request.url.host = [`{{${baseUrlVar}}}`];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// 4. Process query parameters
|
|
58
|
+
if (config.query) {
|
|
59
|
+
walkCollection(collection.item, (item) => {
|
|
60
|
+
if (!isRequest(item) || !item.request?.url?.query)
|
|
61
|
+
return;
|
|
62
|
+
Object.entries(config.query).forEach(([key, value]) => {
|
|
63
|
+
const query = item.request.url.query;
|
|
64
|
+
const paramIndex = query.findIndex((q) => q.key === key);
|
|
65
|
+
if (paramIndex >= 0) {
|
|
66
|
+
const existingParam = query[paramIndex];
|
|
67
|
+
query[paramIndex] = {
|
|
68
|
+
key,
|
|
69
|
+
value,
|
|
70
|
+
disabled: false,
|
|
71
|
+
...(existingParam.description && {
|
|
72
|
+
description: existingParam.description,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// 5. Add collection-level pre-request script for environment validation
|
|
80
|
+
const envVars = config.environment ? Object.keys(config.environment) : [];
|
|
81
|
+
if (envVars.length > 0) {
|
|
82
|
+
const script = [
|
|
83
|
+
'// Validate required environment variables',
|
|
84
|
+
...envVars.map((varName) => `if (!pm.environment.get("${varName}")) {
|
|
85
|
+
console.warn("Please set your ${varName} in the environment");
|
|
86
|
+
}`),
|
|
87
|
+
'',
|
|
88
|
+
'// Save timestamp for chaining requests',
|
|
89
|
+
'pm.globals.set("timestamp", new Date().toISOString());',
|
|
90
|
+
];
|
|
91
|
+
collection.event = collection.event || [];
|
|
92
|
+
collection.event.push({
|
|
93
|
+
listen: 'prerequest',
|
|
94
|
+
script: {
|
|
95
|
+
type: 'text/javascript',
|
|
96
|
+
exec: script,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return collection;
|
|
101
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI to Postman Complete - Core
|
|
3
|
+
* Main API for enriching Postman collections with descriptions, examples, variables, and tests
|
|
4
|
+
*/
|
|
5
|
+
import type { PostmanCollection, EnrichmentConfig } from '@postman-enricher/shared';
|
|
6
|
+
import { filterEndpoints } from './enrichers/filter.js';
|
|
7
|
+
import { addDescriptions } from './enrichers/descriptions.js';
|
|
8
|
+
import { addExamples } from './enrichers/examples.js';
|
|
9
|
+
import { setupVariables } from './enrichers/variables.js';
|
|
10
|
+
import { addTests } from './enrichers/tests.js';
|
|
11
|
+
/**
|
|
12
|
+
* Enrich a Postman collection with additional metadata and functionality
|
|
13
|
+
* @param collection - Postman collection to enrich
|
|
14
|
+
* @param config - Enrichment configuration (object or path to YAML file)
|
|
15
|
+
* @returns Enriched Postman collection
|
|
16
|
+
*/
|
|
17
|
+
export declare function enrichCollection(collection: PostmanCollection, config?: EnrichmentConfig | string): PostmanCollection;
|
|
18
|
+
/**
|
|
19
|
+
* Load enrichment configuration from a YAML file
|
|
20
|
+
* @param filePath - Path to YAML configuration file
|
|
21
|
+
* @returns Parsed enrichment configuration
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadConfigFromYaml(filePath: string): EnrichmentConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Export individual enrichers for advanced usage
|
|
26
|
+
*/
|
|
27
|
+
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI to Postman Complete - Core
|
|
3
|
+
* Main API for enriching Postman collections with descriptions, examples, variables, and tests
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import { parse as parseYaml } from 'yaml';
|
|
7
|
+
import { filterEndpoints } from './enrichers/filter.js';
|
|
8
|
+
import { addDescriptions } from './enrichers/descriptions.js';
|
|
9
|
+
import { addExamples } from './enrichers/examples.js';
|
|
10
|
+
import { setupVariables } from './enrichers/variables.js';
|
|
11
|
+
import { addTests } from './enrichers/tests.js';
|
|
12
|
+
/**
|
|
13
|
+
* Enrich a Postman collection with additional metadata and functionality
|
|
14
|
+
* @param collection - Postman collection to enrich
|
|
15
|
+
* @param config - Enrichment configuration (object or path to YAML file)
|
|
16
|
+
* @returns Enriched Postman collection
|
|
17
|
+
*/
|
|
18
|
+
export function enrichCollection(collection, config = {}) {
|
|
19
|
+
// Load config from YAML file if string path provided
|
|
20
|
+
const enrichmentConfig = typeof config === 'string' ? loadConfigFromYaml(config) : config;
|
|
21
|
+
let enriched = { ...collection };
|
|
22
|
+
// Apply enrichments in order
|
|
23
|
+
// 1. Filter endpoints first (reduce what we're working with)
|
|
24
|
+
if (enrichmentConfig.filter) {
|
|
25
|
+
enriched = filterEndpoints(enriched, enrichmentConfig.filter);
|
|
26
|
+
}
|
|
27
|
+
// 2. Add descriptions (collection, folders, requests)
|
|
28
|
+
if (enrichmentConfig.descriptions) {
|
|
29
|
+
enriched = addDescriptions(enriched, enrichmentConfig.descriptions);
|
|
30
|
+
}
|
|
31
|
+
// 3. Add examples (request bodies and responses)
|
|
32
|
+
if (enrichmentConfig.examples) {
|
|
33
|
+
enriched = addExamples(enriched, enrichmentConfig.examples);
|
|
34
|
+
}
|
|
35
|
+
// 4. Setup variables (path variables, environment variables)
|
|
36
|
+
if (enrichmentConfig.variables) {
|
|
37
|
+
enriched = setupVariables(enriched, enrichmentConfig.variables);
|
|
38
|
+
}
|
|
39
|
+
// 5. Add test scripts
|
|
40
|
+
if (enrichmentConfig.tests) {
|
|
41
|
+
enriched = addTests(enriched, enrichmentConfig.tests);
|
|
42
|
+
}
|
|
43
|
+
return enriched;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load enrichment configuration from a YAML file
|
|
47
|
+
* @param filePath - Path to YAML configuration file
|
|
48
|
+
* @returns Parsed enrichment configuration
|
|
49
|
+
*/
|
|
50
|
+
export function loadConfigFromYaml(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
const yaml = readFileSync(filePath, 'utf8');
|
|
53
|
+
return parseYaml(yaml);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
throw new Error(`Failed to load config from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Export individual enrichers for advanced usage
|
|
61
|
+
*/
|
|
62
|
+
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, };
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@postman-enricher/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Core enrichment logic for Postman Enricher",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"yaml": "^2.8.1",
|
|
19
|
+
"@postman-enricher/shared": "1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@anolilab/semantic-release-pnpm": "^3.0.0",
|
|
23
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
24
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
25
|
+
"@semantic-release/git": "^10.0.1",
|
|
26
|
+
"@semantic-release/github": "^12.0.2",
|
|
27
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
28
|
+
"@types/node": "^24.10.1",
|
|
29
|
+
"semantic-release": "^25.0.2",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.0.0"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/caiopizzol/openapi-to-postman-complete.git",
|
|
38
|
+
"directory": "packages/core"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/caiopizzol/openapi-to-postman-complete/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/caiopizzol/openapi-to-postman-complete#readme",
|
|
44
|
+
"author": "Caio Pizzol",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsc",
|
|
51
|
+
"typecheck": "tsc --noEmit"
|
|
52
|
+
}
|
|
53
|
+
}
|