From 1d06370767bd0ba00a9ffad85d98063e40042eb1 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Fri, 1 Jun 2018 13:26:23 -0400 Subject: [PATCH] feat: document deprecated schema, close #64 --- src/document/docs.ts | 40 ++++----------------- src/document/utils.ts | 51 ++++++++++++++++++++++++++- src/objects.ts | 3 ++ test/document-test.ts | 38 +++++++++++++++++++- test/snapshots/document-test.ts.md | 38 +++++++++++++++++--- test/snapshots/document-test.ts.snap | Bin 1476 -> 1572 bytes 6 files changed, 129 insertions(+), 41 deletions(-) diff --git a/src/document/docs.ts b/src/document/docs.ts index 164abdb..bd48cb3 100644 --- a/src/document/docs.ts +++ b/src/document/docs.ts @@ -1,11 +1,8 @@ // generates Markdown document with all schema information -import stringify from 'json-stable-stringify' import json2md from 'json2md' -import quote from 'quote' import { flatten } from 'ramda' import { - getExample, getObjectSchema, getSchemaVersions, normalizeName, @@ -14,9 +11,9 @@ import { import { CustomFormats } from '../formats' import { ObjectSchema, SchemaCollection } from '../objects' import { documentCustomFormats } from './doc-formats' -import { anchor, documentSchema } from './utils' +import { anchor, documentObjectSchema } from './utils' -const ticks = quote({ quotes: '`' }) +// const ticks = quote({ quotes: '`' }) const title = [{ h1: 'Schemas' }] const titleLink = [{ p: '[🔝](#schemas)' }] @@ -46,36 +43,15 @@ export function documentSchemas( throw new Error(`cannot find schema ${schemaName}@${version}`) } - const schemaDoc = documentSchema(schema.schema, schemas, formats) + const schemaDoc = documentObjectSchema(schema, schemas, formats) - const start: any[] = [{ h3: `${schemaName}@${version}` }] - if (schema.package) { - start.push({ - p: `Defined in ${ticks(schema.package)}`, - }) - } - if (schema.schema.description) { - start.push({ p: schema.schema.description }) - } - - const example = getExample(schemas)(schemaName)(version) - const exampleFragment = flatten([ - schemaDoc, - { p: 'Example:' }, - { - code: { - language: 'json', - content: stringify(example, { space: ' ' }), - }, - }, - titleLink, - ]) - return flatten(start.concat(exampleFragment)) + return flatten(schemaDoc.concat(titleLink)) } const versionFragments = versions.map(documentSchemaVersion) - return [{ h2: normalizeName(schemaName) }].concat(flatten(versionFragments)) + const start: object[] = [{ h2: normalizeName(schemaName) }] + return start.concat(flatten(versionFragments)) } const fragments = flatten(schemaNames(schemas).map(toDoc)) @@ -98,10 +74,6 @@ export function documentSchemas( } } - // const extractH2 = map(prop('h2')) - // const filterH2 = filter(has('h2')) - // const headings = extractH2(filterH2(fragments)) - const headings = schemaNames(schemas) const toc = [ { diff --git a/src/document/utils.ts b/src/document/utils.ts index f1eaa78..5ef2522 100644 --- a/src/document/utils.ts +++ b/src/document/utils.ts @@ -1,5 +1,6 @@ +import stringify from 'json-stable-stringify' import quote from 'quote' -import { find, toLower } from 'ramda' +import { find, flatten, toLower } from 'ramda' import { normalizeName, schemaNames, semverToString } from '..' import { CustomFormats } from '../formats' import { @@ -163,3 +164,51 @@ export const documentSchema = ( return { p: 'Hmm, no properties found in this schema' } } } + +const schemaNameHeading = (name: string, version: string) => + `${name}@${version}` + +export const documentObjectSchema = ( + schema: ObjectSchema, + schemas?: SchemaCollection, + formats?: CustomFormats, +) => { + const schemaName = schema.schema.title + + if (schemaName.includes(' ')) { + throw new Error(`Schema title contains spaces "${schemaName}" + This can cause problems generating anchors!`) + } + + const schemaVersion = semverToString(schema.version) + + const start: object[] = [{ h3: schemaNameHeading(schemaName, schemaVersion) }] + if (schema.package) { + start.push({ + p: `Defined in ${ticks(schema.package)}`, + }) + } + if (schema.schema.description) { + start.push({ p: schema.schema.description }) + } + + if (schema.schema.deprecated) { + start.push({ + p: `**deprecated** ${schema.schema.deprecated}`, + }) + } + + const propertiesTable = documentSchema(schema.schema, schemas, formats) + + const exampleFragment = flatten([ + { p: 'Example:' }, + { + code: { + language: 'json', + content: stringify(schema.example, { space: ' ' }), + }, + }, + ]) + + return flatten(start.concat(propertiesTable).concat(exampleFragment)) +} diff --git a/src/objects.ts b/src/objects.ts index 85b6ca9..ef5bee9 100644 --- a/src/objects.ts +++ b/src/objects.ts @@ -52,6 +52,8 @@ export type JsonProperty = { patternProperties?: object additionalProperties?: boolean enum?: string[] + // if the property is deprecated show this message + deprecated?: string } export type JsonProperties = { @@ -69,6 +71,7 @@ export type JsonSchema = { required?: string[] | true // does the schema allow unknown properties? additionalProperties: boolean + deprecated?: string } export type ObjectSchema = { diff --git a/test/document-test.ts b/test/document-test.ts index 8254a16..6caabeb 100644 --- a/test/document-test.ts +++ b/test/document-test.ts @@ -4,12 +4,13 @@ import { clone } from 'ramda' import { documentSchemas, setPackageName } from '../src' import { documentCustomFormats } from '../src/document/doc-formats' import { + documentObjectSchema, documentProperties, documentSchema, findUsedColumns, } from '../src/document/utils' import { CustomFormats } from '../src/formats' -import { JsonProperties, JsonSchema } from '../src/objects' +import { JsonProperties, JsonSchema, ObjectSchema } from '../src/objects' import { exampleFormats, schemas } from './example-schemas' test('documents just schemas', t => { @@ -156,3 +157,38 @@ test('JSON schema with enumeration to Markdown', t => { const result = json2md(documentSchema(schema)) t.snapshot(result) }) + +test('document deprecated schema', t => { + t.plan(1) + const jsonSchema: JsonSchema = { + title: 'testSchema', + type: 'object', + additionalProperties: false, + description: 'This is a test schema', + deprecated: 'no longer in use', + properties: { + id: { + type: 'string', + }, + name: { + type: 'string', + enum: ['joe', 'mary'], + }, + }, + } + const schema: ObjectSchema = { + version: { + major: 1, + minor: 2, + patch: 3, + }, + schema: jsonSchema, + example: { + id: 'abc', + name: 'joe', + }, + } + const result = json2md(documentObjectSchema(schema)) + // console.log(result) + t.snapshot(result) +}) diff --git a/test/snapshots/document-test.ts.md b/test/snapshots/document-test.ts.md index 0435a58..2cf9e7b 100644 --- a/test/snapshots/document-test.ts.md +++ b/test/snapshots/document-test.ts.md @@ -4,6 +4,34 @@ The actual snapshot is saved in `document-test.ts.snap`. Generated by [AVA](https://ava.li). +## document deprecated schema + +> Snapshot 1 + + `### testSchema@1.2.3␊ + ␊ + ␊ + This is a test schema␊ + ␊ + ␊ + **deprecated** no longer in use␊ + ␊ + name | type | enum␊ + --- | --- | ---␊ + `id` | string | ␊ + `name` | string | `"joe", "mary"`␊ + ␊ + ␊ + Example:␊ + ␊ + ```json␊ + {␊ + "id": "abc",␊ + "name": "joe"␊ + }␊ + ```␊ + + ## JSON schema object to Markdown > Snapshot 1 @@ -134,7 +162,7 @@ Generated by [AVA](https://ava.li). ␊ ## person␊ ␊ - ### person@1.0.0␊ + ### Person@1.0.0␊ ␊ ␊ An example schema describing a person␊ @@ -159,7 +187,7 @@ Generated by [AVA](https://ava.li). ␊ ## team␊ ␊ - ### team@1.0.0␊ + ### Team@1.0.0␊ ␊ ␊ A team of people␊ @@ -198,7 +226,7 @@ Generated by [AVA](https://ava.li). ␊ ## person␊ ␊ - ### person@1.0.0␊ + ### Person@1.0.0␊ ␊ ␊ An example schema describing a person␊ @@ -223,7 +251,7 @@ Generated by [AVA](https://ava.li). ␊ ## team␊ ␊ - ### team@1.0.0␊ + ### Team@1.0.0␊ ␊ ␊ A team of people␊ @@ -280,4 +308,4 @@ Generated by [AVA](https://ava.li). - inner level 1␊ - inner level 2␊ ␊ - ` + ` \ No newline at end of file diff --git a/test/snapshots/document-test.ts.snap b/test/snapshots/document-test.ts.snap index 087c830adbff5d67495a88e47a60e06d0a63d5e1..1ee689954ac9ec65637014b6ec0e4e1c2ce541ce 100644 GIT binary patch literal 1572 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