@scalar/postman-to-openapi 0.5.2 → 0.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/convert.d.ts +29 -1
  3. package/dist/convert.d.ts.map +1 -1
  4. package/dist/convert.js +375 -215
  5. package/dist/helpers/auth.js +116 -92
  6. package/dist/helpers/contact.js +24 -20
  7. package/dist/helpers/external-docs.js +33 -25
  8. package/dist/helpers/form-data.js +42 -36
  9. package/dist/helpers/generate-unique-value.d.ts +23 -0
  10. package/dist/helpers/generate-unique-value.d.ts.map +1 -0
  11. package/dist/helpers/generate-unique-value.js +29 -0
  12. package/dist/helpers/get-operation-examples.d.ts +40 -0
  13. package/dist/helpers/get-operation-examples.d.ts.map +1 -0
  14. package/dist/helpers/get-operation-examples.js +76 -0
  15. package/dist/helpers/license.js +21 -17
  16. package/dist/helpers/logo.js +22 -21
  17. package/dist/helpers/markdown.js +33 -30
  18. package/dist/helpers/merge-operation.d.ts +55 -0
  19. package/dist/helpers/merge-operation.d.ts.map +1 -0
  20. package/dist/helpers/merge-operation.js +125 -0
  21. package/dist/helpers/merge-path-item.d.ts +5 -0
  22. package/dist/helpers/merge-path-item.d.ts.map +1 -0
  23. package/dist/helpers/merge-path-item.js +37 -0
  24. package/dist/helpers/parameters.d.ts +2 -2
  25. package/dist/helpers/parameters.d.ts.map +1 -1
  26. package/dist/helpers/parameters.js +124 -96
  27. package/dist/helpers/path-items.d.ts +1 -1
  28. package/dist/helpers/path-items.d.ts.map +1 -1
  29. package/dist/helpers/path-items.js +245 -202
  30. package/dist/helpers/post-response-scripts.js +12 -12
  31. package/dist/helpers/pre-request-scripts.js +12 -12
  32. package/dist/helpers/prune-document.js +42 -35
  33. package/dist/helpers/rename-operation-example.d.ts +40 -0
  34. package/dist/helpers/rename-operation-example.d.ts.map +1 -0
  35. package/dist/helpers/rename-operation-example.js +61 -0
  36. package/dist/helpers/request-body.d.ts +1 -1
  37. package/dist/helpers/request-body.d.ts.map +1 -1
  38. package/dist/helpers/request-body.js +118 -94
  39. package/dist/helpers/responses.js +62 -57
  40. package/dist/helpers/schemas.js +43 -37
  41. package/dist/helpers/servers.js +83 -57
  42. package/dist/helpers/status-codes.js +40 -30
  43. package/dist/helpers/urls.js +74 -51
  44. package/dist/index.d.ts +2 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +2 -5
  47. package/dist/types.js +1 -1
  48. package/package.json +7 -11
  49. package/dist/convert.js.map +0 -7
  50. package/dist/helpers/auth.js.map +0 -7
  51. package/dist/helpers/contact.js.map +0 -7
  52. package/dist/helpers/external-docs.js.map +0 -7
  53. package/dist/helpers/form-data.js.map +0 -7
  54. package/dist/helpers/license.js.map +0 -7
  55. package/dist/helpers/logo.js.map +0 -7
  56. package/dist/helpers/markdown.js.map +0 -7
  57. package/dist/helpers/parameters.js.map +0 -7
  58. package/dist/helpers/path-items.js.map +0 -7
  59. package/dist/helpers/post-response-scripts.js.map +0 -7
  60. package/dist/helpers/pre-request-scripts.js.map +0 -7
  61. package/dist/helpers/prune-document.js.map +0 -7
  62. package/dist/helpers/request-body.js.map +0 -7
  63. package/dist/helpers/responses.js.map +0 -7
  64. package/dist/helpers/schemas.js.map +0 -7
  65. package/dist/helpers/servers.js.map +0 -7
  66. package/dist/helpers/status-codes.js.map +0 -7
  67. package/dist/helpers/urls.js.map +0 -7
  68. package/dist/index.js.map +0 -7
  69. package/dist/types.js.map +0 -7
