in lib/xMsExampleExtractor.ts [105:261]
public extractOne(
relativeExamplesPath: string,
outputExamples: string,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
api: any,
recordingFileName: string
): void {
const recording = JSON.parse(fs.readFileSync(recordingFileName).toString());
const paths = api.paths;
let pathIndex = 0;
let pathParams: MutableStringMap<number> = {};
for (const path of keys(paths)) {
pathIndex++;
const searchResult = path.match(/\/{\w*\}/g);
const pathParts = path.split("/");
let pathToMatch = path;
pathParams = {};
if (searchResult !== null) {
for (const match of searchResult) {
const splitRegEx = /[{}]/;
const pathParam = match.split(splitRegEx)[1];
for (const [part, value] of entries(pathParts)) {
const pathPart = "/" + value;
if (pathPart.localeCompare(match) === 0) {
pathParams[pathParam] = part;
}
}
pathToMatch = pathToMatch.replace(match, "/[^/]+");
}
}
let newPathToMatch = pathToMatch.replace(/\//g, "\\/");
newPathToMatch = newPathToMatch + "$";
// for this API path (and method), try to find it in the recording file, and get
// the data
const recordingEntries: StringMap<any> = recording.Entries;
let entryIndex = 0;
let queryParams: any = {};
for (const recordingEntry of values(recordingEntries)) {
entryIndex++;
const parsedUrl = new URL(recordingEntry.RequestUri, "https://management.azure.com");
let recordingPath = parsedUrl.href || "";
queryParams = kvPairsToObject(parsedUrl.searchParams) || {};
const hostUrl = parsedUrl ? parsedUrl.protocol! + "//" + parsedUrl.hostname! : undefined;
const headerParams = recordingEntry.RequestHeaders;
// if command-line included check for API version, validate api-version from URI in
// recordings matches the api-version of the spec
if (
!this.options.matchApiVersion ||
("api-version" in queryParams && queryParams["api-version"] === api.info.version)
) {
recordingPath = recordingPath.replace(/\?.*/, "");
const recordingPathParts = recordingPath.split("/");
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
const match = recordingPath.match(newPathToMatch);
if (match !== null) {
log.silly("path: " + path);
log.silly("recording path: " + recordingPath);
const pathParamsValues: MutableStringMap<unknown> = {};
for (const [p, v] of mapEntries(pathParams)) {
const index = v;
pathParamsValues[p] = recordingPathParts[index];
}
if (hostUrl !== undefined) {
pathParamsValues.url = hostUrl;
}
// found a match in the recording
const requestMethodFromRecording = recordingEntry.RequestMethod;
const infoFromOperation = paths[path][requestMethodFromRecording.toLowerCase()];
if (typeof infoFromOperation !== "undefined") {
// need to consider each method in operation
const fileNameArray = recordingFileName.split("/");
let fileName = fileNameArray[fileNameArray.length - 1];
fileName = fileName.split(".json")[0];
fileName = fileName.replace(/\//g, "-");
const exampleFileName = `${fileName}-${requestMethodFromRecording}-example-${pathIndex}${entryIndex}.json`;
const ref = {
$ref: relativeExamplesPath + exampleFileName,
};
const exampleFriendlyName = `${fileName}${requestMethodFromRecording}${pathIndex}${entryIndex}`;
log.debug(`exampleFriendlyName: ${exampleFriendlyName}`);
if (!("x-ms-examples" in infoFromOperation)) {
infoFromOperation["x-ms-examples"] = {};
}
infoFromOperation["x-ms-examples"][exampleFriendlyName] = ref;
const exampleL: {
parameters: MutableStringMap<unknown>;
responses: MutableStringMap<{
body?: unknown;
}>;
} = {
parameters: {},
responses: {},
};
const paramsToProcess = [
...mapEntries(pathParamsValues),
...mapEntries(queryParams),
...mapEntries(headerParams),
];
for (const paramEntry of paramsToProcess) {
const param = paramEntry[0];
const v = paramEntry[1];
exampleL.parameters[param] = v;
}
const params = infoFromOperation.parameters;
for (const param of keys(infoFromOperation.parameters)) {
if (params[param].in === "body") {
const bodyParamName = params[param].name;
const bodyParamValue = recordingEntry.RequestBody;
const bodyParamExample: MutableStringMap<unknown> = {};
bodyParamExample[bodyParamName] = bodyParamValue;
exampleL.parameters[bodyParamName] =
bodyParamValue !== "" ? JSON.parse(bodyParamValue) : "";
}
}
const parseResponseBody = (body: any) => {
try {
return JSON.parse(body);
} catch (err) {
return body;
}
};
for (const _v of keys(infoFromOperation.responses)) {
const statusCodeFromRecording = recordingEntry.StatusCode;
let responseBody = recordingEntry.ResponseBody;
if (typeof responseBody === "string" && responseBody !== "") {
responseBody = parseResponseBody(responseBody);
}
exampleL.responses[statusCodeFromRecording] = {
body: responseBody,
};
}
log.info(
`Writing x-ms-examples at ${pathlib.resolve(outputExamples, exampleFileName)}`
);
const examplePath = pathlib.join(outputExamples, exampleFileName);
const dir = pathlib.dirname(examplePath);
mkdirRecursiveSync(dir);
fs.writeFileSync(examplePath, JSON.stringify(exampleL, null, 2));
}
}
}
}
}
}