Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Lint and validate JSON Schema docs #436

Closed
2 tasks
smoya opened this issue Oct 11, 2023 · 40 comments · Fixed by #452
Closed
2 tasks

[CI] Lint and validate JSON Schema docs #436

smoya opened this issue Oct 11, 2023 · 40 comments · Fixed by #452
Assignees
Labels
bounty AsyncAPI Bounty program related label bounty/2023-Q4 AsyncAPI Bounty program related label enhancement New feature or request level/medium AsyncAPI Bounty program related label released

Comments

@smoya
Copy link
Member

smoya commented Oct 11, 2023

Reason/Context

In order to follow an standard, but also ensuring any change won't break the JSON Schema documents, I suggest we add a new lint + validate action in our GH CI workflows that run on each PR and block the PR if JSON Schema files are not valid or following our requirements.

Description

Consider adding a new script to the package.json scripts section, that lints and validate JSON Schema files. Something like npm run lint or similar. Also could be included in npm test call. In that way, developers could run that command before pushing code but also during the execution of CI tests.

Run the following CI tasks on the JSON Schema files on each PR. It doesn't mean all of the following should run in different actions since most of them could be done just with one tool like Spectral.

  • JSON linting
  • Validate JSON Schema files structure
  • [ ] Add some rules (Spectral?) for validating things like checking all definitions come with their examples and description fields. Any others are welcome as well. Not included for the bounty program

Detailed context

  • This repository holds JSON Schema documents, which are used for validating AsyncAPI documents (transformed to JSON). The parsers mainly use those JSON Schemas (parser-js, for instance) to validate AsyncAPI documents.
  • The JSON Schemas used by the parsers and any other tool that wants to validate AsyncAPI documents are located in the /schemas dir.
  • Those schemas result from bundling several smaller schemas, the ones located under /definitions. Each of those small schemas usually refers to the validation related to just one object from the AsyncAPI spec, I.e., Message Object, Channel Object, etc.
  • When people need to change those schemas, they do not modify them directly under /schemas but rather modify a particular (sometimes several of them) file under /definitions. That's done this way to help developers focus on what they want to change and not deal with a big file containing the whole JSON Schema doc for the entire specification.
Technical details that concern this issue:
  • CI scripts that run on every Pull Request are these.
  • The step that says Run linter is not about lining JSON Schemas but linting Javascript code. So, it has nothing to do with the work we want to do here.
  • The latest step it runs is bundling all smaller schemas found under /definitions into the bundled big ones located in /schemas.
  • We should validate those (/schemas), meaning our JSON Schema linting script should run after the generation of assets (the actual last step).

To illustrate the details above, here is a simple flow chart. Note that the script we should create is represented in the Validate schemas from /schemas step.

flowchart TD
    PR[PR] -->|Update schemas under /definitions| CI(CI / GH Actions)
    CI --> bundle(Bundle definitions into /schemas)
    bundle --> compile(Validate schemas from /schemas)
    subgraph The new action we should build
        compile -->result{Are schemas valid?}
        result -->|Yes| ok[OK - exit code 0]
        result -->|NO| ko[KO - print validation errors + exit code 1]
    end
Loading
@smoya smoya added the enhancement New feature or request label Oct 11, 2023
Copy link
Member

derberg commented Oct 12, 2023

Yes, that would be lovely. Since spectral has some build it rules for AsyncAPI, maybe they have them for JSON schema, and it would make it much easier to use.

@derberg
Copy link
Member

derberg commented Oct 31, 2023

@smoya if we put it up under bounty, would you be available as maintainer to onboard and review with higher priority than other PRs (because of bounty constraints)?

@smoya
Copy link
Member Author

smoya commented Oct 31, 2023

@smoya if we put it up under bounty, would you be available as maintainer to onboard and review with higher priority than other PRs (because of bounty constraints)?

Sure! Let's do it 🙌

@smoya
Copy link
Member Author

smoya commented Oct 31, 2023

