Skip to content

Commit 2f05549

Browse files
committed
update snippet generator
1 parent 2da0ccf commit 2f05549

File tree

1 file changed

+57
-96
lines changed

1 file changed

+57
-96
lines changed

packages/react-openapi/src/code-samples.ts

Lines changed: 57 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,31 @@ export const codeSampleGenerators: CodeSampleGenerator[] = [
3737
label: 'HTTP',
3838
syntax: 'http',
3939
generate: ({ method, url: { origin, path }, headers = {}, body }: CodeSampleInput) => {
40+
// Process URL and headers to use consistent placeholder format
41+
const processedPath = convertPathParametersToPlaceholders(path);
42+
const processedHeaders = processHeadersWithPlaceholders(headers);
43+
4044
if (body) {
4145
// if we had a body add a content length header
4246
const bodyContent = body ? stringifyOpenAPI(body) : '';
4347
// handle unicode chars with a text encoder
4448
const encoder = new TextEncoder();
4549

46-
const bodyString = BodyGenerators.getHTTPBody(body, headers);
50+
const bodyString = BodyGenerators.getHTTPBody(body, processedHeaders);
4751

4852
if (bodyString) {
4953
body = bodyString;
5054
}
5155

52-
headers = {
53-
...headers,
54-
'Content-Length': encoder.encode(bodyContent).length.toString(),
55-
};
56+
processedHeaders['Content-Length'] = encoder.encode(bodyContent).length.toString();
5657
}
5758

58-
if (!headers.hasOwnProperty('Accept')) {
59-
headers.Accept = '*/*';
59+
if (!processedHeaders.hasOwnProperty('Accept')) {
60+
processedHeaders.Accept = '*/*';
6061
}
6162

62-
const headerString = headers
63-
? `${Object.entries(headers)
63+
const headerString = processedHeaders
64+
? `${Object.entries(processedHeaders)
6465
.map(([key, value]) =>
6566
key.toLowerCase() !== 'host' ? `${key}: ${value}` : ''
6667
)
@@ -69,7 +70,7 @@ export const codeSampleGenerators: CodeSampleGenerator[] = [
6970

7071
const bodyString = body ? `\n${body}` : '';
7172

72-
const httpRequest = `${method.toUpperCase()} ${decodeURI(path)} HTTP/1.1
73+
const httpRequest = `${method.toUpperCase()} ${decodeURI(processedPath)} HTTP/1.1
7374
Host: ${origin.replaceAll(/https*:\/\//g, '')}
7475
${headerString}${bodyString}`;
7576

@@ -87,15 +88,23 @@ ${headerString}${bodyString}`;
8788
lines.push(`--request ${method.toUpperCase()}`);
8889
}
8990

90-
lines.push(`--url '${origin}${path}'`);
91+
// Process URL and headers to use consistent placeholder format
92+
const processedUrl = convertPathParametersToPlaceholders(origin + path);
93+
const processedHeaders = processHeadersWithPlaceholders(headers);
94+
95+
lines.push(`--url '${processedUrl}'`);
9196

9297
if (body) {
93-
const bodyContent = BodyGenerators.getCurlBody(body, headers);
98+
const bodyContent = BodyGenerators.getCurlBody(body, processedHeaders);
9499

95100
if (bodyContent) {
96101
body = bodyContent.body;
97102
headers = bodyContent.headers;
103+
} else {
104+
headers = processedHeaders;
98105
}
106+
} else {
107+
headers = processedHeaders;
99108
}
100109

101110
if (headers && Object.keys(headers).length > 0) {
@@ -122,18 +131,26 @@ ${headerString}${bodyString}`;
122131
generate: ({ method, url: { origin, path }, headers, body }) => {
123132
let code = '';
124133

134+
// Process URL and headers to use consistent placeholder format
135+
const processedUrl = convertPathParametersToPlaceholders(origin + path);
136+
const processedHeaders = processHeadersWithPlaceholders(headers);
137+
125138
if (body) {
126-
const lines = BodyGenerators.getJavaScriptBody(body, headers);
139+
const lines = BodyGenerators.getJavaScriptBody(body, processedHeaders);
127140

128141
if (lines) {
129142
// add the generated code to the top
130143
code += lines.code;
131144
body = lines.body;
132145
headers = lines.headers;
146+
} else {
147+
headers = processedHeaders;
133148
}
149+
} else {
150+
headers = processedHeaders;
134151
}
135152

136-
code += `const response = await fetch('${origin}${path}', {
153+
code += `const response = await fetch('${processedUrl}', {
137154
method: '${method.toUpperCase()}',\n`;
138155

139156
if (headers && Object.keys(headers).length > 0) {
@@ -166,23 +183,9 @@ ${headerString}${bodyString}`;
166183
}
167184
code += 'import requests\n\n';
168185

169-
// Extract path parameters and create constants
170-
const { extractedParams, processedPath } = extractPathParameters(path);
171-
if (extractedParams.length > 0) {
172-
extractedParams.forEach(param => {
173-
code += `${param.constant} = "${param.placeholder}"\n`;
174-
});
175-
code += '\n';
176-
}
177-
178-
// Process headers to create better placeholders
179-
const processedHeaders = processPythonHeaders(headers);
180-
if (processedHeaders.constants.length > 0) {
181-
processedHeaders.constants.forEach(constant => {
182-
code += `${constant.name} = "${constant.placeholder}"\n`;
183-
});
184-
code += '\n';
185-
}
186+
// Process headers and URL to use consistent placeholder format
187+
const processedUrl = convertPathParametersToPlaceholders(origin + path);
188+
const processedHeaders = processHeadersWithPlaceholders(headers);
186189

187190
if (body) {
188191
const lines = BodyGenerators.getPythonBody(body, headers);
@@ -195,19 +198,14 @@ ${headerString}${bodyString}`;
195198
}
196199
}
197200

198-
// Build the request
199-
const urlStr = extractedParams.length > 0
200-
? `f"${origin}${processedPath}"`
201-
: `"${origin}${path}"`;
202-
203201
code += `response = requests.${method.toLowerCase()}(\n`;
204-
code += indent(`${urlStr},\n`, 4);
202+
code += indent(`"${processedUrl}",\n`, 4);
205203

206-
if (processedHeaders.headers && Object.keys(processedHeaders.headers).length > 0) {
204+
if (processedHeaders && Object.keys(processedHeaders).length > 0) {
207205
code += indent(`headers={\n`, 4);
208-
Object.entries(processedHeaders.headers).forEach(([key, value], index, array) => {
206+
Object.entries(processedHeaders).forEach(([key, value], index, array) => {
209207
const isLast = index === array.length - 1;
210-
code += indent(`"${key}": ${value}${isLast ? '' : ','}\n`, 8);
208+
code += indent(`"${key}": "${value}"${isLast ? '' : ','}\n`, 8);
211209
});
212210
code += indent(`},\n`, 4);
213211
}
@@ -551,78 +549,41 @@ function buildHeredoc(lines: string[]): string {
551549
}
552550

553551
/**
554-
* Extracts path parameters and converts them to Python constants
552+
* Converts path parameters from {paramName} to YOUR_PARAM_NAME format
555553
*/
556-
function extractPathParameters(path: string): {
557-
extractedParams: Array<{ constant: string; placeholder: string; param: string }>;
558-
processedPath: string;
559-
} {
560-
const extractedParams: Array<{ constant: string; placeholder: string; param: string }> = [];
561-
let processedPath = path;
562-
563-
// Find all path parameters in the format {paramName}
564-
const paramMatches = path.match(/\{([^}]+)\}/g);
565-
566-
if (paramMatches) {
567-
paramMatches.forEach(match => {
568-
const paramName = match.slice(1, -1); // Remove { and }
569-
// Convert camelCase to SNAKE_CASE
570-
const constantName = paramName
571-
.replace(/([a-z])([A-Z])/g, '$1_$2')
572-
.toUpperCase();
573-
const placeholder = `<your ${paramName.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase()}>`;
574-
575-
extractedParams.push({
576-
constant: constantName,
577-
placeholder: placeholder,
578-
param: paramName
579-
});
580-
581-
// Replace {paramName} with {CONSTANT_NAME} for f-string
582-
processedPath = processedPath.replace(match, `{${constantName}}`);
583-
});
584-
}
585-
586-
return { extractedParams, processedPath };
554+
function convertPathParametersToPlaceholders(urlPath: string): string {
555+
return urlPath.replace(/\{([^}]+)\}/g, (match, paramName) => {
556+
// Convert camelCase to UPPER_SNAKE_CASE
557+
const placeholder = paramName
558+
.replace(/([a-z])([A-Z])/g, '$1_$2')
559+
.toUpperCase();
560+
return `YOUR_${placeholder}`;
561+
});
587562
}
588563

589564
/**
590-
* Processes headers to create Python constants and clean formatting
565+
* Processes headers to use consistent placeholder format
591566
*/
592-
function processPythonHeaders(headers?: Record<string, string>): {
593-
constants: Array<{ name: string; placeholder: string }>;
594-
headers: Record<string, string>;
595-
} {
567+
function processHeadersWithPlaceholders(headers?: Record<string, string>): Record<string, string> {
596568
if (!headers) {
597-
return { constants: [], headers: {} };
569+
return {};
598570
}
599571

600-
const constants: Array<{ name: string; placeholder: string }> = [];
601572
const processedHeaders: Record<string, string> = {};
602573

603574
Object.entries(headers).forEach(([key, value]) => {
604575
if (key === 'Authorization' && value.includes('Bearer')) {
605-
// Extract token constants
606-
const constantName = 'API_TOKEN';
607-
const placeholder = '<your gitbook api token>';
608-
constants.push({ name: constantName, placeholder });
609-
processedHeaders[key] = `f"Bearer {${constantName}}"`;
576+
processedHeaders[key] = 'Bearer YOUR_API_TOKEN';
610577
} else if (key === 'Authorization' && value.includes('Basic')) {
611-
const constantName = 'API_TOKEN';
612-
const placeholder = '<your basic auth token>';
613-
constants.push({ name: constantName, placeholder });
614-
processedHeaders[key] = `f"Basic {${constantName}}"`;
578+
processedHeaders[key] = 'Basic YOUR_API_TOKEN';
615579
} else if (value.includes('YOUR_') || value.includes('TOKEN')) {
616-
// Generic token handling
617-
const constantName = 'API_TOKEN';
618-
const placeholder = '<your api token>';
619-
constants.push({ name: constantName, placeholder });
620-
processedHeaders[key] = `f"Bearer {${constantName}}"`;
580+
// Already in correct format or generic token
581+
processedHeaders[key] = value.replace(/YOUR_SECRET_TOKEN|YOUR_TOKEN/g, 'YOUR_API_TOKEN');
621582
} else {
622-
// Regular headers
623-
processedHeaders[key] = `"${value}"`;
583+
// Regular headers - keep as-is
584+
processedHeaders[key] = value;
624585
}
625586
});
626587

627-
return { constants, headers: processedHeaders };
588+
return processedHeaders;
628589
}

0 commit comments

Comments
 (0)