fastify / help

Need help with Fastify? File an Issue here.
https://www.fastify.io/
65 stars 8 forks source link

Allow ignoring single fields/errors #1053

Closed Bluscream closed 2 months ago

Bluscream commented 2 months ago

You have already researched for similar issues?

I hope so

What are you trying to achieve, or the steps to reproduce?

I want to merge all schemas from different API endpoint responses so i can let AI build a OpenAPI spec file for me

import fs from 'fs/promises';
import path from 'path';
import { defaultResolver, mergeSchemas } from '@fastify/merge-json-schemas';

async function getAllJsonFiles(directory) {
  const files = await fs.readdir(directory);
  const jsonFiles = [];

  for (const file of files) {
    const filePath = path.join(directory, file);
    const stats = await fs.stat(filePath);

    if (stats.isDirectory()) {
      jsonFiles.push(...await getAllJsonFiles(filePath));
    } else if (path.extname(file) === '.json') {
      jsonFiles.push(filePath);
    }
  }

  return jsonFiles;
}

async function loadSchema(file) {
  try {
    const content = await fs.readFile(file, 'utf8');
    return JSON.parse(content);
  } catch (error) {
    console.error(`Error loading schema from ${file}:`, error);
    throw error;
  }
}

async function mergeSchemasWithFallback(files) {
  let schemas = [];

  for (const file of files) {
    try {
      const schema = await loadSchema(file);

      // Check if the schema has a custom resolver
      if (schema.$ref && !schema.$ref.startsWith('#')) {
        console.log(`Found external reference: ${schema.$ref}`);

        // Try to resolve the $ref
        let resolvedRef;
        try {
          resolvedRef = await fs.promises.readFile(schema.$ref, 'utf8');
          resolvedRef = JSON.parse(resolvedRef);
        } catch (error) {
          console.error(`Failed to resolve reference: ${schema.$ref}`, error);
        }

        // Merge the resolved schema
        schemas.push(resolvedRef || schema);
      } else {
        schemas.push(schema);
      }
    } catch (error) {
      console.error(`Error processing schema from ${file}:`, error);
    }
  }

  try {
    return mergeSchemas(schemas, { onConflict: "first"});
  } catch (error) {
    console.error('An error occurred during schema merging:', error);
    throw error;
  }
}

async function writeMergedSchemaToFile(mergedSchema) {
  try {
    await fs.writeFile('merged.schema.json', JSON.stringify(mergedSchema, null, 2));
    console.log('Merged schema has been written to merged.schema.json');
  } catch (error) {
    console.error('Error writing merged schema to file:', error);
  }
}

(async () => {
  try {
    const jsonFiles = await getAllJsonFiles(process.cwd());

    const mergedSchema = await mergeSchemasWithFallback(jsonFiles);

    // Write the merged schema to a file
    await writeMergedSchemaToFile(mergedSchema);

    console.log(JSON.stringify(mergedSchema, null, 2));

  } catch (error) {
    console.error('An error occurred:', error);
  }
})();

What was the result you received?

PS C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\schemas\pietsmiet.de> node ..\..\scripts\merge-schemas.js
An error occurred during schema merging: MergeError [JsonSchemaMergeError]: Failed to merge "type" keyword schemas.
    at hybridArraysIntersection (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\lib\resolvers.js:33:11)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeProperties (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:208:34)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeObjects (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:228:34)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:353:24)
    at mergeSchemasWithFallback (file:///C:/Users/blusc/AppData/Local/Temp/grayjay-source-pietsmietde/scripts/merge-schemas.js:64:12)
    at async file:///C:/Users/blusc/AppData/Local/Temp/grayjay-source-pietsmietde/scripts/merge-schemas.js:84:26 {
  code: 'JSON_SCHEMA_MERGE_ERROR',
  schemas: [ [ 'null' ], [ 'null' ], [ 'string' ], [ 'string' ], [ 'string' ] ]
}
An error occurred: MergeError [JsonSchemaMergeError]: Failed to merge "type" keyword schemas.
    at hybridArraysIntersection (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\lib\resolvers.js:33:11)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeProperties (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:208:34)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeObjects (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:228:34)
    at _mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:310:5)
    at mergeSchemas (C:\Users\blusc\AppData\Local\Temp\grayjay-source-pietsmietde\node_modules\@fastify\merge-json-schemas\index.js:353:24)
    at mergeSchemasWithFallback (file:///C:/Users/blusc/AppData/Local/Temp/grayjay-source-pietsmietde/scripts/merge-schemas.js:64:12)
    at async file:///C:/Users/blusc/AppData/Local/Temp/grayjay-source-pietsmietde/scripts/merge-schemas.js:84:26 {
  code: 'JSON_SCHEMA_MERGE_ERROR',
  schemas: [ [ 'null' ], [ 'null' ], [ 'string' ], [ 'string' ], [ 'string' ] ]
}

What did you expect?

a merged.schema.json file in my directory

Context

Please read this entire template before posting any issue. If you ignore these instructions and post an issue here that does not follow the instructions, your issue might be closed, locked, and assigned the missing discussion label.

mcollina commented 2 months ago

Thanks for reporting!

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

Bluscream commented 2 months ago

I worked around this problem by generating a whole OpenAPI spec from scratch using a HAR file, which allowed me to extract all response schemas into one file.