export async function generateAutorestConfig()

in generator/autorest.ts [53:157]


export async function generateAutorestConfig(readmePath: string, bicepReadmePath: string) {
  // This function takes in an input autorest configuration file (readme.md), and generates a autorest configuration file tailored for use by autorest.bicep (readme.bicep.md)
  // We search for markdown yaml blocks containing input .json files, and unconditionally use them to generate output.
  // The expected output file should consist of a set of blocks tagged by api version and a 'multi-api' block with links to tags:
  //
  //   ##Bicep
  //   
  //   ### Bicep multi-api
  //   ```yaml $(bicep) && $(multiapi)
  //   batch:
  //     - tag: microsoft.securityinsights-2024-03-01
  //     - tag: microsoft.securityinsights-2024-01-01-preview
  //     ...
  //   ```
  //
  //   ### Tag: microsoft.securityinsights-2024-03-01 and bicep
  //   ```yaml $(tag) == 'microsoft.securityinsights-2024-03-01' && $(bicep)
  //   input-file:
  //     - Microsoft.SecurityInsights/stable/2024-03-01/AlertRules.json
  //     - Microsoft.SecurityInsights/stable/2024-03-01/AutomationRules.json
  //     ...
  //   ```
  //
  //   ### Tag: microsoft.securityinsights-2024-01-01-preview and bicep
  //   ```yaml $(tag) == 'microsoft.securityinsights-2024-01-01-preview' && $(bicep)
  //   input-file:
  //     - Microsoft.SecurityInsights/preview/2024-01-01-preview/AlertRules.json
  //     - Microsoft.SecurityInsights/preview/2024-01-01-preview/AutomationRules.json
  //     - Microsoft.SecurityInsights/preview/2024-01-01-preview/BillingStatistics.json
  //     ...

  // We expect a path format convention of <provider>/(any/number/of/intervening/folders)/<yyyy>-<mm>-<dd>(|-preview)/<filename>.json
  // This information is used to generate individual tags in the generated autorest configuration
  // eslint-disable-next-line no-useless-escape
  const pathRegex = /^(\$\(this-folder\)\/|)([^\/]+)(?:\/[^\/]+)*\/(\d{4}-\d{2}-\d{2}(|-preview))\/.*\.json$/i;

  const readmeContents = await readFile(readmePath, { encoding: 'utf8' });
  const readmeMarkdown = markdown.parse(readmeContents);

  const inputFiles = new Set<string>();
  // we need to look for all autorest configuration elements containing input files, and collect that list of files. These will look like (e.g.):
  // ```yaml $(tag) == 'someTag'
  // input-file:
  // - path/to/file.json
  // - path/to/other_file.json
  // ```
  for (const node of markdown.iterate(readmeMarkdown.markDown)) {
    // We're only interested in yaml code blocks
    if (node.type !== 'code_block' || !node.info || !node.literal ||
      !node.info.trim().startsWith('yaml')) {
      continue;
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const yamlData = yaml.load(node.literal) as any;
    if (yamlData) {
      // input-file may be a single string or an array of strings
      const inputFile = yamlData['input-file'];
      if (typeof inputFile === 'string') {
        inputFiles.add(inputFile);
      } else if (inputFile instanceof Array) {
        for (const i of inputFile) {
          inputFiles.add(i);
        }
      }
    }
  }

  const filesByTag: Record<string, string[]> = {};
  for (const file of inputFiles) {
    const normalizedFile = normalizeJsonPath(file);
    const match = pathRegex.exec(normalizedFile);
    if (match) {
      // Generate a unique tag. We can't process all of the different API versions in one autorest pass
      // because there are constraints on naming uniqueness (e.g. naming of definitions), so we want to pass over
      // each API version separately.
      const tagName = `${match[2].toLowerCase()}-${match[3].toLowerCase()}`;
      if (!filesByTag[tagName]) {
        filesByTag[tagName] = [];
      }

      filesByTag[tagName].push(normalizedFile);
    } else {
      console.warn(`WARNING: Unable to parse swagger path "${file}"`);
    }
  }

  let generatedContent = `##Bicep

### Bicep multi-api
\`\`\`yaml $(bicep) && $(multiapi)
${yaml.dump({ 'batch': Object.keys(filesByTag).map(tag => ({ 'tag': tag })) }, { lineWidth: 1000 })}
\`\`\`
`;

  for (const tag of Object.keys(filesByTag)) {
    generatedContent += `### Tag: ${tag} and bicep
\`\`\`yaml $(tag) == '${tag}' && $(bicep)
${yaml.dump({ 'input-file': filesByTag[tag] }, { lineWidth: 1000})}
\`\`\`
`;
  }

  await writeFile(bicepReadmePath, generatedContent);
}