@postman-enricher/core 1.0.0 → 1.1.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/dist/enrichers/organize.d.ts +5 -0
- package/dist/enrichers/organize.js +53 -0
- package/dist/enrichers/pathVariables.d.ts +5 -0
- package/dist/enrichers/pathVariables.js +29 -0
- package/dist/enrichers/preserveIds.d.ts +5 -0
- package/dist/enrichers/preserveIds.js +47 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +22 -7
- package/package.json +2 -2
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organize enricher - Reorganizes collection by REST resource hierarchy
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, OrganizeConfig } from '@postman-enricher/shared';
|
|
5
|
+
export declare function organizeByResources(collection: PostmanCollection, config: OrganizeConfig): PostmanCollection;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organize enricher - Reorganizes collection by REST resource hierarchy
|
|
3
|
+
*/
|
|
4
|
+
import { getUrlPath, isRequest } from '@postman-enricher/shared';
|
|
5
|
+
export function organizeByResources(collection, config) {
|
|
6
|
+
if (!config?.enabled || config.strategy !== 'resources') {
|
|
7
|
+
return collection;
|
|
8
|
+
}
|
|
9
|
+
const excludePathParams = config.excludePathParams ?? true;
|
|
10
|
+
const maxDepth = config.nestingLevel || Infinity;
|
|
11
|
+
const organized = buildResourceHierarchy(collection.item, excludePathParams, maxDepth);
|
|
12
|
+
return {
|
|
13
|
+
...collection,
|
|
14
|
+
item: organized.length > 0 ? organized : collection.item,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function buildResourceHierarchy(items, excludePathParams, maxDepth) {
|
|
18
|
+
const folderMap = new Map();
|
|
19
|
+
items.forEach((item) => {
|
|
20
|
+
if (!isRequest(item) || !item.request?.url)
|
|
21
|
+
return;
|
|
22
|
+
const path = getUrlPath(item.request.url);
|
|
23
|
+
const segments = extractSegments(path, excludePathParams).slice(0, maxDepth);
|
|
24
|
+
if (segments.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
// Create/get folders for the path hierarchy
|
|
27
|
+
let folderPath = '';
|
|
28
|
+
let parentFolder = null;
|
|
29
|
+
segments.forEach((segment, index) => {
|
|
30
|
+
folderPath = folderPath ? `${folderPath}/${segment}` : segment;
|
|
31
|
+
if (!folderMap.has(folderPath)) {
|
|
32
|
+
const folder = { name: segment, item: [] };
|
|
33
|
+
folderMap.set(folderPath, folder);
|
|
34
|
+
if (parentFolder) {
|
|
35
|
+
parentFolder.item.push(folder);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
parentFolder = folderMap.get(folderPath);
|
|
39
|
+
// Add item to deepest folder
|
|
40
|
+
if (index === segments.length - 1) {
|
|
41
|
+
parentFolder.item.push(item);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
// Return only top-level folders
|
|
46
|
+
return Array.from(folderMap.values()).filter((folder) => !folder.name.includes('/'));
|
|
47
|
+
}
|
|
48
|
+
function extractSegments(path, excludePathParams) {
|
|
49
|
+
return path
|
|
50
|
+
.split('/')
|
|
51
|
+
.filter((seg) => seg && !seg.endsWith(':'))
|
|
52
|
+
.filter((seg) => !excludePathParams || (!seg.startsWith(':') && !seg.startsWith('{')));
|
|
53
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Variables enricher - Ensures path parameters reference collection/environment variables
|
|
3
|
+
*/
|
|
4
|
+
import type { PostmanCollection, PathVariablesConfig } from '@postman-enricher/shared';
|
|
5
|
+
export declare function setupPathVariables(collection: PostmanCollection, config: PathVariablesConfig): PostmanCollection;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Variables enricher - Ensures path parameters reference collection/environment variables
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isRequest } from '@postman-enricher/shared';
|
|
5
|
+
export function setupPathVariables(collection, config) {
|
|
6
|
+
if (!config?.enabled) {
|
|
7
|
+
return collection;
|
|
8
|
+
}
|
|
9
|
+
walkCollection(collection.item, (item) => {
|
|
10
|
+
if (!isRequest(item) || !item.request?.url)
|
|
11
|
+
return;
|
|
12
|
+
const url = item.request.url;
|
|
13
|
+
if (typeof url === 'string' || !url.variable)
|
|
14
|
+
return;
|
|
15
|
+
// Update path variables with mappings
|
|
16
|
+
url.variable = url.variable.map((variable) => {
|
|
17
|
+
const mapping = config.mapping?.[variable.key];
|
|
18
|
+
if (mapping) {
|
|
19
|
+
return {
|
|
20
|
+
...variable,
|
|
21
|
+
value: mapping.reference,
|
|
22
|
+
description: mapping.description || variable.description,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return variable;
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return collection;
|
|
29
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID Preservation - Maintains IDs across collection regenerations
|
|
3
|
+
*/
|
|
4
|
+
import { walkCollection, isRequest, getRequestMethod, } from '@postman-enricher/shared';
|
|
5
|
+
import { readFileSync, existsSync } from 'fs';
|
|
6
|
+
export function preserveIds(collection, existingPath) {
|
|
7
|
+
if (!existingPath || !existsSync(existingPath)) {
|
|
8
|
+
return collection;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const existing = JSON.parse(readFileSync(existingPath, 'utf8'));
|
|
12
|
+
const idMap = buildIdMap(existing);
|
|
13
|
+
// Restore collection ID
|
|
14
|
+
if (existing.info?._postman_id) {
|
|
15
|
+
collection.info._postman_id = existing.info._postman_id;
|
|
16
|
+
}
|
|
17
|
+
// Restore item IDs
|
|
18
|
+
walkCollection(collection.item, (item) => {
|
|
19
|
+
const key = getItemKey(item);
|
|
20
|
+
const existingId = idMap.get(key);
|
|
21
|
+
if (existingId) {
|
|
22
|
+
item.id = existingId;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return collection;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return collection; // Silently fail if existing collection is invalid
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function buildIdMap(collection) {
|
|
32
|
+
const map = new Map();
|
|
33
|
+
walkCollection(collection.item, (item) => {
|
|
34
|
+
if (item.id) {
|
|
35
|
+
const key = getItemKey(item);
|
|
36
|
+
map.set(key, item.id);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return map;
|
|
40
|
+
}
|
|
41
|
+
function getItemKey(item) {
|
|
42
|
+
if (isRequest(item)) {
|
|
43
|
+
const method = getRequestMethod(item);
|
|
44
|
+
return `${method}_${item.name}`;
|
|
45
|
+
}
|
|
46
|
+
return `folder_${item.name}`;
|
|
47
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,13 +8,17 @@ import { addDescriptions } from './enrichers/descriptions.js';
|
|
|
8
8
|
import { addExamples } from './enrichers/examples.js';
|
|
9
9
|
import { setupVariables } from './enrichers/variables.js';
|
|
10
10
|
import { addTests } from './enrichers/tests.js';
|
|
11
|
+
import { organizeByResources } from './enrichers/organize.js';
|
|
12
|
+
import { setupPathVariables } from './enrichers/pathVariables.js';
|
|
13
|
+
import { preserveIds } from './enrichers/preserveIds.js';
|
|
11
14
|
/**
|
|
12
15
|
* Enrich a Postman collection with additional metadata and functionality
|
|
13
16
|
* @param collection - Postman collection to enrich
|
|
14
17
|
* @param config - Enrichment configuration (object or path to YAML file)
|
|
18
|
+
* @param existingCollectionPath - Optional path to existing collection for ID preservation
|
|
15
19
|
* @returns Enriched Postman collection
|
|
16
20
|
*/
|
|
17
|
-
export declare function enrichCollection(collection: PostmanCollection, config?: EnrichmentConfig | string): PostmanCollection;
|
|
21
|
+
export declare function enrichCollection(collection: PostmanCollection, config?: EnrichmentConfig | string, existingCollectionPath?: string): PostmanCollection;
|
|
18
22
|
/**
|
|
19
23
|
* Load enrichment configuration from a YAML file
|
|
20
24
|
* @param filePath - Path to YAML configuration file
|
|
@@ -24,4 +28,4 @@ export declare function loadConfigFromYaml(filePath: string): EnrichmentConfig;
|
|
|
24
28
|
/**
|
|
25
29
|
* Export individual enrichers for advanced usage
|
|
26
30
|
*/
|
|
27
|
-
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, };
|
|
31
|
+
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, organizeByResources, setupPathVariables, preserveIds, };
|
package/dist/index.js
CHANGED
|
@@ -9,34 +9,49 @@ import { addDescriptions } from './enrichers/descriptions.js';
|
|
|
9
9
|
import { addExamples } from './enrichers/examples.js';
|
|
10
10
|
import { setupVariables } from './enrichers/variables.js';
|
|
11
11
|
import { addTests } from './enrichers/tests.js';
|
|
12
|
+
import { organizeByResources } from './enrichers/organize.js';
|
|
13
|
+
import { setupPathVariables } from './enrichers/pathVariables.js';
|
|
14
|
+
import { preserveIds } from './enrichers/preserveIds.js';
|
|
12
15
|
/**
|
|
13
16
|
* Enrich a Postman collection with additional metadata and functionality
|
|
14
17
|
* @param collection - Postman collection to enrich
|
|
15
18
|
* @param config - Enrichment configuration (object or path to YAML file)
|
|
19
|
+
* @param existingCollectionPath - Optional path to existing collection for ID preservation
|
|
16
20
|
* @returns Enriched Postman collection
|
|
17
21
|
*/
|
|
18
|
-
export function enrichCollection(collection, config = {}) {
|
|
22
|
+
export function enrichCollection(collection, config = {}, existingCollectionPath) {
|
|
19
23
|
// Load config from YAML file if string path provided
|
|
20
24
|
const enrichmentConfig = typeof config === 'string' ? loadConfigFromYaml(config) : config;
|
|
21
25
|
let enriched = { ...collection };
|
|
22
|
-
//
|
|
26
|
+
// 0. Preserve IDs from existing collection (if provided)
|
|
27
|
+
if (existingCollectionPath) {
|
|
28
|
+
enriched = preserveIds(enriched, existingCollectionPath);
|
|
29
|
+
}
|
|
23
30
|
// 1. Filter endpoints first (reduce what we're working with)
|
|
24
31
|
if (enrichmentConfig.filter) {
|
|
25
32
|
enriched = filterEndpoints(enriched, enrichmentConfig.filter);
|
|
26
33
|
}
|
|
27
|
-
// 2.
|
|
34
|
+
// 2. Organize by resource hierarchy
|
|
35
|
+
if (enrichmentConfig.organize) {
|
|
36
|
+
enriched = organizeByResources(enriched, enrichmentConfig.organize);
|
|
37
|
+
}
|
|
38
|
+
// 3. Add descriptions (collection, folders, requests)
|
|
28
39
|
if (enrichmentConfig.descriptions) {
|
|
29
40
|
enriched = addDescriptions(enriched, enrichmentConfig.descriptions);
|
|
30
41
|
}
|
|
31
|
-
//
|
|
42
|
+
// 4. Add examples (request bodies and responses)
|
|
32
43
|
if (enrichmentConfig.examples) {
|
|
33
44
|
enriched = addExamples(enriched, enrichmentConfig.examples);
|
|
34
45
|
}
|
|
35
|
-
//
|
|
46
|
+
// 5. Setup variables (path variables, environment variables)
|
|
36
47
|
if (enrichmentConfig.variables) {
|
|
37
48
|
enriched = setupVariables(enriched, enrichmentConfig.variables);
|
|
38
49
|
}
|
|
39
|
-
//
|
|
50
|
+
// 6. Setup path variables
|
|
51
|
+
if (enrichmentConfig.pathVariables) {
|
|
52
|
+
enriched = setupPathVariables(enriched, enrichmentConfig.pathVariables);
|
|
53
|
+
}
|
|
54
|
+
// 7. Add test scripts
|
|
40
55
|
if (enrichmentConfig.tests) {
|
|
41
56
|
enriched = addTests(enriched, enrichmentConfig.tests);
|
|
42
57
|
}
|
|
@@ -59,4 +74,4 @@ export function loadConfigFromYaml(filePath) {
|
|
|
59
74
|
/**
|
|
60
75
|
* Export individual enrichers for advanced usage
|
|
61
76
|
*/
|
|
62
|
-
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, };
|
|
77
|
+
export { filterEndpoints, addDescriptions, addExamples, setupVariables, addTests, organizeByResources, setupPathVariables, preserveIds, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postman-enricher/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Core enrichment logic for Postman Enricher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"yaml": "^2.8.1",
|
|
19
|
-
"@postman-enricher/shared": "1.
|
|
19
|
+
"@postman-enricher/shared": "1.1.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@anolilab/semantic-release-pnpm": "^3.0.0",
|