Skip to content
This repository has been archived by the owner on Jan 27, 2022. It is now read-only.

Commit

Permalink
feat(JSON Schema): Allow for inline $refs
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Jan 30, 2020
1 parent 00ec60f commit e426380
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 5 deletions.
103 changes: 103 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@stencila/dev-config": "1.4.10",
"@stencila/encoda": "0.83.2",
"@stencila/logga": "2.1.0",
"@stoplight/json-ref-resolver": "3.0.8",
"@types/fs-extra": "8.0.1",
"@types/jest": "24.9.1",
"@types/js-yaml": "3.12.2",
Expand Down
11 changes: 10 additions & 1 deletion ts/bindings/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ const docComment = (description?: string, tags: string[] = []): string => {
const schemaToType = (schema: Schema): string => {
const { type, anyOf, allOf, $ref } = schema

if ($ref !== undefined) return `${$ref.replace('.schema.json', '')}`
if ($ref !== undefined) return $refToType($ref)
if (anyOf !== undefined) return anyOfToType(anyOf)
if (allOf !== undefined) return allOfToType(allOf)
if (schema.enum !== undefined) return enumToType(schema.enum)
Expand All @@ -192,6 +192,15 @@ const schemaToType = (schema: Schema): string => {
throw new Error(`Unhandled schema: ${JSON.stringify(schema)}`)
}

/**
* Convert a schema `$ref` (reference) to a Typescript type
*
* Assume that any `$ref`s refer to a type defined in the file.
*/
const $refToType = ($ref: string): string => {
return $ref.replace('.schema.json', '')
}

/**
* Convert a schema with the `anyOf` property to a Typescript `Union` type.
*/
Expand Down
11 changes: 8 additions & 3 deletions ts/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* generating languages bindings and documentation.
*/

import { Resolver } from '@stoplight/json-ref-resolver'
import fs from 'fs-extra'
import globby from 'globby'
import path from 'path'
Expand All @@ -11,7 +12,8 @@ import Schema from './schema-interface'
export { default as Schema } from './schema-interface'

/**
* Read the schemas from `public/*.schema.json`.
* Read the schemas from `public/*.schema.json` and dereference
* any inline references.
*/
export async function readSchemas(
glob: string | string[] = path.join(
Expand All @@ -21,10 +23,13 @@ export async function readSchemas(
'*.schema.json'
)
): Promise<Schema[]> {
// Read in the schemas
const files = await globby(glob)
return Promise.all(
files.map(async (file: string): Promise<Schema> => fs.readJSON(file))
files.map(async (file: string) => {
const resolver = new Resolver()
const resolved = await resolver.resolve(await fs.readJSON(file))
return resolved.result
})
)
}

Expand Down
5 changes: 4 additions & 1 deletion ts/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ const checkSchema = (
if (
key === '$ref' &&
typeof child === 'string' &&
!child.startsWith('#') &&
!child.endsWith('Types') &&
!schemas.has(child)
) {
Expand Down Expand Up @@ -383,13 +384,15 @@ const processSchema = (schemas: Map<string, Schema>, schema: Schema): void => {
}
}

// Replace any `$ref`s to YAML with a ref to the JSON generated in this function
// Replace any `$ref`s that are not internal (i.e. starting with `#`)
// with a ref to the JSON file generated by this function
const walk = (node: Schema): void => {
if (typeof node !== 'object') return
for (const [key, child] of Object.entries(node)) {
if (
key === '$ref' &&
typeof child === 'string' &&
!child.startsWith('#') &&
!child.endsWith('.schema.json')
)
node[key] = child + '.schema.json'
Expand Down

0 comments on commit e426380

Please sign in to comment.