From 467fc854c400e84afabe36731c1871781b0d6a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Pintos=20L=C3=B3pez?= Date: Sat, 9 Sep 2023 00:48:42 +0200 Subject: [PATCH] feat(json-schema-parser): add parse --- .../parser/json-schema-parser/CHANGELOG.md | 11 ++ .../parser/json-schema-parser/package.json | 3 + .../parser/json-schema-parser/src/index.ts | 1 - .../202012/calculations/parse.spec.ts | 115 ++++++++++++++++++ .../jsonSchema/202012/calculations/parse.ts | 80 ++++++++++++ .../src/jsonSchema/202012/index.ts | 8 ++ .../202012/models/JsonSchemaParseResult.ts | 6 + .../202012/models/ParseJsonSchemaOptions.ts | 8 ++ 8 files changed, 231 insertions(+), 1 deletion(-) delete mode 100644 packages/parser/json-schema-parser/src/index.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.spec.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/index.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/models/JsonSchemaParseResult.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/models/ParseJsonSchemaOptions.ts diff --git a/packages/parser/json-schema-parser/CHANGELOG.md b/packages/parser/json-schema-parser/CHANGELOG.md index d62dd54..46e5f3f 100644 --- a/packages/parser/json-schema-parser/CHANGELOG.md +++ b/packages/parser/json-schema-parser/CHANGELOG.md @@ -18,3 +18,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. + +## [UNRELEASED] + +### Added +- Added `parse`. +- Added `DereferenceFunction` +- Added `ParseJsonSchemaOptions` +- Added `UriOptions`. + + + diff --git a/packages/parser/json-schema-parser/package.json b/packages/parser/json-schema-parser/package.json index 57018eb..49c06bd 100644 --- a/packages/parser/json-schema-parser/package.json +++ b/packages/parser/json-schema-parser/package.json @@ -29,6 +29,9 @@ }, "homepage": "https://github.com/cuaklabs/ajstt#readme", "license": "See license in \"LICENSE\" file", + "exports": { + "./2020-12": "./lib/jsonSchema/202012/index.js" + }, "name": "@cuaklabs/json-schema-parser", "publishConfig": { "access": "public" diff --git a/packages/parser/json-schema-parser/src/index.ts b/packages/parser/json-schema-parser/src/index.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/packages/parser/json-schema-parser/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.spec.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.spec.ts new file mode 100644 index 0000000..e7ce5f1 --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.spec.ts @@ -0,0 +1,115 @@ +import { afterAll, beforeAll, describe, expect, it, jest } from '@jest/globals'; + +jest.mock('./dereferenceJsonSchema'); + +import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12'; + +import { JsonRootSchemaFixtures } from '../fixtures/JsonRootSchemaFixtures'; +import { DereferenceFunction } from '../models/DereferenceFunction'; +import { JsonSchemaParseResult } from '../models/JsonSchemaParseResult'; +import { UriOptions } from '../models/UriOptions'; +import { dereferenceJsonSchema } from './dereferenceJsonSchema'; +import { parse } from './parse'; + +describe(parse.name, () => { + let derefMock: jest.Mock; + + describe('having an array of schemas and uri options', () => { + let jsonSchemaFixture: JsonSchema; + let uriOptionsFixture: UriOptions; + + beforeAll(() => { + jsonSchemaFixture = JsonRootSchemaFixtures.any; + uriOptionsFixture = { + encapsulatingDocumentBaseUri: 'sample://uri', + }; + }); + + describe('when called', () => { + let result: unknown; + + beforeAll(async () => { + ( + dereferenceJsonSchema as jest.Mock + ).mockResolvedValueOnce(undefined); + + result = await parse(derefMock, [jsonSchemaFixture], uriOptionsFixture); + }); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('should call dereferenceJsonSchema()', () => { + expect(dereferenceJsonSchema).toHaveBeenCalledTimes(1); + expect(dereferenceJsonSchema).toHaveBeenCalledWith( + derefMock, + jsonSchemaFixture, + new Map(), + uriOptionsFixture, + ); + }); + + it('should return JsonSchemaParseResult', () => { + const expected: JsonSchemaParseResult = { + referenceMap: new Map(), + schemas: [jsonSchemaFixture], + }; + + expect(result).toStrictEqual(expected); + }); + }); + }); + + describe('having an array of ParseJsonSchemaOptions', () => { + let jsonSchemaFixture: JsonSchema; + let uriOptionsFixture: UriOptions; + + beforeAll(() => { + jsonSchemaFixture = JsonRootSchemaFixtures.any; + uriOptionsFixture = { + encapsulatingDocumentBaseUri: 'sample://uri', + }; + }); + + describe('when called', () => { + let result: unknown; + + beforeAll(async () => { + ( + dereferenceJsonSchema as jest.Mock + ).mockResolvedValueOnce(undefined); + + result = await parse(derefMock, [ + { + schema: jsonSchemaFixture, + uriOptions: uriOptionsFixture, + }, + ]); + }); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('should call dereferenceJsonSchema()', () => { + expect(dereferenceJsonSchema).toHaveBeenCalledTimes(1); + expect(dereferenceJsonSchema).toHaveBeenCalledWith( + derefMock, + jsonSchemaFixture, + new Map(), + uriOptionsFixture, + ); + }); + + it('should return JsonSchemaParseResult', () => { + const expected: JsonSchemaParseResult = { + referenceMap: new Map(), + schemas: [jsonSchemaFixture], + }; + + expect(result).toStrictEqual(expected); + }); + }); + }); +}); diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.ts new file mode 100644 index 0000000..254820c --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/parse.ts @@ -0,0 +1,80 @@ +import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12'; + +import { DereferenceFunction } from '../models/DereferenceFunction'; +import { JsonSchemaParseResult } from '../models/JsonSchemaParseResult'; +import { ParseJsonSchemaOptions } from '../models/ParseJsonSchemaOptions'; +import { UriOptions } from '../models/UriOptions'; +import { dereferenceJsonSchema } from './dereferenceJsonSchema'; + +export async function parse( + deref: DereferenceFunction, + schemas: JsonSchema[], + options: UriOptions, +): Promise; +export async function parse( + deref: DereferenceFunction, + options: ParseJsonSchemaOptions[], +): Promise; +export async function parse( + ...args: + | [DereferenceFunction, JsonSchema[], UriOptions] + | [DereferenceFunction, ParseJsonSchemaOptions[]] +): Promise { + const [deref, schemasOrOptions, optionsOrUndefined]: + | [DereferenceFunction, JsonSchema[], UriOptions] + | [DereferenceFunction, ParseJsonSchemaOptions[], undefined] = args as + | [DereferenceFunction, JsonSchema[], UriOptions] + | [DereferenceFunction, ParseJsonSchemaOptions[], undefined]; + + if (optionsOrUndefined === undefined) { + return parseFromMultipleOptions(deref, schemasOrOptions); + } else { + return parseFromSingleOptions(deref, schemasOrOptions, optionsOrUndefined); + } +} + +async function parseFromSingleOptions( + deref: DereferenceFunction, + schemas: JsonSchema[], + options: UriOptions, +): Promise { + const referenceMap: Map = new Map(); + + await Promise.all( + schemas.map( + async (schema: JsonSchema): Promise => + dereferenceJsonSchema(deref, schema, referenceMap, options), + ), + ); + + return { + referenceMap, + schemas, + }; +} + +async function parseFromMultipleOptions( + deref: DereferenceFunction, + options: ParseJsonSchemaOptions[], +): Promise { + const referenceMap: Map = new Map(); + + await Promise.all( + options.map( + async (schemaOptions: ParseJsonSchemaOptions): Promise => + dereferenceJsonSchema( + deref, + schemaOptions.schema, + referenceMap, + schemaOptions.uriOptions, + ), + ), + ); + + return { + referenceMap, + schemas: options.map( + (schemaOptions: ParseJsonSchemaOptions) => schemaOptions.schema, + ), + }; +} diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/index.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/index.ts new file mode 100644 index 0000000..d496fdb --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/index.ts @@ -0,0 +1,8 @@ +import { parse } from './calculations/parse'; +import { DereferenceFunction } from './models/DereferenceFunction'; +import { ParseJsonSchemaOptions } from './models/ParseJsonSchemaOptions'; +import { UriOptions } from './models/UriOptions'; + +export type { DereferenceFunction, ParseJsonSchemaOptions, UriOptions }; + +export { parse }; diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/models/JsonSchemaParseResult.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/models/JsonSchemaParseResult.ts new file mode 100644 index 0000000..13d224a --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/models/JsonSchemaParseResult.ts @@ -0,0 +1,6 @@ +import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12'; + +export interface JsonSchemaParseResult { + schemas: JsonSchema[]; + referenceMap: Map; +} diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/models/ParseJsonSchemaOptions.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/models/ParseJsonSchemaOptions.ts new file mode 100644 index 0000000..0b5c896 --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/models/ParseJsonSchemaOptions.ts @@ -0,0 +1,8 @@ +import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12'; + +import { UriOptions } from './UriOptions'; + +export interface ParseJsonSchemaOptions { + schema: JsonSchema; + uriOptions: UriOptions; +}