@derberg i think removing the spectral rules from the scope of this issue will help ensure the accomplishment for the bounty program.
Also, of course, increasing the level of detail of the job to be done.

Wdyt?

@princerajpoot20
Copy link
Member

princerajpoot20 commented Nov 2, 2023

@smoya @derberg I am interested in working on this issue.
I have some prior experience in CI/CD --> PR1, PR2 PR3

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 2, 2023

@derberg @smoya

I would like to give this issue a try. Although I don't have much knowledge about linting and JSON Schemas and how these things work, so it may take some time to learn about it.
It will be 'learning on the go' approach. (I think programming is supposed to be like this: learning by building things?)

Also, I'm having some experience with ci/cd as I've been working on this PR.

So if this approach falls under the bounty program's timeline, I'm happy to get started with it. 😄

Also, any reference/docs in your opinion as experienced developers to help me get started with this issue? 👀

Thank you!

@aeworxet aeworxet added bounty AsyncAPI Bounty program related label level/medium AsyncAPI Bounty program related label bounty/2023-Q4 AsyncAPI Bounty program related label labels Nov 6, 2023
@aeworxet
Copy link

aeworxet commented Nov 7, 2023

Bounty Issue's End of Life (EOL): 2024-02-29 23:59:59 UTC-12:00

@smoya
Copy link
Member Author

smoya commented Nov 7, 2023

As per the Prioritization of participants section in the Bounty program rules, you both @princerajpoot20 and @AnimeshKumar923 fall under the the 3rd option, where is the maintainer who has to decide who is going to participate in the program.

After carefully evaluating each individual case, I determine @AnimeshKumar923 becomes the participant for this issue in the Bounty Program 2023 Q4.
The reason that made me opt for @AnimeshKumar923 was the fact this issue won't be a thing in the program if @AnimeshKumar923 would not start this Slack thread a week ago. That ended up in @derberg pinging me to evaluate if I would include it in the program, and myself doing so.

Again, it is hard decision because you @princerajpoot20 are also a very potential candidate for this and someone I would also trust to accomplish this.

Thanks for your understanding! Congrats @AnimeshKumar923 🎉

@AnimeshKumar923
Copy link
Contributor

@smoya Thank you very much for giving me this opportunity! 🙇

I'm much eager to get started with a new challenge and take it to completion. I'll give the best from my side to the resolution of this issue. 🚀
Also, very grateful to @derberg for the recommendation. Thank you! 😁
Excited to be participating in the AsyncAPI Bounty Program! Let's GO! 🥳

@AnimeshKumar923
Copy link
Contributor

What will be the timeline for this issue? 👀 @aeworxet

@aeworxet
Copy link

aeworxet commented Nov 8, 2023

@smoya please make the assignment action for @AnimeshKumar923 so I can determine and post the timeline.

@smoya
Copy link
Member Author

smoya commented Nov 8, 2023

@smoya please make the assignment action for @AnimeshKumar923 so I can determine and post the timeline.

Issue assigned

@aeworxet
Copy link

aeworxet commented Nov 8, 2023

Bounty Issue's Timeline

Complexity Level Assignment date (by GitHub) Start date (by BP rules) End date (by BP rules) Draft PR submission Final PR submission Final PR merge
Medium 2023-11-08 2023-11-13 2023-12-22 2023-11-24 2023-12-08 2023-12-22
Please note that the dates given represent deadlines, not specific dates, so if the goal is reached sooner, it's better.

@AnimeshKumar923
Copy link
Contributor

@smoya Thank you for the assignment. I'll start working on it right away.

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 8, 2023

The approach that I've understood is that we can use this Spectral GH Action to lint JSON files.

@smoya

  • I want to ask that what is the difference between validating JSON Schema files structure and JSON linting?
  • Also, do we have a custom rule-set to provide for linting?

We have the following code example on how can we implement the GH Action 👇

name: Run Spectral on Pull Requests

on:
  - pull_request

