public extractOne()

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));
            }
          }
        }
      }
    }
  }