@@ -1,23 +1,24 @@
1
- function processLogo(postmanCollection) {
2
- const logoVariables = postmanCollection.variable?.filter((v) => v.key?.startsWith("x-logo.")) || [];
3
- if (logoVariables.length === 0) {
4
- return null;
5
- }
6
- const logo = {};
7
- logoVariables.forEach((v) => {
8
- if (v.key) {
9
- const key = v.key.replace("x-logo.", "").replace("Var", "");
10
- logo[key] = v.value;
1
+ /**
2
+ * Processes logo information from a Postman Collection.
3
+ * This function extracts logo-related variables from the collection
4
+ * and constructs an object with logo properties.
5
+ */
6
+ export function processLogo(postmanCollection) {
7
+ const logoVariables = postmanCollection.variable?.filter((v) => v.key?.startsWith('x-logo.')) || [];
8
+ if (logoVariables.length === 0) {
9
+ return null;
11
10
  }
12
- });
13
- return {
14
- url: logo.url,
15
- backgroundColor: logo.backgroundColor,
16
- altText: logo.altText,
17
- href: logo.href
18
- };
11
+ const logo = {};
12
+ logoVariables.forEach((v) => {
13
+ if (v.key) {
14
+ const key = v.key.replace('x-logo.', '').replace('Var', '');
15
+ logo[key] = v.value;
16
+ }
17
+ });
18
+ return {
19
+ url: logo.url,
20
+ backgroundColor: logo.backgroundColor,
21
+ altText: logo.altText,
22
+ href: logo.href,
23
+ };
19
24
  }
20
- export {
21
- processLogo
22
- };
23
- //# sourceMappingURL=logo.js.map
@@ -1,32 +1,35 @@
1
- const supHeaders = ["object", "name", "description", "example", "type", "required"];
2
- function parseMdTable(md) {
3
- const lines = md.split("\n").filter((line) => line.trim() !== "");
4
- if (typeof lines[0] === "undefined" || lines.length < 3) {
5
- return {};
6
- }
7
- const header = lines[0].split("|").map((cell) => cell.trim()).filter(Boolean);
8
- if (!header.includes("object") || !header.includes("name")) {
9
- return {};
10
- }
11
- const headers = header.map((h) => supHeaders.includes(h) ? h : false);
12
- const rows = lines.slice(2).map(
13
- (line) => line.split("|").map((cell) => cell.trim()).filter(Boolean)
14
- );
15
- const tableObj = rows.reduce((accTable, cell) => {
16
- const cellObj = cell.reduce((accCell, field, index) => {
17
- if (headers[index] && typeof headers[index] === "string") {
18
- accCell[headers[index]] = field;
19
- }
20
- return accCell;
21
- }, {});
22
- if (cellObj.name) {
23
- accTable[cellObj.name] = cellObj;
1
+ const supHeaders = ['object', 'name', 'description', 'example', 'type', 'required'];
2
+ /**
3
+ * Parses a Markdown table and returns an object representation.
4
+ */
5
+ export function parseMdTable(md) {
6
+ const lines = md.split('\n').filter((line) => line.trim() !== '');
7
+ if (typeof lines[0] === 'undefined' || lines.length < 3) {
8
+ return {};
9
+ }
10
+ const header = lines[0]
11
+ .split('|')
12
+ .map((cell) => cell.trim())
13
+ .filter(Boolean);
14
+ if (!header.includes('object') || !header.includes('name')) {
15
+ return {};
24
16
  }
25
- return accTable;
26
- }, {});
27
- return tableObj;
17
+ const headers = header.map((h) => (supHeaders.includes(h) ? h : false));
18
+ const rows = lines.slice(2).map((line) => line
19
+ .split('|')
20
+ .map((cell) => cell.trim())
21
+ .filter(Boolean));
22
+ const tableObj = rows.reduce((accTable, cell) => {
23
+ const cellObj = cell.reduce((accCell, field, index) => {
24
+ if (headers[index] && typeof headers[index] === 'string') {
25
+ accCell[headers[index]] = field;
26
+ }
27
+ return accCell;
28
+ }, {});
29
+ if (cellObj.name) {
30
+ accTable[cellObj.name] = cellObj;
31
+ }
32
+ return accTable;
33
+ }, {});
34
+ return tableObj;
28
35
  }
29
- export {
30
- parseMdTable
31
- };
32
- //# sourceMappingURL=markdown.js.map
@@ -0,0 +1,55 @@
1
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
+ /**
3
+ * Merges two OpenAPI OperationObject instances.
4
+ * Assumes that all example names (keys in the 'examples' objects) are unique across both operations.
5
+ * This assumption allows us to shallowly merge example maps without risk of overwriting.
6
+ *
7
+ * @example
8
+ * const op1: OpenAPIV3_1.OperationObject = {
9
+ * tags: ['user'],
10
+ * parameters: [
11
+ * {
12
+ * name: 'id',
13
+ * in: 'path',
14
+ * required: true,
15
+ * schema: { type: 'string' },
16
+ * examples: { A: { value: 1 } }
17
+ * }
18
+ * ],
19
+ * requestBody: {
20
+ * content: {
21
+ * 'application/json': {
22
+ * examples: { example1: { value: { foo: 'bar' } } }
23
+ * }
24
+ * }
25
+ * }
26
+ * }
27
+ *
28
+ * const op2: OpenAPIV3_1.OperationObject = {
29
+ * tags: ['admin'],
30
+ * parameters: [
31
+ * {
32
+ * name: 'id',
33
+ * in: 'path',
34
+ * required: true,
35
+ * schema: { type: 'string' },
36
+ * examples: { B: { value: 2 } }
37
+ * }
38
+ * ],
39
+ * requestBody: {
40
+ * content: {
41
+ * 'application/json': {
42
+ * examples: { example2: { value: { hello: 'world' } } }
43
+ * }
44
+ * }
45
+ * }
46
+ * }
47
+ *
48
+ * const merged = mergeOperations(op1, op2)
49
+ * // merged.tags -> ['user', 'admin']
50
+ * // merged.parameters[0].examples -> { B: { value: 2 }, A: { value: 1 } }
51
+ * // merged.requestBody.content['application/json'].examples ->
52
+ * // { example2: {...}, example1: {...} }
53
+ */
54
+ export declare const mergeOperations: (operation1: OpenAPIV3_1.OperationObject, operation2: OpenAPIV3_1.OperationObject) => OpenAPIV3_1.OperationObject;
55
+ //# sourceMappingURL=merge-operation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-operation.d.ts","sourceRoot":"","sources":["../../src/helpers/merge-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,eAAO,MAAM,eAAe,GAC1B,YAAY,WAAW,CAAC,eAAe,EACvC,YAAY,WAAW,CAAC,eAAe,KACtC,WAAW,CAAC,eAiFd,CAAA"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Merges two OpenAPI OperationObject instances.
3
+ * Assumes that all example names (keys in the 'examples' objects) are unique across both operations.
4
+ * This assumption allows us to shallowly merge example maps without risk of overwriting.
5
+ *
6
+ * @example
7
+ * const op1: OpenAPIV3_1.OperationObject = {
8
+ * tags: ['user'],
9
+ * parameters: [
10
+ * {
11
+ * name: 'id',
12
+ * in: 'path',
13
+ * required: true,
14
+ * schema: { type: 'string' },
15
+ * examples: { A: { value: 1 } }
16
+ * }
17
+ * ],
18
+ * requestBody: {
19
+ * content: {
20
+ * 'application/json': {
21
+ * examples: { example1: { value: { foo: 'bar' } } }
22
+ * }
23
+ * }
24
+ * }
25
+ * }
26
+ *
27
+ * const op2: OpenAPIV3_1.OperationObject = {
28
+ * tags: ['admin'],
29
+ * parameters: [
30
+ * {
31
+ * name: 'id',
32
+ * in: 'path',
33
+ * required: true,
34
+ * schema: { type: 'string' },
35
+ * examples: { B: { value: 2 } }
36
+ * }
37
+ * ],
38
+ * requestBody: {
39
+ * content: {
40
+ * 'application/json': {
41
+ * examples: { example2: { value: { hello: 'world' } } }
42
+ * }
43
+ * }
44
+ * }
45
+ * }
46
+ *
47
+ * const merged = mergeOperations(op1, op2)
48
+ * // merged.tags -> ['user', 'admin']
49
+ * // merged.parameters[0].examples -> { B: { value: 2 }, A: { value: 1 } }
50
+ * // merged.requestBody.content['application/json'].examples ->
51
+ * // { example2: {...}, example1: {...} }
52
+ */
53
+ export const mergeOperations = (operation1, operation2) => {
54
+ const operation = { ...operation2 };
55
+ // Merge tags (union, preserving uniqueness)
56
+ if (operation1.tags || operation.tags) {
57
+ operation.tags = Array.from(new Set([...(operation1.tags ?? []), ...(operation.tags ?? [])]));
58
+ }
59
+ const parameters = new Map();
60
+ const generateParameterId = (param) => `${param.name}/${param.in}`;
61
+ // Seed parameter list from operation2 (the base)
62
+ if (operation.parameters) {
63
+ for (const parameter of operation.parameters) {
64
+ const id = generateParameterId(parameter);
65
+ parameters.set(id, parameter);
66
+ }
67
+ }
68
+ // Merge parameters from operation1 into parameters of operation2.
69
+ // For each parameter, merge their 'examples' objects, assuming example keys are unique.
70
+ if (operation1.parameters) {
71
+ for (const parameter of operation1.parameters) {
72
+ const id = generateParameterId(parameter);
73
+ if (parameters.has(id)) {
74
+ const existingParameter = parameters.get(id);
75
+ if (existingParameter) {
76
+ // Example keys are expected to be unique, so shallow merge is safe.
77
+ existingParameter.examples = {
78
+ ...existingParameter.examples,
79
+ ...parameter.examples,
80
+ };
81
+ }
82
+ }
83
+ else {
84
+ parameters.set(id, parameter);
85
+ }
86
+ }
87
+ }
88
+ if (parameters.size > 0) {
89
+ operation.parameters = Array.from(parameters.values());
90
+ }
91
+ const contentMediaTypeMap = new Map();
92
+ // Seed requestBody content from operation2 (the base)
93
+ if (operation.requestBody?.content) {
94
+ for (const [contentType, mediaType] of Object.entries(operation.requestBody.content)) {
95
+ contentMediaTypeMap.set(contentType, mediaType);
96
+ }
97
+ }
98
+ // Merge requestBody content from operation1 into the base.
99
+ // When merging 'examples', we expect example names to be unique (no overwrite).
100
+ if (operation1.requestBody?.content) {
101
+ for (const [contentType, mediaType] of Object.entries(operation1.requestBody.content)) {
102
+ const mediaTypeObj = mediaType;
103
+ if (contentMediaTypeMap.has(contentType)) {
104
+ const existingMediaType = contentMediaTypeMap.get(contentType);
105
+ if (existingMediaType && (existingMediaType.examples || mediaTypeObj.examples)) {
106
+ // Assumption: example names (keys) are unique, so this merge is safe
107
+ existingMediaType.examples = {
108
+ ...existingMediaType.examples,
109
+ ...mediaTypeObj.examples,
110
+ };
111
+ }
112
+ }
113
+ else {
114
+ contentMediaTypeMap.set(contentType, mediaTypeObj);
115
+ }
116
+ }
117
+ }
118
+ if (contentMediaTypeMap.size > 0) {
119
+ operation.requestBody = {
120
+ ...operation.requestBody,
121
+ content: Object.fromEntries(contentMediaTypeMap),
122
+ };
123
+ }
124
+ return operation;
125
+ };
@@ -0,0 +1,5 @@
1
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
+ export declare const DEFAULT_EXAMPLE_NAME = "Default example";
3
+ export declare const OPERATION_KEYS: readonly (keyof OpenAPIV3_1.PathItemObject)[];
4
+ export declare const mergePathItem: (paths: OpenAPIV3_1.PathsObject, normalizedPathKey: string, pathItem: OpenAPIV3_1.PathItemObject, mergeOperation?: boolean) => void;
5
+ //# sourceMappingURL=merge-path-item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-path-item.d.ts","sourceRoot":"","sources":["../../src/helpers/merge-path-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAOxD,eAAO,MAAM,oBAAoB,oBAAoB,CAAA;AAErD,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,MAAM,WAAW,CAAC,cAAc,CAAC,EASvE,CAAA;AAED,eAAO,MAAM,aAAa,GACxB,OAAO,WAAW,CAAC,WAAW,EAC9B,mBAAmB,MAAM,EACzB,UAAU,WAAW,CAAC,cAAc,EACpC,iBAAgB,OAAe,KAC9B,IA8BF,CAAA"}
@@ -0,0 +1,37 @@
1
+ import { generateUniqueValue } from '../helpers/generate-unique-value.js';
2
+ import { getOperationExamples } from '../helpers/get-operation-examples.js';
3
+ import { mergeOperations } from '../helpers/merge-operation.js';
4
+ import { renameOperationExamples } from '../helpers/rename-operation-example.js';
5
+ export const DEFAULT_EXAMPLE_NAME = 'Default example';
6
+ export const OPERATION_KEYS = [
7
+ 'get',
8
+ 'put',
9
+ 'post',
10
+ 'delete',
11
+ 'options',
12
+ 'head',
13
+ 'patch',
14
+ 'trace',
15
+ ];
16
+ export const mergePathItem = (paths, normalizedPathKey, pathItem, mergeOperation = false) => {
17
+ const targetPath = (paths[normalizedPathKey] ?? {});
18
+ for (const [key, value] of Object.entries(pathItem)) {
19
+ if (value === undefined) {
20
+ continue;
21
+ }
22
+ const isOperationKey = OPERATION_KEYS.includes(key);
23
+ if (isOperationKey && targetPath[key] && mergeOperation) {
24
+ // Get all example names from the target path
25
+ const exampleNames = getOperationExamples(targetPath);
26
+ // Generate a unique example name
27
+ const newExampleName = generateUniqueValue(DEFAULT_EXAMPLE_NAME, (value) => !exampleNames.has(value), '#');
28
+ // Rename operation examples from the new path item (we know it's gonna have only the default example)
29
+ renameOperationExamples(pathItem[key], DEFAULT_EXAMPLE_NAME, newExampleName);
30
+ // Merge the operations
31
+ targetPath[key] = mergeOperations(targetPath[key], pathItem[key]);
32
+ continue;
33
+ }
34
+ targetPath[key] = value;
35
+ }
36
+ paths[normalizedPathKey] = targetPath;
37
+ };
@@ -4,9 +4,9 @@ import type { Request } from '../types.js';
4
4
  * Extracts parameters from a Postman request and converts them to OpenAPI parameter objects.
5
5
  * Processes query, path, and header parameters from the request URL and headers.
6
6
  */
7
- export declare function extractParameters(request: Request): OpenAPIV3_1.ParameterObject[];
7
+ export declare function extractParameters(request: Request, exampleName: string): OpenAPIV3_1.ParameterObject[];
8
8
  /**
9
9
  * Creates an OpenAPI parameter object from a Postman parameter.
10
10
  */
11
- export declare function createParameterObject(param: any, paramIn: 'query' | 'path' | 'header'): OpenAPIV3_1.ParameterObject;
11
+ export declare function createParameterObject(param: any, paramIn: 'query' | 'path' | 'header', exampleName: string): OpenAPIV3_1.ParameterObject;
12
12
  //# sourceMappingURL=parameters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../src/helpers/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,SAAS,CAAA;AAI9C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAAC,eAAe,EAAE,CA2DjF;AAoBD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC,eAAe,CAmDnH"}
1
+ {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../src/helpers/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,SAAS,CAAA;AAI9C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC,eAAe,EAAE,CA2DtG;AAoBD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,GAAG,EACV,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,EACpC,WAAW,EAAE,MAAM,GAClB,WAAW,CAAC,eAAe,CAwD7B"}
@@ -1,103 +1,131 @@
1
- import { inferSchemaType } from "./schemas.js";
2
- function extractParameters(request) {
3
- const parameters = [];
4
- const parameterMap = /* @__PURE__ */ new Map();
5
- if (typeof request === "string" || !request.url) {
6
- return parameters;
7
- }
8
- const url = typeof request.url === "string" ? { raw: request.url } : request.url;
9
- if (url.query) {
10
- url.query.forEach((param) => {
11
- const paramObj = createParameterObject(param, "query");
12
- if (paramObj.name) {
13
- parameterMap.set(paramObj.name, paramObj);
14
- }
15
- });
16
- }
17
- if (url.variable) {
18
- url.variable.forEach((param) => {
19
- const paramObj = createParameterObject(param, "path");
20
- if (paramObj.name) {
21
- parameterMap.set(paramObj.name, paramObj);
22
- }
23
- });
24
- }
25
- if (url.path) {
26
- const pathArray = Array.isArray(url.path) ? url.path : [url.path];
27
- const extractedVariables = extractPathVariablesFromPathArray(pathArray);
28
- extractedVariables.forEach((varName) => {
29
- if (!parameterMap.has(varName)) {
30
- parameterMap.set(varName, {
31
- name: varName,
32
- in: "path",
33
- required: true,
34
- schema: {
35
- type: "string"
36
- }
1
+ import { inferSchemaType } from './schemas.js';
2
+ /**
3
+ * Extracts parameters from a Postman request and converts them to OpenAPI parameter objects.
4
+ * Processes query, path, and header parameters from the request URL and headers.
5
+ */
6
+ export function extractParameters(request, exampleName) {
7
+ const parameters = [];
8
+ const parameterMap = new Map();
9
+ if (typeof request === 'string' || !request.url) {
10
+ return parameters;
11
+ }
12
+ const url = typeof request.url === 'string' ? { raw: request.url } : request.url;
13
+ // Process query parameters
14
+ if (url.query) {
15
+ url.query.forEach((param) => {
16
+ const paramObj = createParameterObject(param, 'query', exampleName);
17
+ if (paramObj.name) {
18
+ parameterMap.set(paramObj.name, paramObj);
19
+ }
37
20
  });
38
- }
39
- });
40
- }
41
- if (request.header && Array.isArray(request.header)) {
42
- request.header.forEach((header) => {
43
- const paramObj = createParameterObject(header, "header");
44
- if (paramObj.name) {
45
- parameterMap.set(paramObj.name, paramObj);
46
- }
47
- });
48
- }
49
- return Array.from(parameterMap.values());
21
+ }
22
+ // Process path parameters
23
+ if (url.variable) {
24
+ url.variable.forEach((param) => {
25
+ const paramObj = createParameterObject(param, 'path', exampleName);
26
+ if (paramObj.name) {
27
+ parameterMap.set(paramObj.name, paramObj);
28
+ }
29
+ });
30
+ }
31
+ // Include variables extracted from url.path array
32
+ if (url.path) {
33
+ const pathArray = Array.isArray(url.path) ? url.path : [url.path];
34
+ const extractedVariables = extractPathVariablesFromPathArray(pathArray);
35
+ extractedVariables.forEach((varName) => {
36
+ if (!parameterMap.has(varName)) {
37
+ parameterMap.set(varName, {
38
+ name: varName,
39
+ in: 'path',
40
+ required: true,
41
+ schema: {
42
+ type: 'string',
43
+ },
44
+ });
45
+ }
46
+ });
47
+ }
48
+ // Process header parameters
49
+ if (request.header && Array.isArray(request.header)) {
50
+ request.header.forEach((header) => {
51
+ const paramObj = createParameterObject(header, 'header', exampleName);
52
+ if (paramObj.name) {
53
+ parameterMap.set(paramObj.name, paramObj);
54
+ }
55
+ });
56
+ }
57
+ return Array.from(parameterMap.values());
50
58
  }
59
+ /**
60
+ * Helper function to extract variables from the url.path array.
61
+ */
51
62
  function extractPathVariablesFromPathArray(pathArray) {
52
- const variables = [];
53
- const variableRegex = /{{\s*([\w.-]+)\s*}}/;
54
- pathArray.forEach((segment) => {
55
- const segmentString = typeof segment === "string" ? segment : segment.value;
56
- const match = segmentString.match(variableRegex);
57
- if (match?.[1]) {
58
- variables.push(match[1]);
59
- }
60
- });
61
- return variables;
63
+ const variables = [];
64
+ const variableRegex = /{{\s*([\w.-]+)\s*}}/;
65
+ pathArray.forEach((segment) => {
66
+ const segmentString = typeof segment === 'string' ? segment : segment.value;
67
+ const match = segmentString.match(variableRegex);
68
+ if (match?.[1]) {
69
+ variables.push(match[1]);
70
+ }
71
+ });
72
+ return variables;
62
73
  }
63
- function createParameterObject(param, paramIn) {
64
- const parameter = {
65
- name: param.key || "",
66
- in: paramIn,
67
- description: param.description
68
- };
69
- if (paramIn === "path") {
70
- parameter.required = true;
71
- } else if (paramIn === "query") {
72
- const isRequired = param.description?.toLowerCase().includes("[required]") || param.key && param.key.toLowerCase() === "required";
73
- if (isRequired) {
74
- parameter.required = true;
75
- if (parameter.description) {
76
- parameter.description = parameter.description.replace(/\[required\]/gi, "").trim();
77
- }
74
+ /**
75
+ * Creates an OpenAPI parameter object from a Postman parameter.
76
+ */
77
+ export function createParameterObject(param, paramIn, exampleName) {
78
+ const parameter = {
79
+ name: param.key || '',
80
+ in: paramIn,
81
+ description: param.description,
82
+ examples: {
83
+ [exampleName]: {
84
+ value: param.value,
85
+ 'x-disabled': !!param.disabled,
86
+ },
87
+ },
88
+ };
89
+ // Path parameters are always required in OpenAPI
90
+ if (paramIn === 'path') {
91
+ parameter.required = true;
92
+ }
93
+ else if (paramIn === 'query') {
94
+ // Check if the parameter is required based on description or name
95
+ const isRequired = param.description?.toLowerCase().includes('[required]') || (param.key && param.key.toLowerCase() === 'required');
96
+ if (isRequired) {
97
+ parameter.required = true;
98
+ // Remove '[required]' from the description
99
+ if (parameter.description) {
100
+ parameter.description = parameter.description.replace(/\[required\]/gi, '').trim();
101
+ }
102
+ }
103
+ }
104
+ if (param.value !== undefined) {
105
+ // For path parameters, prefer string type unless value is explicitly a number type
106
+ // This prevents converting string IDs like "testId" to integers
107
+ if (paramIn === 'path') {
108
+ // Path parameters are typically strings (IDs, slugs, etc.)
109
+ // Only use number/integer if the value is actually a number type, not a string
110
+ if (typeof param.value === 'number') {
111
+ parameter.schema = inferSchemaType(param.value);
112
+ }
113
+ else {
114
+ // For strings (including empty strings), default to string type
115
+ parameter.schema = { type: 'string' };
116
+ }
117
+ }
118
+ else {
119
+ parameter.schema = inferSchemaType(param.value);
120
+ }
121
+ }
122
+ else {
123
+ parameter.schema = { type: 'string' }; // Default to string if no value is provided
78
124
  }
79
- }
80
- if (param.value !== void 0) {
81
- parameter.example = param.value;
82
- if (paramIn === "path") {
83
- if (typeof param.value === "number") {
84
- parameter.schema = inferSchemaType(param.value);
85
- } else {
86
- parameter.schema = { type: "string" };
87
- }
88
- } else {
89
- parameter.schema = inferSchemaType(param.value);
125
+ // Add x-scalar-disabled extension if parameter is disabled
126
+ if (param.disabled === true) {
127
+ // @ts-expect-error - x-scalar-disabled is not a valid parameter object property
128
+ parameter['x-scalar-disabled'] = true;
90
129
  }
91
- } else {
92
- parameter.schema = { type: "string" };
93
- }
94
- if (param.disabled === true) {
95
- parameter["x-scalar-disabled"] = true;
96
- }
97
- return parameter;
130
+ return parameter;
98
131
  }
99
- export {
100
- createParameterObject,
101
- extractParameters
102
- };
103
- //# sourceMappingURL=parameters.js.map
@@ -15,7 +15,7 @@ export type ServerUsage = {
15
15
  * Handles nested item groups, extracts request details, and generates corresponding
16
16
  * OpenAPI path items and operations.
17
17
  */
18
- export declare function processItem(item: Item | ItemGroup, parentTags?: string[], parentPath?: string): {
18
+ export declare function processItem(item: Item | ItemGroup, exampleName?: string, parentTags?: string[], parentPath?: string): {
19
19
  paths: OpenAPIV3_1.PathsObject;
20
20
  components: OpenAPIV3_1.ComponentsObject;
21
21
  serverUsage: ServerUsage[];
@@ -1 +1 @@
1
- {"version":3,"file":"path-items.d.ts","sourceRoot":"","sources":["../../src/helpers/path-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAW9C,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAE7F;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;CACpB,CAAA;AAoBD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,UAAU,GAAE,MAAM,EAAO,EACzB,UAAU,GAAE,MAAW,GACtB;IACD,KAAK,EAAE,WAAW,CAAC,WAAW,CAAA;IAC9B,UAAU,EAAE,WAAW,CAAC,gBAAgB,CAAA;IACxC,WAAW,EAAE,WAAW,EAAE,CAAA;CAC3B,CA2KA"}
1
+ {"version":3,"file":"path-items.d.ts","sourceRoot":"","sources":["../../src/helpers/path-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAW9C,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAE7F;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;CACpB,CAAA;AAoBD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,WAAW,GAAE,MAAkB,EAC/B,UAAU,GAAE,MAAM,EAAO,EACzB,UAAU,GAAE,MAAW,GACtB;IACD,KAAK,EAAE,WAAW,CAAC,WAAW,CAAA;IAC9B,UAAU,EAAE,WAAW,CAAC,gBAAgB,CAAA;IACxC,WAAW,EAAE,WAAW,EAAE,CAAA;CAC3B,CA2KA"}