jobs:
  build:
    name: Run Spectral
    runs-on: ubuntu-latest
    steps:
      # Check out the repository
      - uses: actions/checkout@v2

      # Run Spectral
      - uses: stoplightio/spectral-action@latest
        with:
          file_glob: 'doc/api/*.yaml'
          spectral_ruleset: # we have to provide a custom ruleset, if present

If we have a custom rule-set, we can provide that in the last spectral_ruleset field to lint.

Is my approach correct? 👀

@smoya
Copy link
Member Author

smoya commented Nov 9, 2023

The approach that I've understood is that we can use this Spectral GH Action to lint JSON files

Based on the following part found in the description of this issue:

Consider adding a new script to the package.json scripts section, that lints and validate JSON Schema files. Something like npm run lint or similar. Also could be included in npm test call. In that way, developers could run that command before pushing code but also during the execution of CI tests.

Ideally we should be able to run such a validation through npm run lint-schemas or similar command. That means we can't use any other GH action but rather call this command through our current GH actions.

Also, I would tell you to discard Spectral, at least by now, since you will need to deal with rulesets, something we don't want to do atm since we do not have any rule defined. We just want to lint the JSON Schemas ensuring they are proper JSON Schema files and don't contain typos and/or errors.
FYI, Spectral uses AJV under the hood, and I would recommend to we use it as well.

I want to ask that what is the difference between validating JSON Schema files structure and JSON linting?

  • By JSON linting I meant ensuring the files are valid JSON.
  • By JSON Schema files structure I meant ensuring the files are valid JSON Schema files.

In practice, by validating the files are JSON Schema files you are already validating they are proper JSON files, so you just need to focus on the second.

@AnimeshKumar923
Copy link
Contributor

Based on the following part found in the description of this issue:

Consider adding a new script to the package.json scripts section, that lints and validate JSON Schema files. Something like npm run lint or similar. Also could be included in npm test call. In that way, developers could run that command before pushing code but also during the execution of CI tests.

Ideally we should be able to run such a validation through npm run lint-schemas or similar command. That means we can't use any other GH action but rather call this command through our current GH actions.

Okay, I see...

Also, I would tell you to discard Spectral, at least by now, since you will need to deal with rulesets, something we don't want to do atm since we do not have any rule defined.

Got it. Won't proceed forward with the Spectral approach.

We just want to lint the JSON Schemas ensuring they are proper JSON Schema files and don't contain typos and/or errors. FYI, Spectral uses AJV under the hood, and I would recommend to we use it as well.

Okay, I'll take AJV an proceed forward with it.

* By **JSON linting** I meant ensuring the files are valid JSON.

* By **JSON Schema files structure** I meant ensuring the files are valid JSON Schema files.

In practice, by validating the files are JSON Schema files you are already validating they are proper JSON files, so you just need to focus on the second.

Okay, understood the difference. Thank you for your detailed response 😄

@AnimeshKumar923
Copy link
Contributor

@smoya

I tried installing AJV and ajv-cli on my local system and tinkered around using it. I followed your recommendations and read about AJV from the docs link you provided.

I assume we will validate the incoming schemas using the existing ones present in the schemas folder.

I tried validating it with same 1.0.0.json and 2.6.0.json files as data and schemas arguments and the results are below:

image

image

