Skip to content

Commit

Permalink
feat(json-schema-parser): add parse
Browse files Browse the repository at this point in the history
  • Loading branch information
notaphplover committed Sep 8, 2023
1 parent 5765ccb commit 467fc85
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 1 deletion.
11 changes: 11 additions & 0 deletions packages/parser/json-schema-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.



3 changes: 3 additions & 0 deletions packages/parser/json-schema-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 0 additions & 1 deletion packages/parser/json-schema-parser/src/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<DereferenceFunction>;

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<typeof dereferenceJsonSchema>
).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<typeof dereferenceJsonSchema>
).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);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -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<JsonSchemaParseResult>;
export async function parse(
deref: DereferenceFunction,
options: ParseJsonSchemaOptions[],
): Promise<JsonSchemaParseResult>;
export async function parse(
...args:
| [DereferenceFunction, JsonSchema[], UriOptions]
| [DereferenceFunction, ParseJsonSchemaOptions[]]
): Promise<JsonSchemaParseResult> {
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<JsonSchemaParseResult> {
const referenceMap: Map<string, JsonSchema> = new Map();

await Promise.all(
schemas.map(
async (schema: JsonSchema): Promise<void> =>
dereferenceJsonSchema(deref, schema, referenceMap, options),
),
);

return {
referenceMap,
schemas,
};
}

async function parseFromMultipleOptions(
deref: DereferenceFunction,
options: ParseJsonSchemaOptions[],
): Promise<JsonSchemaParseResult> {
const referenceMap: Map<string, JsonSchema> = new Map();

await Promise.all(
options.map(
async (schemaOptions: ParseJsonSchemaOptions): Promise<void> =>
dereferenceJsonSchema(
deref,
schemaOptions.schema,
referenceMap,
schemaOptions.uriOptions,
),
),
);

return {
referenceMap,
schemas: options.map(
(schemaOptions: ParseJsonSchemaOptions) => schemaOptions.schema,
),
};
}
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12';

export interface JsonSchemaParseResult {
schemas: JsonSchema[];
referenceMap: Map<string, JsonSchema>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12';

import { UriOptions } from './UriOptions';

export interface ParseJsonSchemaOptions {
schema: JsonSchema;
uriOptions: UriOptions;
}

0 comments on commit 467fc85

Please sign in to comment.