Repository: asyncapi/parser-js
Pull request #610 (2022-09-14 12:52:57)

refactor: add fromURL and fromFile utils
<!--   Thank you for your contribution. Before you submit the pull request:
1. Follow contributing guidelines and make sure PR title follows Conventional Commits specification -> https://github.com/asyncapi/generator/blob/master/CONTRIBUTING.md
2. Test your changes and attach their results to the pull request.
3. Update the relevant documentation.
-->

**Description**

- add `fromURL` and `fromFile` utils:
  - `fromURL` is util which operates on HTTP sources - old `parseFromURL` function
  - `fromFile` is util which operates on filesystem sources.
- change `path` to the `source` in ParseOptions and ValidateOptions
- add tests
- update Readme.md

cc @smoya 

**Related issue(s)**
Part of #481 
Part of #482 

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=610)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=610)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=610)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=610&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=610&metric=duplicated_lines_density&view=list) No Duplication information


magicmatatjahu: /rtm

Patch:
diff --git a/README.md b/README.md
index 003cda9..7efcef6 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,24 @@ yarn add @asyncapi/parser
 
 The parser by default supports AsyncAPI Schema Format and JSON Schema Format for schemas. For additional formats, check [Custom schema parsers](#custom-schema-parsers) section.
 
+## Usage
+
+The package exposes the main class `Parser`, which has two main functions:
+
+- `validate()` - function that validates the passed AsyncAPI document. Returns array of all possible errors against the validation conditions.
+- `parse()` - function that validates the passed AsyncAPI document, and then if it's valid, parses the input. It returns an object that contains:
+  - `document` object, which is an parsed AsyncAPI document with [`AsyncAPIDocumentInterface`](./src/models/asyncapi.ts) API. If the schema is invalid against the validation conditions, the field has `undefined` value.
+  - `diagnostics` array that contains all possible errors against the validation conditions.
+- `registerSchemaParser()` - function that registers custom schema parsers. For more info, please check [Custom schema parsers](#custom-schema-parsers) section.
+
+Natively `Parser` class does not contain methods that operate on the source (AsyncAPI document) from a file or URL. However, the package exposes utils that make this possible:
+
+```ts
+import { fromURL, fromFile } from '@asyncapi/parser';
+```
+
+Check out the [examples](#examples) of using the above mentioned functionalities.
+
 ## Examples 
 
 ### Example with parsing
@@ -125,6 +143,26 @@ Head over to [asyncapi/openapi-schema-parser](https://www.github.com/asyncapi/op
 
 Head over to [asyncapi/raml-dt-schema-parser](https://www.github.com/asyncapi/raml-dt-schema-parser) for more information.
 
+### Example with performing actions on HTTP source
+
+```ts
+import { Parser, fromURL } from '@asyncapi/parser';
+
+const parser = new Parser();
+
+const { document, diagnostics } = await (await fromURL(parser, 'https://example.com/')).parse();
+```
+
+### Example with performing actions on file source
+
+```ts
+import { Parser, fromFile } from '@asyncapi/parser';
+
+const parser = new Parser();
+
+const { document, diagnostics } = await (await fromFile(parser, './asyncapi.yaml')).parse();
+```
+
 ### [Example with stringify and unstringify parsed document](#stringify)
 
 ```ts
diff --git a/package-lock.json b/package-lock.json
index a5cbe3f..bf9df1a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,9 +17,11 @@
         "@stoplight/spectral-rulesets": "^1.12.0",
         "ajv": "^8.11.0",
         "avsc": "^5.7.5",
+        "fetch-mock-jest": "^1.5.1",
         "js-yaml": "^4.1.0",
         "jsonpath-plus": "^7.2.0",
         "lodash": "^4.17.21",
+        "node-fetch": "2.6.7",
         "ramldt2jsonschema": "^1.2.3",
         "webapi-parser": "^0.5.0"
       },
@@ -35,6 +37,7 @@
         "@types/js-yaml": "^4.0.5",
         "@types/json-schema": "^7.0.11",
         "@types/lodash": "^4.14.179",
+        "@types/node-fetch": "^2.6.2",
         "@typescript-eslint/eslint-plugin": "^5.36.2",
         "@typescript-eslint/parser": "^5.36.2",
         "conventional-changelog-conventionalcommits": "^4.2.3",
@@ -77,7 +80,6 @@
     },
     "node_modules/@ampproject/remapping": {
       "version": "2.1.2",
-      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@jridgewell/trace-mapping": "^0.3.0"
@@ -93,7 +95,6 @@
     },
     "node_modules/@babel/code-frame": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/highlight": "^7.16.7"
@@ -104,7 +105,6 @@
     },
     "node_modules/@babel/compat-data": {
       "version": "7.17.0",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -112,7 +112,6 @@
     },
     "node_modules/@babel/core": {
       "version": "7.17.5",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "^2.1.0",
@@ -141,7 +140,6 @@
     },
     "node_modules/@babel/core/node_modules/semver": {
       "version": "6.3.0",
-      "dev": true,
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
@@ -149,7 +147,6 @@
     },
     "node_modules/@babel/generator": {
       "version": "7.17.3",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.17.0",
@@ -162,7 +159,6 @@
     },
     "node_modules/@babel/generator/node_modules/source-map": {
       "version": "0.5.7",
-      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.10.0"
@@ -170,7 +166,6 @@
     },
     "node_modules/@babel/helper-compilation-targets": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/compat-data": "^7.16.4",
@@ -187,7 +182,6 @@
     },
     "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
       "version": "6.3.0",
-      "dev": true,
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
@@ -195,7 +189,6 @@
     },
     "node_modules/@babel/helper-environment-visitor": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -206,7 +199,6 @@
     },
     "node_modules/@babel/helper-function-name": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/helper-get-function-arity": "^7.16.7",
@@ -219,7 +211,6 @@
     },
     "node_modules/@babel/helper-get-function-arity": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -230,7 +221,6 @@
     },
     "node_modules/@babel/helper-hoist-variables": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -241,7 +231,6 @@
     },
     "node_modules/@babel/helper-module-imports": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -252,7 +241,6 @@
     },
     "node_modules/@babel/helper-module-transforms": {
       "version": "7.17.6",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/helper-environment-visitor": "^7.16.7",
@@ -278,7 +266,6 @@
     },
     "node_modules/@babel/helper-simple-access": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -289,7 +276,6 @@
     },
     "node_modules/@babel/helper-split-export-declaration": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.16.7"
@@ -300,7 +286,6 @@
     },
     "node_modules/@babel/helper-validator-identifier": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -308,7 +293,6 @@
     },
     "node_modules/@babel/helper-validator-option": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -316,7 +300,6 @@
     },
     "node_modules/@babel/helpers": {
       "version": "7.17.2",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/template": "^7.16.7",
@@ -329,7 +312,6 @@
     },
     "node_modules/@babel/highlight": {
       "version": "7.16.10",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/helper-validator-identifier": "^7.16.7",
@@ -342,7 +324,6 @@
     },
     "node_modules/@babel/parser": {
       "version": "7.17.3",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -516,7 +497,6 @@
     },
     "node_modules/@babel/runtime": {
       "version": "7.19.0",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "regenerator-runtime": "^0.13.4"
@@ -539,7 +519,6 @@
     },
     "node_modules/@babel/template": {
       "version": "7.16.7",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "^7.16.7",
@@ -552,7 +531,6 @@
     },
     "node_modules/@babel/traverse": {
       "version": "7.17.3",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "^7.16.7",
@@ -572,7 +550,6 @@
     },
     "node_modules/@babel/traverse/node_modules/globals": {
       "version": "11.12.0",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -580,7 +557,6 @@
     },
     "node_modules/@babel/types": {
       "version": "7.17.0",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/helper-validator-identifier": "^7.16.7",
@@ -1916,7 +1892,6 @@
     },
     "node_modules/@jridgewell/resolve-uri": {
       "version": "3.0.5",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.0.0"
@@ -1943,12 +1918,10 @@
     },
     "node_modules/@jridgewell/sourcemap-codec": {
       "version": "1.4.11",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@jridgewell/trace-mapping": {
       "version": "0.3.15",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.0.3",
@@ -2910,6 +2883,16 @@
       "version": "17.0.21",
       "license": "MIT"
     },
+    "node_modules/@types/node-fetch": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz",
+      "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "form-data": "^3.0.0"
+      }
+    },
     "node_modules/@types/normalize-package-data": {
       "version": "2.4.0",
       "dev": true,
@@ -3529,7 +3512,6 @@
     },
     "node_modules/ansi-styles": {
       "version": "3.2.1",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "color-convert": "^1.9.0"
@@ -3660,6 +3642,12 @@
         "astring": "bin/astring"
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "dev": true
+    },
     "node_modules/at-least-node": {
       "version": "1.0.0",
       "dev": true,
@@ -3817,7 +3805,6 @@
     },
     "node_modules/browserslist": {
       "version": "4.21.3",
-      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -3933,7 +3920,6 @@
     },
     "node_modules/caniuse-lite": {
       "version": "1.0.30001387",
-      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -3960,7 +3946,6 @@
     },
     "node_modules/chalk": {
       "version": "2.4.2",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ansi-styles": "^3.2.1",
@@ -4094,7 +4079,6 @@
     },
     "node_modules/color-convert": {
       "version": "1.9.3",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "color-name": "1.1.3"
@@ -4102,7 +4086,6 @@
     },
     "node_modules/color-name": {
       "version": "1.1.3",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/colorette": {
@@ -4119,6 +4102,18 @@
         "node": ">=0.1.90"
       }
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/commander": {
       "version": "5.1.0",
       "license": "MIT",
@@ -4250,12 +4245,21 @@
     },
     "node_modules/convert-source-map": {
       "version": "1.8.0",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "safe-buffer": "~5.1.1"
       }
     },
+    "node_modules/core-js": {
+      "version": "3.25.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.1.tgz",
+      "integrity": "sha512-sr0FY4lnO1hkQ4gLDr24K0DGnweGO1QwSj5BpfQjpSJPdqWalja4cTps29Y/PJVG/P7FYlPDkH3hO+Tr0CvDgQ==",
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
     "node_modules/core-js-pure": {
       "version": "3.25.0",
       "dev": true,
@@ -4392,7 +4396,6 @@
     },
     "node_modules/debug": {
       "version": "4.3.4",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ms": "2.1.2"
@@ -4474,6 +4477,15 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/dependency-graph": {
       "version": "0.11.0",
       "license": "MIT",
@@ -4581,7 +4593,6 @@
     },
     "node_modules/electron-to-chromium": {
       "version": "1.4.242",
-      "dev": true,
       "license": "ISC"
     },
     "node_modules/emittery": {
@@ -4774,7 +4785,6 @@
     },
     "node_modules/escalade": {
       "version": "3.1.1",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6"
@@ -4782,7 +4792,6 @@
     },
     "node_modules/escape-string-regexp": {
       "version": "1.0.5",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=0.8.0"
@@ -5805,6 +5814,84 @@
         "pend": "~1.2.0"
       }
     },
+    "node_modules/fetch-mock": {
+      "version": "9.11.0",
+      "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.11.0.tgz",
+      "integrity": "sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==",
+      "dependencies": {
+        "@babel/core": "^7.0.0",
+        "@babel/runtime": "^7.0.0",
+        "core-js": "^3.0.0",
+        "debug": "^4.1.1",
+        "glob-to-regexp": "^0.4.0",
+        "is-subset": "^0.1.1",
+        "lodash.isequal": "^4.5.0",
+        "path-to-regexp": "^2.2.1",
+        "querystring": "^0.2.0",
+        "whatwg-url": "^6.5.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      },
+      "funding": {
+        "type": "charity",
+        "url": "https://www.justgiving.com/refugee-support-europe"
+      },
+      "peerDependencies": {
+        "node-fetch": "*"
+      },
+      "peerDependenciesMeta": {
+        "node-fetch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fetch-mock-jest": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/fetch-mock-jest/-/fetch-mock-jest-1.5.1.tgz",
+      "integrity": "sha512-+utwzP8C+Pax1GSka3nFXILWMY3Er2L+s090FOgqVNrNCPp0fDqgXnAHAJf12PLHi0z4PhcTaZNTz8e7K3fjqQ==",
+      "dependencies": {
+        "fetch-mock": "^9.11.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      },
+      "funding": {
+        "type": "charity",
+        "url": "https://www.justgiving.com/refugee-support-europe"
+      },
+      "peerDependencies": {
+        "node-fetch": "*"
+      },
+      "peerDependenciesMeta": {
+        "node-fetch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fetch-mock/node_modules/tr46": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+      "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/fetch-mock/node_modules/webidl-conversions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
+    },
+    "node_modules/fetch-mock/node_modules/whatwg-url": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+      "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+      "dependencies": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^1.0.1",
+        "webidl-conversions": "^4.0.2"
+      }
+    },
     "node_modules/figures": {
       "version": "3.2.0",
       "dev": true,
@@ -5891,6 +5978,20 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/form-data": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/from2": {
       "version": "2.3.0",
       "dev": true,
@@ -5971,7 +6072,6 @@
     },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -6093,8 +6193,7 @@
     "node_modules/glob-to-regexp": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
-      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
-      "dev": true
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
     },
     "node_modules/globals": {
       "version": "13.17.0",
@@ -6271,7 +6370,6 @@
     },
     "node_modules/has-flag": {
       "version": "3.0.0",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -6726,6 +6824,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-subset": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+      "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw=="
+    },
     "node_modules/is-symbol": {
       "version": "1.0.4",
       "license": "MIT",
@@ -9379,7 +9482,6 @@
     },
     "node_modules/js-tokens": {
       "version": "4.0.0",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/js-yaml": {
@@ -9408,7 +9510,6 @@
     },
     "node_modules/jsesc": {
       "version": "2.5.2",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "jsesc": "bin/jsesc"
@@ -9468,7 +9569,6 @@
     },
     "node_modules/json5": {
       "version": "2.2.0",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "minimist": "^1.2.5"
@@ -9699,6 +9799,11 @@
       "version": "4.4.2",
       "license": "MIT"
     },
+    "node_modules/lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+    },
     "node_modules/lodash.ismatch": {
       "version": "4.4.0",
       "dev": true,
@@ -9733,6 +9838,11 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
+    },
     "node_modules/lodash.template": {
       "version": "4.5.0",
       "dev": true,
@@ -10114,7 +10224,6 @@
     },
     "node_modules/minimist": {
       "version": "1.2.6",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/minimist-options": {
@@ -10197,7 +10306,6 @@
     },
     "node_modules/ms": {
       "version": "2.1.2",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/natural-compare": {
@@ -10251,7 +10359,8 @@
     },
     "node_modules/node-fetch": {
       "version": "2.6.7",
-      "license": "MIT",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
       "dependencies": {
         "whatwg-url": "^5.0.0"
       },
@@ -10274,7 +10383,6 @@
     },
     "node_modules/node-releases": {
       "version": "2.0.6",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/normalize-package-data": {
@@ -15200,6 +15308,11 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/path-to-regexp": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
+      "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w=="
+    },
     "node_modules/pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -15208,7 +15321,6 @@
     },
     "node_modules/picocolors": {
       "version": "1.0.0",
-      "dev": true,
       "license": "ISC"
     },
     "node_modules/picomatch": {
@@ -15469,6 +15581,15 @@
         "teleport": ">=0.2.0"
       }
     },
+    "node_modules/querystring": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
+      "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==",
+      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "dev": true,
@@ -15745,7 +15866,6 @@
     },
     "node_modules/regenerator-runtime": {
       "version": "0.13.9",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/regexp-tree": {
@@ -15937,7 +16057,6 @@
     },
     "node_modules/safe-buffer": {
       "version": "5.1.2",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/safe-regex": {
@@ -16464,7 +16583,6 @@
     },
     "node_modules/supports-color": {
       "version": "5.5.0",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "has-flag": "^3.0.0"
@@ -16753,7 +16871,6 @@
     },
     "node_modules/to-fast-properties": {
       "version": "2.0.0",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -16797,7 +16914,8 @@
     },
     "node_modules/tr46": {
       "version": "0.0.3",
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
     },
     "node_modules/traverse": {
       "version": "0.6.6",
@@ -17108,7 +17226,6 @@
     },
     "node_modules/update-browserslist-db": {
       "version": "1.0.7",
-      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -17230,7 +17347,8 @@
     },
     "node_modules/webidl-conversions": {
       "version": "3.0.1",
-      "license": "BSD-2-Clause"
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
     },
     "node_modules/webpack": {
       "version": "5.74.0",
@@ -17504,7 +17622,8 @@
     },
     "node_modules/whatwg-url": {
       "version": "5.0.0",
-      "license": "MIT",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
       "dependencies": {
         "tr46": "~0.0.3",
         "webidl-conversions": "^3.0.0"
@@ -17706,7 +17825,6 @@
   "dependencies": {
     "@ampproject/remapping": {
       "version": "2.1.2",
-      "dev": true,
       "requires": {
         "@jridgewell/trace-mapping": "^0.3.0"
       }
@@ -17718,18 +17836,15 @@
     },
     "@babel/code-frame": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/highlight": "^7.16.7"
       }
     },
     "@babel/compat-data": {
-      "version": "7.17.0",
-      "dev": true
+      "version": "7.17.0"
     },
     "@babel/core": {
       "version": "7.17.5",
-      "dev": true,
       "requires": {
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.16.7",
@@ -17749,14 +17864,12 @@
       },
       "dependencies": {
         "semver": {
-          "version": "6.3.0",
-          "dev": true
+          "version": "6.3.0"
         }
       }
     },
     "@babel/generator": {
       "version": "7.17.3",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.17.0",
         "jsesc": "^2.5.1",
@@ -17764,14 +17877,12 @@
       },
       "dependencies": {
         "source-map": {
-          "version": "0.5.7",
-          "dev": true
+          "version": "0.5.7"
         }
       }
     },
     "@babel/helper-compilation-targets": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/compat-data": "^7.16.4",
         "@babel/helper-validator-option": "^7.16.7",
@@ -17780,21 +17891,18 @@
       },
       "dependencies": {
         "semver": {
-          "version": "6.3.0",
-          "dev": true
+          "version": "6.3.0"
         }
       }
     },
     "@babel/helper-environment-visitor": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-function-name": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/helper-get-function-arity": "^7.16.7",
         "@babel/template": "^7.16.7",
@@ -17803,28 +17911,24 @@
     },
     "@babel/helper-get-function-arity": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-hoist-variables": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-module-imports": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-module-transforms": {
       "version": "7.17.6",
-      "dev": true,
       "requires": {
         "@babel/helper-environment-visitor": "^7.16.7",
         "@babel/helper-module-imports": "^7.16.7",
@@ -17842,29 +17946,24 @@
     },
     "@babel/helper-simple-access": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-split-export-declaration": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/types": "^7.16.7"
       }
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.16.7",
-      "dev": true
+      "version": "7.16.7"
     },
     "@babel/helper-validator-option": {
-      "version": "7.16.7",
-      "dev": true
+      "version": "7.16.7"
     },
     "@babel/helpers": {
       "version": "7.17.2",
-      "dev": true,
       "requires": {
         "@babel/template": "^7.16.7",
         "@babel/traverse": "^7.17.0",
@@ -17873,7 +17972,6 @@
     },
     "@babel/highlight": {
       "version": "7.16.10",
-      "dev": true,
       "requires": {
         "@babel/helper-validator-identifier": "^7.16.7",
         "chalk": "^2.0.0",
@@ -17881,8 +17979,7 @@
       }
     },
     "@babel/parser": {
-      "version": "7.17.3",
-      "dev": true
+      "version": "7.17.3"
     },
     "@babel/plugin-syntax-async-generators": {
       "version": "7.8.4",
@@ -17984,7 +18081,6 @@
     },
     "@babel/runtime": {
       "version": "7.19.0",
-      "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.4"
       }
@@ -17999,7 +18095,6 @@
     },
     "@babel/template": {
       "version": "7.16.7",
-      "dev": true,
       "requires": {
         "@babel/code-frame": "^7.16.7",
         "@babel/parser": "^7.16.7",
@@ -18008,7 +18103,6 @@
     },
     "@babel/traverse": {
       "version": "7.17.3",
-      "dev": true,
       "requires": {
         "@babel/code-frame": "^7.16.7",
         "@babel/generator": "^7.17.3",
@@ -18023,14 +18117,12 @@
       },
       "dependencies": {
         "globals": {
-          "version": "11.12.0",
-          "dev": true
+          "version": "11.12.0"
         }
       }
     },
     "@babel/types": {
       "version": "7.17.0",
-      "dev": true,
       "requires": {
         "@babel/helper-validator-identifier": "^7.16.7",
         "to-fast-properties": "^2.0.0"
@@ -18922,8 +19014,7 @@
       }
     },
     "@jridgewell/resolve-uri": {
-      "version": "3.0.5",
-      "dev": true
+      "version": "3.0.5"
     },
     "@jridgewell/set-array": {
       "version": "1.1.2",
@@ -18942,12 +19033,10 @@
       }
     },
     "@jridgewell/sourcemap-codec": {
-      "version": "1.4.11",
-      "dev": true
+      "version": "1.4.11"
     },
     "@jridgewell/trace-mapping": {
       "version": "0.3.15",
-      "dev": true,
       "requires": {
         "@jridgewell/resolve-uri": "^3.0.3",
         "@jridgewell/sourcemap-codec": "^1.4.10"
@@ -19656,6 +19745,16 @@
     "@types/node": {
       "version": "17.0.21"
     },
+    "@types/node-fetch": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz",
+      "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "form-data": "^3.0.0"
+      }
+    },
     "@types/normalize-package-data": {
       "version": "2.4.0",
       "dev": true
@@ -20080,7 +20179,6 @@
     },
     "ansi-styles": {
       "version": "3.2.1",
-      "dev": true,
       "requires": {
         "color-convert": "^1.9.0"
       }
@@ -20163,6 +20261,12 @@
     "astring": {
       "version": "1.8.3"
     },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "dev": true
+    },
     "at-least-node": {
       "version": "1.0.0",
       "dev": true
@@ -20274,7 +20378,6 @@
     },
     "browserslist": {
       "version": "4.21.3",
-      "dev": true,
       "requires": {
         "caniuse-lite": "^1.0.30001370",
         "electron-to-chromium": "^1.4.202",
@@ -20334,8 +20437,7 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001387",
-      "dev": true
+      "version": "1.0.30001387"
     },
     "cardinal": {
       "version": "2.1.1",
@@ -20347,7 +20449,6 @@
     },
     "chalk": {
       "version": "2.4.2",
-      "dev": true,
       "requires": {
         "ansi-styles": "^3.2.1",
         "escape-string-regexp": "^1.0.5",
@@ -20439,14 +20540,12 @@
     },
     "color-convert": {
       "version": "1.9.3",
-      "dev": true,
       "requires": {
         "color-name": "1.1.3"
       }
     },
     "color-name": {
-      "version": "1.1.3",
-      "dev": true
+      "version": "1.1.3"
     },
     "colorette": {
       "version": "2.0.19",
@@ -20458,6 +20557,15 @@
       "version": "1.0.3",
       "dev": true
     },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
     "commander": {
       "version": "5.1.0"
     },
@@ -20550,11 +20658,15 @@
     },
     "convert-source-map": {
       "version": "1.8.0",
-      "dev": true,
       "requires": {
         "safe-buffer": "~5.1.1"
       }
     },
+    "core-js": {
+      "version": "3.25.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.1.tgz",
+      "integrity": "sha512-sr0FY4lnO1hkQ4gLDr24K0DGnweGO1QwSj5BpfQjpSJPdqWalja4cTps29Y/PJVG/P7FYlPDkH3hO+Tr0CvDgQ=="
+    },
     "core-js-pure": {
       "version": "3.25.0",
       "dev": true
@@ -20642,7 +20754,6 @@
     },
     "debug": {
       "version": "4.3.4",
-      "dev": true,
       "requires": {
         "ms": "2.1.2"
       }
@@ -20688,6 +20799,12 @@
         "object-keys": "^1.1.1"
       }
     },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "dev": true
+    },
     "dependency-graph": {
       "version": "0.11.0"
     },
@@ -20758,8 +20875,7 @@
       }
     },
     "electron-to-chromium": {
-      "version": "1.4.242",
-      "dev": true
+      "version": "1.4.242"
     },
     "emittery": {
       "version": "0.10.2",
@@ -20893,12 +21009,10 @@
       }
     },
     "escalade": {
-      "version": "3.1.1",
-      "dev": true
+      "version": "3.1.1"
     },
     "escape-string-regexp": {
-      "version": "1.0.5",
-      "dev": true
+      "version": "1.0.5"
     },
     "eslint": {
       "version": "8.23.0",
@@ -21558,6 +21672,56 @@
         "pend": "~1.2.0"
       }
     },
+    "fetch-mock": {
+      "version": "9.11.0",
+      "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.11.0.tgz",
+      "integrity": "sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==",
+      "requires": {
+        "@babel/core": "^7.0.0",
+        "@babel/runtime": "^7.0.0",
+        "core-js": "^3.0.0",
+        "debug": "^4.1.1",
+        "glob-to-regexp": "^0.4.0",
+        "is-subset": "^0.1.1",
+        "lodash.isequal": "^4.5.0",
+        "path-to-regexp": "^2.2.1",
+        "querystring": "^0.2.0",
+        "whatwg-url": "^6.5.0"
+      },
+      "dependencies": {
+        "tr46": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+          "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+          "requires": {
+            "punycode": "^2.1.0"
+          }
+        },
+        "webidl-conversions": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+          "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
+        },
+        "whatwg-url": {
+          "version": "6.5.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+          "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+          "requires": {
+            "lodash.sortby": "^4.7.0",
+            "tr46": "^1.0.1",
+            "webidl-conversions": "^4.0.2"
+          }
+        }
+      }
+    },
+    "fetch-mock-jest": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/fetch-mock-jest/-/fetch-mock-jest-1.5.1.tgz",
+      "integrity": "sha512-+utwzP8C+Pax1GSka3nFXILWMY3Er2L+s090FOgqVNrNCPp0fDqgXnAHAJf12PLHi0z4PhcTaZNTz8e7K3fjqQ==",
+      "requires": {
+        "fetch-mock": "^9.11.0"
+      }
+    },
     "figures": {
       "version": "3.2.0",
       "dev": true,
@@ -21609,6 +21773,17 @@
       "version": "1.0.2",
       "dev": true
     },
+    "form-data": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
     "from2": {
       "version": "2.3.0",
       "dev": true,
@@ -21662,8 +21837,7 @@
       "version": "1.2.3"
     },
     "gensync": {
-      "version": "1.0.0-beta.2",
-      "dev": true
+      "version": "1.0.0-beta.2"
     },
     "get-caller-file": {
       "version": "2.0.5",
@@ -21743,8 +21917,7 @@
     "glob-to-regexp": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
-      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
-      "dev": true
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
     },
     "globals": {
       "version": "13.17.0",
@@ -21859,8 +22032,7 @@
       "version": "1.0.2"
     },
     "has-flag": {
-      "version": "3.0.0",
-      "dev": true
+      "version": "3.0.0"
     },
     "has-property-descriptors": {
       "version": "1.0.0",
@@ -22108,6 +22280,11 @@
         "has-tostringtag": "^1.0.0"
       }
     },
+    "is-subset": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+      "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw=="
+    },
     "is-symbol": {
       "version": "1.0.4",
       "requires": {
@@ -23851,8 +24028,7 @@
       }
     },
     "js-tokens": {
-      "version": "4.0.0",
-      "dev": true
+      "version": "4.0.0"
     },
     "js-yaml": {
       "version": "4.1.0",
@@ -23869,8 +24045,7 @@
       "version": "1.3.0"
     },
     "jsesc": {
-      "version": "2.5.2",
-      "dev": true
+      "version": "2.5.2"
     },
     "json-parse-better-errors": {
       "version": "1.0.2",
@@ -23916,7 +24091,6 @@
     },
     "json5": {
       "version": "2.2.0",
-      "dev": true,
       "requires": {
         "minimist": "^1.2.5"
       }
@@ -24067,6 +24241,11 @@
     "lodash.get": {
       "version": "4.4.2"
     },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+    },
     "lodash.ismatch": {
       "version": "4.4.0",
       "dev": true
@@ -24094,6 +24273,11 @@
       "version": "4.1.1",
       "dev": true
     },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
+    },
     "lodash.template": {
       "version": "4.5.0",
       "dev": true,
@@ -24337,8 +24521,7 @@
       }
     },
     "minimist": {
-      "version": "1.2.6",
-      "dev": true
+      "version": "1.2.6"
     },
     "minimist-options": {
       "version": "4.1.0",
@@ -24396,8 +24579,7 @@
       "dev": true
     },
     "ms": {
-      "version": "2.1.2",
-      "dev": true
+      "version": "2.1.2"
     },
     "natural-compare": {
       "version": "1.4.0",
@@ -24439,6 +24621,8 @@
     },
     "node-fetch": {
       "version": "2.6.7",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
       "requires": {
         "whatwg-url": "^5.0.0"
       }
@@ -24448,8 +24632,7 @@
       "dev": true
     },
     "node-releases": {
-      "version": "2.0.6",
-      "dev": true
+      "version": "2.0.6"
     },
     "normalize-package-data": {
       "version": "2.5.0",
@@ -28154,6 +28337,11 @@
       "version": "1.0.7",
       "dev": true
     },
+    "path-to-regexp": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
+      "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w=="
+    },
     "pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -28161,8 +28349,7 @@
       "dev": true
     },
     "picocolors": {
-      "version": "1.0.0",
-      "dev": true
+      "version": "1.0.0"
     },
     "picomatch": {
       "version": "2.3.1",
@@ -28321,6 +28508,11 @@
       "version": "1.5.1",
       "dev": true
     },
+    "querystring": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
+      "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg=="
+    },
     "queue-microtask": {
       "version": "1.2.3",
       "dev": true
@@ -28501,8 +28693,7 @@
       }
     },
     "regenerator-runtime": {
-      "version": "0.13.9",
-      "dev": true
+      "version": "0.13.9"
     },
     "regexp-tree": {
       "version": "0.1.24",
@@ -28597,8 +28788,7 @@
       }
     },
     "safe-buffer": {
-      "version": "5.1.2",
-      "dev": true
+      "version": "5.1.2"
     },
     "safe-regex": {
       "version": "2.1.1",
@@ -28973,7 +29163,6 @@
     },
     "supports-color": {
       "version": "5.5.0",
-      "dev": true,
       "requires": {
         "has-flag": "^3.0.0"
       }
@@ -29166,8 +29355,7 @@
       "dev": true
     },
     "to-fast-properties": {
-      "version": "2.0.0",
-      "dev": true
+      "version": "2.0.0"
     },
     "to-object-path": {
       "version": "0.3.0",
@@ -29194,7 +29382,9 @@
       "dev": true
     },
     "tr46": {
-      "version": "0.0.3"
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
     },
     "traverse": {
       "version": "0.6.6",
@@ -29394,7 +29584,6 @@
     },
     "update-browserslist-db": {
       "version": "1.0.7",
-      "dev": true,
       "requires": {
         "escalade": "^3.1.1",
         "picocolors": "^1.0.0"
@@ -29479,7 +29668,9 @@
       }
     },
     "webidl-conversions": {
-      "version": "3.0.1"
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
     },
     "webpack": {
       "version": "5.74.0",
@@ -29658,6 +29849,8 @@
     },
     "whatwg-url": {
       "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
       "requires": {
         "tr46": "~0.0.3",
         "webidl-conversions": "^3.0.0"
diff --git a/package.json b/package.json
index 95efe4f..c07d62c 100644
--- a/package.json
+++ b/package.json
@@ -44,9 +44,11 @@
     "@stoplight/spectral-rulesets": "^1.12.0",
     "ajv": "^8.11.0",
     "avsc": "^5.7.5",
+    "fetch-mock-jest": "^1.5.1",
     "js-yaml": "^4.1.0",
     "jsonpath-plus": "^7.2.0",
     "lodash": "^4.17.21",
+    "node-fetch": "2.6.7",
     "ramldt2jsonschema": "^1.2.3",
     "webapi-parser": "^0.5.0"
   },
@@ -62,6 +64,7 @@
     "@types/js-yaml": "^4.0.5",
     "@types/json-schema": "^7.0.11",
     "@types/lodash": "^4.14.179",
+    "@types/node-fetch": "^2.6.2",
     "@typescript-eslint/eslint-plugin": "^5.36.2",
     "@typescript-eslint/parser": "^5.36.2",
     "conventional-changelog-conventionalcommits": "^4.2.3",
@@ -120,4 +123,4 @@
       ]
     ]
   }
-}
\ No newline at end of file
+}
diff --git a/src/from.ts b/src/from.ts
new file mode 100644
index 0000000..d1246e6
--- /dev/null
+++ b/src/from.ts
@@ -0,0 +1,58 @@
+import { readFile } from 'fs/promises';
+
+import type { RequestInit } from 'node-fetch';
+import type { Parser } from './parser';
+import type { ParseInput, ParseOptions, ParseOutput } from './parse';
+import type { ValidateOptions, ValidateOutput } from './lint';
+
+interface FromResult {
+  parse: (options?: ParseOptions) => Promise<ParseOutput>;
+  validate: (options?: ValidateOptions) => Promise<ValidateOutput>;
+}
+
+export function fromURL(parser: Parser, source: string, options?: RequestInit): FromResult {
+  async function fetchUrl(): Promise<ParseInput> {
+    const fetchFn = await getFetch();
+    return (await fetchFn(source, options as any)).text();
+  }
+
+  return {
+    async parse(options: ParseOptions = {}) {
+      const schema = await fetchUrl();
+      return parser.parse(schema, { ...options, source });
+    },
+    async validate(options: ValidateOptions = {}) {
+      const schema = await fetchUrl();
+      return parser.validate(schema, { ...options, source });
+    }
+  };
+}
+
+export function fromFile(parser: Parser, source: string, options?: Parameters<typeof readFile>[1]): FromResult {
+  async function readFileFn(): Promise<ParseInput> {
+    return (await readFile(source, options)).toString();
+  }
+
+  return {
+    async parse(options: ParseOptions = {}) {
+      const schema = await readFileFn();
+      return parser.parse(schema, { ...options, source });
+    },
+    async validate(options: ValidateOptions = {}) {
+      const schema = await readFileFn();
+      return parser.validate(schema, { ...options, source });
+    }
+  };
+}
+
+let __fetchFn: typeof fetch | undefined;
+async function getFetch(): Promise<typeof fetch> {
+  if (__fetchFn) {
+    return __fetchFn;
+  }
+
+  if (typeof fetch === 'undefined') {
+    return __fetchFn = (await import('node-fetch')).default as unknown as typeof fetch;
+  }
+  return (__fetchFn = fetch);
+}
diff --git a/src/index.ts b/src/index.ts
index 88ee5d7..cac2d23 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,7 +4,7 @@ export * from './models';
 
 export { Parser };
 export { stringify, unstringify } from './stringify';
-export { AsyncAPISchemaParser } from './schema-parser/asyncapi-schema-parser';
+export { fromURL, fromFile } from './from';
 
 export { AsyncAPIDocument as OldAsyncAPIDocument } from './old-api/asyncapi';
 export { migrateToOldAPI } from './old-api/migrator';
diff --git a/src/lint.ts b/src/lint.ts
index 07aaef5..a79c140 100644
--- a/src/lint.ts
+++ b/src/lint.ts
@@ -14,7 +14,7 @@ export interface LintOptions extends IRunOpts {
 }
 
 export interface ValidateOptions extends IRunOpts {
-  path?: string;
+  source?: string;
   allowedSeverity?: {
     warning?: boolean;
   };
@@ -39,7 +39,7 @@ export async function validate(parser: Parser, asyncapi: ParseInput, options: Va
   }
 
   const stringifiedDocument = normalizeInput(asyncapi as Exclude<ParseInput, AsyncAPIDocumentInterface>);
-  const document = new Document(stringifiedDocument, Yaml, options.path);
+  const document = new Document(stringifiedDocument, Yaml, options.source);
 
   const { allowedSeverity } = normalizeOptions(options);
   // eslint-disable-next-line prefer-const
diff --git a/src/parse.ts b/src/parse.ts
index 00e84ce..4e73fb0 100644
--- a/src/parse.ts
+++ b/src/parse.ts
@@ -14,22 +14,21 @@ import type { MaybeAsyncAPI, Diagnostic } from './types';
 
 export type ParseInput = string | MaybeAsyncAPI | AsyncAPIDocumentInterface;
 export interface ParseOutput {
-  source: ParseInput;
   document: AsyncAPIDocumentInterface | undefined;
   diagnostics: Diagnostic[]; 
 }
 
 export interface ParseOptions {
+  source?: string;
   applyTraits?: boolean;
   parseSchemas?: boolean;
-  validateOptions?: ValidateOptions;
+  validateOptions?: Omit<ValidateOptions, 'source'>;
 }
 
 export async function parse(parser: Parser, asyncapi: ParseInput, options?: ParseOptions): Promise<ParseOutput> {
   const maybeDocument = toAsyncAPIDocument(asyncapi);
   if (maybeDocument) {
     return { 
-      source: asyncapi,
       document: maybeDocument,
       diagnostics: [],
     };
@@ -39,10 +38,9 @@ export async function parse(parser: Parser, asyncapi: ParseInput, options?: Pars
     const document = normalizeInput(asyncapi as Exclude<ParseInput, AsyncAPIDocumentInterface>);
     options = normalizeOptions(options);
 
-    const { validated, diagnostics } = await validate(parser, document, options.validateOptions);
+    const { validated, diagnostics } = await validate(parser, document, { ...options.validateOptions, source: options.source });
     if (validated === undefined) {
       return {
-        source: asyncapi,
         document: undefined,
         diagnostics,
       };
@@ -57,7 +55,6 @@ export async function parse(parser: Parser, asyncapi: ParseInput, options?: Pars
     await customOperations(parser, parsedDoc, detailed, options);
   
     return { 
-      source: asyncapi,
       document: parsedDoc,
       diagnostics,
     };
diff --git a/src/spectral.ts b/src/spectral.ts
index f486a56..e278968 100644
--- a/src/spectral.ts
+++ b/src/spectral.ts
@@ -20,6 +20,8 @@ function configureRuleset(parser: Parser): RulesetDefinition {
     rules: {
       'asyncapi-is-asyncapi': asyncApi2IsAsyncApi(),
       'asyncapi-schemas-v2': asyncApi2SchemaParserRule(parser),
+      // operationId is optional field
+      'asyncapi-operation-operationId': 'warn',
       // We do not use these rules from the official ruleset due to the fact 
       // that the given rules validate only AsyncAPI Schemas and prevent defining schemas in other formats 
       'asyncapi-payload-unsupported-schemaFormat': 'off',
diff --git a/tsconfig.json b/tsconfig.json
index f7bc416..65f9ca8 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,7 +4,8 @@
     "baseUrl": "./src",
     "target": "es6",
     "lib": [
-      "esnext"
+      "esnext",
+      "DOM"
     ],
     "declaration": true,
     "allowJs": true,


Test patch:
diff --git a/test/from.spec.ts b/test/from.spec.ts
new file mode 100644
index 0000000..0105deb
--- /dev/null
+++ b/test/from.spec.ts
@@ -0,0 +1,37 @@
+import path from 'path';
+import { Parser } from '../src/parser';
+import { fromURL, fromFile } from '../src/from';
+import { hasErrorDiagnostic, hasWarningDiagnostic } from '../src/utils';
+
+describe('fromURL() & fromFile()', function() {
+  const parser = new Parser();
+
+  describe('fromURL()', function() {
+    it('should operate on existing HTTP source', async function() {
+      const { document, diagnostics } = await fromURL(parser, 'https://raw.githubusercontent.com/asyncapi/spec/master/examples/simple.yml').parse();
+      expect(document).not.toBeUndefined();
+      expect(diagnostics.length > 0).toEqual(true);
+      expect(hasWarningDiagnostic(diagnostics)).toEqual(true);
+    });
+
+    it('should throw error on nonexisting HTTP source', async function() {
+      const { document, diagnostics } = await fromURL(parser, 'https://raw.githubusercontent.com/asyncapi/spec/master/examples/non-existing-spec.yml').parse();
+      expect(document).toBeUndefined();
+      expect(diagnostics.length > 0).toEqual(true);
+      expect(hasErrorDiagnostic(diagnostics)).toEqual(true);
+    });
+  });
+
+  describe('fromFile()', function() {
+    it('should operate on existing file source', async function() {
+      const { document, diagnostics } = await fromFile(parser, path.resolve(__dirname, './mocks/simple.yaml')).parse();
+      expect(document).not.toBeUndefined();
+      expect(diagnostics.length > 0).toEqual(true);
+      expect(hasWarningDiagnostic(diagnostics)).toEqual(true);
+    });
+
+    it('should throw error on nonexisting file source', async function() {
+      expect(() => fromFile(parser, path.resolve(__dirname, './mocks/non-existing-spec.yaml')).parse()).rejects.toThrow();
+    });
+  });
+});
diff --git a/test/mocks/simple.yaml b/test/mocks/simple.yaml
new file mode 100644
index 0000000..050c78a
--- /dev/null
+++ b/test/mocks/simple.yaml
@@ -0,0 +1,24 @@
+asyncapi: '2.4.0'
+info:
+  title: Account Service
+  version: 1.0.0
+  description: This service is in charge of processing user signups
+channels:
+  user/signedup:
+    subscribe:
+      operationId: 'subscribe'
+      message:
+        $ref: '#/components/messages/UserSignedUp'
+components:
+  messages:
+    UserSignedUp:
+      payload:
+        type: object
+        properties:
+          displayName:
+            type: string
+            description: Name of the user
+          email:
+            type: string
+            format: email
+            description: Email of the user
\ No newline at end of file
diff --git a/test/parse.spec.ts b/test/parse.spec.ts
index d26afa7..3662873 100644
--- a/test/parse.spec.ts
+++ b/test/parse.spec.ts
@@ -142,7 +142,7 @@ describe('parse()', function() {
         }
       }
     };
-    const { document } = await parse(parser, documentRaw, { validateOptions: { path: __filename } });
+    const { document } = await parse(parser, documentRaw, { source: __filename });
 
     const messagePayload = document?.channels().get('channel')?.operations().get('someId')?.messages()[0].payload();
     const circular = messagePayload?.properties()?.['circular'];