it says that error: no schema with key or ref "http://json-schema.org/draft-04/schema".
and error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema.
If I give the same schema as data to verify against it, it should be successful? (I'm making assumptions here)

There was some different versions of drafts mentioned here What version are we using here at the schemas folder?

the -s flag only takes one file at a time. -d can take multiple at once. How will we validate the incoming the schema? Will it be one-by-one with all the versions of .json files? or only the latest 2.6.0.json file?


I'm new to these topics and learning these so I will require a bit more guidance on how these works. Therefore, I hope you'll guide me through it, I may ask a lot of questions. Thank you! 😅

@smoya
Copy link
Member Author

smoya commented Nov 10, 2023

I tried validating it with same 1.0.0.json and 2.6.0.json files as data and schemas arguments

The validate command in AJV is used for validating JSON data against a JSON Schema doc. For example, in the case you want to validate a JSON object contains a particular property:

The JSON Schema doc. This will be the one AJV expects in the -s param:

{
  "type": "object",
  "properties": {
    "name": {
        "type": "string"
    }
  }
}

The JSON doc. This will be the one AJV expects in the -d param:

{
  "name": "Sergio"
}

However, since we want to validate the JSON Schema documents themselves, we do not have data to test against.
Instead, you might wanna use the ajv compile command, which only requires the -s parameter. That command validates the given JSON Schema doc itself.

it says that error: no schema with key or ref "http://json-schema.org/draft-04/schema".

The reason for the missing schema for draft-04 is that ajv doesn't support draft-04 by default anymore, instead you need to install an extra package, as mentioned in https://github.com/ajv-validator/ajv#ajv-json-schema-validator.

and error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema.

This is a known issue for us in fact. The point is that AJV includes by default several JSON Schema drafts, including the 07. Since our JSON Schema files under /schemas have Draft-07 JSON Schema embedded into the file itself, AJV complaints about having the same meta schema defined twice. As a fun fact, we do remove those default meta schemas from AJV in our parser-js. See https://github.com/asyncapi/parser-js/blob/master/src/ruleset/functions/documentStructure.ts#L62.

In order to do all of this, I would say we would need to create our own script (in ts/javascript) that executes the compile of AJV via the library instead of cli version. That script will be able to remove the extra Draft-07 schema from AJV, or include the Draft-04, etc etc. WDYT?

There was some different versions of drafts mentioned here What version are we using here at the schemas folder?

Depends on the version of the spec. Mainly Draft-07, but 1.x.x.json files use the Draft-04. But afaik, you can validate with Draft-07 as well since those meta schemas are included into our final schema files.

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 10, 2023

@smoya

However, since we want to validate the JSON Schema documents themselves, we do not have data to test against. Instead, you might wanna use the ajv compile command, which only requires the -s parameter. That command validates the given JSON Schema doc itself.

Okay, now it's more clear to me that we only have to validate the documents itself and not against any data input. Got it!

and error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema.

This is a known issue for us in fact. The point is that AJV includes by default several JSON Schema drafts, including the 07. Since our JSON Schema files under /schemas have Draft-07 JSON Schema embedded into the file itself, AJV complaints about having the same meta schema defined twice. As a fun fact, we do remove those default meta schemas from AJV in our parser-js. See https://github.com/asyncapi/parser-js/blob/master/src/ruleset/functions/documentStructure.ts#L62.

So this can be solved by integrating the parser-js in the script that we will develop?

In order to do all of this, I would say we would need to create our own script (in ts/javascript) that executes the compile of AJV via the library instead of cli version. That script will be able to remove the extra Draft-07 schema from AJV, or include the Draft-04, etc etc. WDYT?

Yes, we can follow this approach. It's getting a bit complex for me as I'm new to all these technologies but I'll manage somehow along the way... 😁

There was some different versions of drafts mentioned here What version are we using here at the schemas folder?

Depends on the version of the spec. Mainly Draft-07, but 1.x.x.json files use the Draft-04. But afaik, you can validate with Draft-07 as well since those meta schemas are included into our final schema files.

So, I guess using the Draft-07 will be enough to validate almost all schemas?

it says that error: no schema with key or ref "http://json-schema.org/draft-04/schema".

The reason for the missing schema for draft-04 is that ajv doesn't support draft-04 by default anymore, instead you need to install an extra package, as mentioned in https://github.com/ajv-validator/ajv#ajv-json-schema-validator.

I assume it will be solved if we validate using the method you mentioned... 👉 But afaik, you can validate with Draft-07 as well since those meta schemas are included into our final schema files. so we don't have to install the extra package?

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 10, 2023

@smoya

meta schemas are included into our final schema files.

What's the name of the final schema file? Is it this?

@AnimeshKumar923
Copy link
Contributor

Hey @smoya 👋

I did some more research and I have following updates...


I tried tinkering and developing the following script:

const Ajv = require('ajv');
const fs = require('fs').promises;
const path = require('path');
const { Parser } = require('@asyncapi/parser');


async function parsing(){
  try {
    // Start measuring time
    console.time('Parsing time');

    // Load your JSON Schema document
    const schemaDocument = await fs.readFile ('./schemas/2.6.0.json', 'utf-8');

    // Log the length of the schemaDocument to help diagnose if it's reading the file properly
    console.log('Length of schemaDocument:', schemaDocument.length);

    // const schema = JSON.parse(schemaDocument);



    const parser = new Parser();
    const { document } = await parser.parse(schemaDocument);
    
    if (document) {
      // => Example AsyncAPI specification
      console.log(document.info().title());
    }


    // Create an instance of Ajv
    const ajv = new Ajv();

    // Compile the schema
    const validate = ajv.compile(document); // schema -> document

    // Check if the schema is valid
    const isSchemaValid = validate(document); // schema -> document

    if (isSchemaValid) {
      console.log('JSON Schema is valid!');
    } else {
      console.error('JSON Schema is not valid:', validate.errors);
    }

    // Stop measuring time
    console.timeEnd('Parsing time');

  } catch (error) {
    console.error('Error parsing AsyncAPI document:', error.message);
  }
}

parsing();

I'm still learning javascript at the moment and at an early stage right now, so the majority of the above code I've generated through referencing docs and using ChatGPT in the process.

Referenced this example from parser-js docs for the below code portion 👇

const parser = new Parser();
    const { document } = await parser.parse(schemaDocument);
    
    if (document) {
      // => Example AsyncAPI specification
      console.log(document.info().title());
    }

This is the output 👇

image

  • The script is reading the file correctly hence showing the length of schemaDocument

  • The script took a long time to validate according to me and still was stuck hence I was compelled to force quit.

  • Is it normal to take this much time? One attempt took 3 mins and the other took ~8 mins 👀

  • How can I integrate the parser-js to implement your suggestion That script will be able to remove the extra Draft-07 schema from AJV ? After implementing this, I think we can remove this error 👉 error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema


Additional info:

  • Branch on which I'm testing right now.
  • Changes done in package.json after implementing the validation-script.
  • My system specs (for context) are:
CPU: Intel i3-3217U (4) @ 1.800GHz, 2 cores, 4 threads
GPU: Intel HD 4000 (iGPU)
Memory: 6 GB DDR3 @ 1600 MHz (5.8 GB usable out of 6 GB)
OS: Ubuntu 22.04.3 LTS x86_64
Kernel: 6.2.0-34-generic
Shell: zsh 5.8.1

@smoya
Copy link
Member Author

smoya commented Nov 13, 2023

Let me clarify concepts and hopefully help you to get more context:

  • This repository holds JSON Schema documents, which are used for validating AsyncAPI documents (transformed to JSON). The parsers mainly use those JSON Schemas (parser-js, for instance) to validate AsyncAPI documents.
  • The JSON Schemas used by the parsers and any other tool that wants to validate AsyncAPI documents are located in the /schemas dir.
  • Those schemas result from bundling several smaller schemas, the ones located under /definitions. Each of those small schemas usually refers to the validation related to just one object from the AsyncAPI spec, I.e., Message Object, Channel Object, etc.
  • When people need to change those schemas, they do not modify them directly under /schemas but rather modify a particular (sometimes several of them) file under /definitions. That's done this way to help developers focus on what they want to change and not deal with a big file containing the whole JSON Schema doc for the entire specification.

Now, getting back to the technical side of this issue, this is some more context you might need to know as well:

  • CI scripts that run on every Pull Request are these.
  • The step that says Run linter is not about lining JSON Schemas but linting Javascript code. So, it has nothing to do with the work we want to do here.
  • The latest step it runs is bundling all smaller schemas found under /definitions into the bundled big ones located in /schemas.
  • We should validate those (/schemas), meaning our JSON Schema linting script should run after the generation of assets (the actual last step).

@smoya
Copy link
Member Author

smoya commented Nov 13, 2023

After my previous comment trying to clarify some concepts, I'm gonna answer some of your previous questions. Most of them should be answered by my previous explanation, but if not, please do not hesitate to come back again.

So this can be solved by integrating the parser-js in the script that we will develop?

No. We can't use the Parser-JS because that parser only parses AsyncAPI documents. Examples of AsyncAPI documents can be found here.
We rather want to validate the JSON Schema documents found under /schemas dir on this right repository.

Yes, we can follow this approach. It's getting a bit complex for me as I'm new to all these technologies but I'll manage somehow along the way... 😁

You are heading in the right direction. I believe you are able to make it 🙌 . I'm here with you.

So, I guess using the Draft-07 will be enough to validate almost all schemas?

I'm not purely convinced about that. I think we should compile all with Draft-07 except for 1.0.0.*.json and 1.1.0.*.json schema documents, since they are written having in mind Draft-04. But in the case validating (compiling) them with Draft-07 give an OK, it is fine then to use Draft-07 for all 👍 .

How can I integrate the parser-js to implement your suggestion That script will be able to remove the extra Draft-07 schema from AJV

If you open any of our JSON Schema documents under /schemas, you will see that there is a key under definitions that belong to the Draft-07 (or 04 in the previous named cases) metaschema. For instance, see https://github.com/asyncapi/spec-json-schemas/blob/master/schemas/2.6.0.json#L821
That means the whole Draft-07 is embedded into our Schema (for reasons I won't explain here).

As AJV has already those metaschemas preloaded, it will collide with that one.

The hacky solution for this? To remove our own definition from the document prior to send the schema to validate (compile in our case).
This is what we do in Parser-js, in https://github.com/asyncapi/parser-js/blob/master/src/ruleset/functions/documentStructure.ts#L62

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 13, 2023

@smoya

After my previous comment trying to clarify some concepts, I'm gonna answer some of your previous questions. Most of them should be answered by my previous explanation, but if not, please do not hesitate to come back again.

Thank you for your in-depth explanations. I'll be asking more questions later on as I try to understand and figure out the problem and it's corresponding solution. Thank you for having patience with me 😅 🙇

So this can be solved by integrating the parser-js in the script that we will develop?

No. We can't use the Parser-JS because that parser only parses AsyncAPI documents. Examples of AsyncAPI documents can be found here. We rather want to validate the JSON Schema documents found under /schemas dir on this right repository.

Understood!

Yes, we can follow this approach. It's getting a bit complex for me as I'm new to all these technologies but I'll manage somehow along the way... 😁

You are heading in the right direction. I believe you are able to make it 🙌 . I'm here with you.

Thank you for believing in me. Sometimes it gets overwhelming while learning but it's good to be able to help and contribute here because of people like you supporting. 😀

So, I guess using the Draft-07 will be enough to validate almost all schemas?

I'm not purely convinced about that. I think we should compile all with Draft-07 except for 1.0.0.*.json and 1.1.0.*.json schema documents, since they are written having in mind Draft-04. But in the case validating (compiling) them with Draft-07 give an OK, it is fine then to use Draft-07 for all 👍 .

I used the search button and found out that files from 1.0.0.json upto 2.0.0-rc1.json are using Draft-04. Draft-07 usage starts from 2.0.0-rc2.json and goes till latest. So, I think we should compile all with Draft-07 except for files from 1.0.0.*.json to 2.0.0-rc1.json schema documents.
image

How can I integrate the parser-js to implement your suggestion That script will be able to remove the extra Draft-07 schema from AJV

If you open any of our JSON Schema documents under /schemas, you will see that there is a key under definitions that belong to the Draft-07 (or 04 in the previous named cases) metaschema. For instance, see https://github.com/asyncapi/spec-json-schemas/blob/master/schemas/2.6.0.json#L821 That means the whole Draft-07 is embedded into our Schema (for reasons I won't explain here).

Okay, I see... 👀

As AJV has already those metaschemas preloaded, it will collide with that one.

Yes, I think that's why this error is show error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema

The hacky solution for this? To remove our own definition from the document prior to send the schema to validate (compile in our case). This is what we do in Parser-js, in https://github.com/asyncapi/parser-js/blob/master/src/ruleset/functions/documentStructure.ts#L62

So, we have to somehow incorporate this method into the script that will be written so that it will remove the duplicates?
Am I correct?

@smoya
Copy link
Member Author

smoya commented Nov 13, 2023

So, I think we should compile all with Draft-07 except for files from 1.0.0.*.json to 2.0.0-rc1.json schema documents.

Makes sense 👍

Yes, I think that's why this error is show error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema

That's correct!

So, we have to somehow incorporate this method into the script that will be written so that it will remove the duplicates?
Am I correct?

Exactly!

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 13, 2023

So, I think we should compile all with Draft-07 except for files from 1.0.0.*.json to 2.0.0-rc1.json schema documents.

Makes sense 👍

Yes, I think that's why this error is show error: reference "http://json-schema.org/draft-07/schema" resolves to more than one schema

That's correct!

So, we have to somehow incorporate this method into the script that will be written so that it will remove the duplicates?
Am I correct?

Exactly!

Okay, I think I'm going in the right direction.
Now, first I'll have to learn a little bit TypeScript and then I'll do some learning and tinkering while referencing from your explanations. Will report to you with my studies... 😁 🫡

@AnimeshKumar923
Copy link
Contributor

AnimeshKumar923 commented Nov 14, 2023

UPDATE

@smoya

Tried developing the following script while getting familiarized with TypeScript and used the function that you mentioned above:

/*
 * We can run this script using ts-node which is installed .nvm/versions/node/v20.9.0/bin/ts-node 
 * 
 * The tsconfig.json file is required to run this script in TypeScript itself.
 * 
 * This script can be directly executed using the following command by going into scripts folder and then execute --> ```ts-node validate-schemas.ts```
*/



import Ajv, { ErrorObject } from 'ajv';
import specs from '@asyncapi/specs';

type AsyncAPIVersions = keyof typeof specs.schemas;

/************  Code from Asyncapi-parser-js/src/ruleset/functions/documentStructure.ts  *************/


function getCopyOfSchema(version: AsyncAPIVersions): Record<string, unknown> {
  return JSON.parse(JSON.stringify(specs.schemas[version])) as Record<string, unknown>;
}

const serializedSchemas = new Map<AsyncAPIVersions, Record<string, unknown>>();
function getSerializedSchema(version: AsyncAPIVersions): Record<string, unknown> {
  const schema = serializedSchemas.get(version);
  if (schema) {
    return schema;
  }
  
  // Copy to not operate on the original json schema - between imports (in different modules) we operate on this same schema.
  const copied = getCopyOfSchema(version) as { definitions: Record<string, unknown> };
  // Remove the meta schemas because they are already present within Ajv, and it's not possible to add duplicated schemas.
  delete copied.definitions['http://json-schema.org/draft-07/schema'];
  delete copied.definitions['http://json-schema.org/draft-04/schema'];
  
  serializedSchemas.set(version, copied);
  return copied;
}

/***************************************************************************************************/


const asyncApiVersionToUse: AsyncAPIVersions = '2.0.0'; // Replace with the actual version

// Get the serialized schema for the specified AsyncAPI version
const serializedSchema = getSerializedSchema(asyncApiVersionToUse);

// Create an instance of Ajv
const ajv: Ajv = new Ajv();

// Compile the schema
const validate = ajv.compile(serializedSchema);

// Check if the schema is valid
const isSchemaValid: boolean | PromiseLike<boolean> | undefined = validate(serializedSchema);

if (isSchemaValid) {
  console.log('JSON Schema is valid!');
} else {
  const validationErrors: ErrorObject[] | null | undefined = validate.errors;
  console.error('JSON Schema is not valid:', validationErrors);
}

Tried executing this script and getting the this error:

/home/animeshkumar923/Desktop/open-source/asyncapi-spec-json-schemas/node_modules/ajv/lib/vocabularies/format/format.ts:87
        throw new Error(unknownMsg())
              ^
Error: unknown format "uri" ignored in schema at path "#/properties/id"

I think it's referring to this line in the 2.0.0.json.

I don't know how to fix this. Can you please help me out?
Let me know if you need any more information from my side.

@AnimeshKumar923
Copy link
Contributor

@smoya Bringing your kind attention to this issue

@smoya
Copy link
Member Author

smoya commented Nov 17, 2023

Hi @AnimeshKumar923! Sorry for the delay.

I've reviewed your script and these are the list of issues I found:

  • We don't need the @asyncapi/specs pkg. What we want to validate are, in fact, those AsyncAPI Spec JSON Schema files way before publishing them into that NPM package.
  • You should load all the schemas from schemas repo directory, and compile each of them with AJV. Then fail or success based on the results.

I would say the code you have prior to the AJV instantiation should be removed and maybe replaced with the logic that loads the files and, in a loop, call the ajv.compile.

@smoya
Copy link
Member Author

smoya commented Nov 17, 2023

@AnimeshKumar923 I added a simple mermaid flow chart in the description of this issue. I tried to simplify the CI flow that surrounds this script.
Feel more than free to ask any questions here or via DM 👍

@AnimeshKumar923
Copy link
Contributor

@AnimeshKumar923 I added a simple mermaid flow chart in the description of this issue. I tried to simplify the CI flow that surrounds this script. Feel more than free to ask any questions here or via DM 👍

Thank you for your hard-work! 🙏 Will do.

@smoya
Copy link
Member Author

smoya commented Nov 21, 2023

For the record and for any other future mentee who reads this, @AnimeshKumar923 and I kept chatting via Slack DMs and videocalls. Sometimes synchronous communication works better when things are blocked. :)

@AnimeshKumar923
Copy link
Contributor

Sometimes I prefer Slack because it makes the work and discussions a bit more organized in my opinion. 😅

Sometimes synchronous communication works better when things are blocked. :)

It's working superbly I would say 🤩

@aeworxet
Copy link

Please provide an update to the PR.

@aeworxet
Copy link

Bounty Issue Completed 🎉

Please go to the AsyncAPI's OpenCollective page and submit an invoice for USD 200.00 with the subject Bounty spec-json-schemas#436, tag bounty.

@smoya
Copy link
Member Author

smoya commented Dec 13, 2023

Bounty Issue Completed 🎉

Please go to the AsyncAPI's OpenCollective page and submit an invoice for USD 200.00 with the subject Bounty spec-json-schemas#436, tag bounty.

So well deserved! 🚀

@AnimeshKumar923
Copy link
Contributor

Bounty Issue Completed 🎉

Please go to the AsyncAPI's OpenCollective page and submit an invoice for USD 200.00 with the subject Bounty spec-json-schemas#436, tag bounty.

So well deserved! 🚀

Grateful! 🙇

@asyncapi-bot
Copy link
Contributor

🎉 This issue has been resolved in version 6.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@aeworxet
Copy link

@asyncapi/bounty_team

@aeworxet aeworxet moved this to Completed in Bounty Program Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bounty AsyncAPI Bounty program related label bounty/2023-Q4 AsyncAPI Bounty program related label enhancement New feature or request level/medium AsyncAPI Bounty program related label released
Projects
Status: Completed
Development

Successfully merging a pull request may close this issue.

6 participants