first commit
This commit is contained in:
575
src/index.ts
Normal file
575
src/index.ts
Normal file
@@ -0,0 +1,575 @@
|
||||
|
||||
// import * as wrap from 'word-wrap';
|
||||
// import { JSONSchema7 } from 'json-schema';
|
||||
// import { JSONSchema, JSONSchemaDefinition, SchemaDoc } from '../../documents';
|
||||
// import { MarkdownBuilder } from './builder';
|
||||
// import { JsonPointer } from '../../utils';
|
||||
// import { render_document_formats } from './formats-section';
|
||||
|
||||
// const indent_with = ' ';
|
||||
|
||||
export function build_markdown_from_json_schema(/* json_schema: SchemaDoc */) /* : string */ { }
|
||||
// const schema = json_schema.data;
|
||||
// const doc = new MarkdownBuilder({
|
||||
// numbered_headings: false,
|
||||
// });
|
||||
|
||||
// doc.h1(schema.title, { id: '/title' });
|
||||
|
||||
// if (schema.description) {
|
||||
// doc.p(schema.description);
|
||||
// }
|
||||
|
||||
// render_document_formats(doc, json_schema.json_media_type, {
|
||||
// json: json_schema.json_media_type,
|
||||
// yaml: json_schema.yaml_media_type,
|
||||
// });
|
||||
|
||||
// doc.h2('Schema', { id: '/' });
|
||||
|
||||
// const close_block = doc.code_block({ lang: 'clike' });
|
||||
// doc.raw(render_type(schema) + '\n\n');
|
||||
// close_block();
|
||||
|
||||
// if (schema.definitions) {
|
||||
// const ptr = new JsonPointer([ 'definitions' ]);
|
||||
|
||||
// doc.h2('Definitions', { id: ptr.as_md_str() });
|
||||
|
||||
// for (const [ name, type ] of Object.entries(schema.definitions) as [ string, JSONSchemaDefinition ][]) {
|
||||
// if (name === '//') {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// doc.h3(name, { id: ptr.step_down(name).as_md_str() });
|
||||
|
||||
// const close_block = doc.code_block({ lang: 'clike' });
|
||||
// doc.raw(render_comment_if_needed(type) + 'def ' + name + ': ' + render_type(type) + '\n');
|
||||
// close_block();
|
||||
// }
|
||||
// }
|
||||
|
||||
// return doc.as_str();
|
||||
// }
|
||||
|
||||
// function render_comment_if_needed(obj: JSONSchema | boolean, indent_depth = 0) {
|
||||
// if (typeof obj === 'boolean') {
|
||||
// return '';
|
||||
// }
|
||||
|
||||
// const indent = `${indent_with.repeat(indent_depth)}// `;
|
||||
|
||||
// const chunks: string[] = [ ];
|
||||
|
||||
// if (obj.title) {
|
||||
// chunks.push(indent + obj.title + '\n');
|
||||
// }
|
||||
|
||||
// if (obj.description) {
|
||||
// chunks.push(wrap(obj.description, { indent, width: 100, }) + '\n');
|
||||
// }
|
||||
|
||||
// if (Array.isArray(obj.examples)) {
|
||||
// chunks.push(
|
||||
// indent + 'Examples:\n' + obj.examples.map((example) => {
|
||||
// return indent + '- ' + JSON.stringify(example) + '\n'
|
||||
// }).join('')
|
||||
// );
|
||||
// }
|
||||
|
||||
// if ((obj as JSONSchema7).$comment) {
|
||||
// chunks.push(
|
||||
// indent + '--- Comment ---\n' +
|
||||
// wrap((obj as JSONSchema7).$comment, { indent, width: 100, }) + '\n'
|
||||
// );
|
||||
// }
|
||||
|
||||
// return chunks.join(indent + '\n');
|
||||
// }
|
||||
|
||||
// function render_schema(doc: SchemaDoc, indent_depth = 0, inline = true) {
|
||||
// const schema = doc.data;
|
||||
// const chunks: string[] = [ ];
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
|
||||
// chunks.push(render_comment_if_needed(schema, indent_depth));
|
||||
// chunks.push((inline ? '' : indent) + 'schema ' + (schema.$id ? str(schema.$id) + ' {\n' : '{\n'));
|
||||
// chunks.push(render_type(schema, indent_depth + 1, false));
|
||||
|
||||
// if (schema.definitions) {
|
||||
// chunks.push('\n');
|
||||
// chunks.push(render_definitions(schema, indent_depth + 1));
|
||||
// }
|
||||
|
||||
// chunks.push('}');
|
||||
|
||||
// return chunks.join('');
|
||||
// }
|
||||
|
||||
// function render_type(obj: JSONSchema | boolean, indent_depth = 0, inline = true) {
|
||||
// if (obj === true) {
|
||||
// return render_simple('any', indent_depth, inline);
|
||||
// }
|
||||
|
||||
// if (obj === false) {
|
||||
// return render_simple('never', indent_depth, inline);
|
||||
// }
|
||||
|
||||
// const chunks: string[] = [ ];
|
||||
// const core_type = render_core_type_details(obj, indent_depth, inline);
|
||||
|
||||
// if (core_type) {
|
||||
// chunks.push(core_type);
|
||||
// }
|
||||
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
|
||||
// if (obj.oneOf) {
|
||||
// chunks.push(render_additional(obj, render_one_of));
|
||||
// }
|
||||
|
||||
// if (obj.anyOf) {
|
||||
// chunks.push(render_additional(obj, render_any_of));
|
||||
// }
|
||||
|
||||
// if (obj.allOf) {
|
||||
// chunks.push(render_additional(obj, render_all_of));
|
||||
// }
|
||||
|
||||
// if (obj.not) {
|
||||
// chunks.push(render_additional(obj, render_not));
|
||||
// }
|
||||
|
||||
// // todo: if
|
||||
// // todo: then
|
||||
// // todo: else
|
||||
|
||||
// if (! chunks.length) {
|
||||
// return render_any(obj, indent_depth, inline);
|
||||
// }
|
||||
|
||||
// if (inline) {
|
||||
// if (! chunks[chunks.length - 1].endsWith(';')) {
|
||||
// chunks.push(';');
|
||||
// }
|
||||
// }
|
||||
|
||||
// else if (! chunks[chunks.length - 1].endsWith(';\n')) {
|
||||
// if (chunks[chunks.length - 1].endsWith('\n')) {
|
||||
// chunks[chunks.length - 1] = chunks[chunks.length - 1].slice(0, -1) + ';\n';
|
||||
// }
|
||||
|
||||
// else {
|
||||
// chunks.push(
|
||||
// chunks[chunks.length - 1].endsWith(';') ? '\n' : ';\n'
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// return chunks.join('');
|
||||
|
||||
// function render_additional(obj: JSONSchema, render: (obj: JSONSchema, indent_depth: number, inline: boolean) => string) {
|
||||
// if (chunks.length) {
|
||||
// const newline = inline ? '\n' : '';
|
||||
// return newline + indent + '+ ' + render(obj, indent_depth, true);
|
||||
// }
|
||||
|
||||
// return render(obj, indent_depth, inline);
|
||||
// }
|
||||
// }
|
||||
|
||||
// function render_core_type_details(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// if (obj.$ref) {
|
||||
// return render_ref(obj, indent_depth, inline);
|
||||
// }
|
||||
|
||||
// if (Array.isArray(obj.type)) {
|
||||
// const is_obj = obj.type.includes('object');
|
||||
// const is_arr = obj.type.includes('array');
|
||||
|
||||
// if (is_obj && is_arr) {
|
||||
// // todo: render schemas that can be both objects and arrays somehow...
|
||||
// }
|
||||
|
||||
// else if (is_obj) {
|
||||
// return render_object(obj, indent_depth, inline)
|
||||
// }
|
||||
|
||||
// else if (is_arr) {
|
||||
// // todo: render multi-type arrays
|
||||
// }
|
||||
|
||||
// else {
|
||||
// return render_basic(obj, indent_depth, inline);
|
||||
// }
|
||||
// }
|
||||
|
||||
// const type = obj.type || infer_type(obj);
|
||||
|
||||
// switch (type) {
|
||||
// case 'any': return render_any(obj, indent_depth, inline);
|
||||
// case 'array': return render_array(obj, indent_depth, inline);
|
||||
// case 'boolean': return render_basic(obj, indent_depth, inline);
|
||||
// case 'integer': return render_basic(obj, indent_depth, inline);
|
||||
// case 'null': return render_simple('null', indent_depth, inline);
|
||||
// case 'number': return render_basic(obj, indent_depth, inline);
|
||||
// case 'object': return render_object(obj, indent_depth, inline);
|
||||
// case 'string': return render_basic(obj, indent_depth, inline);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // ===== Type-Specific Renderers =====
|
||||
|
||||
// function render_simple(text: string, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// return inline ? `${text};` : (indent + `${text};\n`);
|
||||
// }
|
||||
|
||||
// function render_basic_type_and_attributes(obj: JSONSchema, type_str?: string, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const basic_type = type_str || (
|
||||
// Array.isArray(obj.type) ? obj.type.join(' | ') : (obj.type || 'any')
|
||||
// );
|
||||
// const chunks: string[] = [ (inline ? '' : indent) + basic_type ];
|
||||
// const attrs: string[] = [ ];
|
||||
|
||||
// if ('const' in obj) {
|
||||
// attrs.push(`(const ${JSON.stringify(obj.const)})`);
|
||||
// }
|
||||
|
||||
// if ('enum' in obj) {
|
||||
// const values = obj.enum.map((value) => JSON.stringify(value));
|
||||
// const value_list = render_inline_list(values, 1);
|
||||
// attrs.push(`(enum${value_list})`);
|
||||
// }
|
||||
|
||||
// if ('default' in obj) {
|
||||
// attrs.push(`(default ${JSON.stringify(obj.default)})`);
|
||||
// }
|
||||
|
||||
// if ('minimum' in obj) {
|
||||
// attrs.push(`(minimum ${obj.minimum})`);
|
||||
// }
|
||||
|
||||
// if ('maximum' in obj) {
|
||||
// attrs.push(`(maximum ${obj.maximum})`);
|
||||
// }
|
||||
|
||||
// if ('exclusiveMinimum' in obj) {
|
||||
// attrs.push(`(exclusive-minimum ${obj.exclusiveMinimum})`);
|
||||
// }
|
||||
|
||||
// if ('exclusiveMaximum' in obj) {
|
||||
// attrs.push(`(exclusive-maximum ${obj.exclusiveMaximum})`);
|
||||
// }
|
||||
|
||||
// if ('multipleOf' in obj) {
|
||||
// attrs.push(`(multiple-of ${obj.multipleOf})`);
|
||||
// }
|
||||
|
||||
// if ('minItems' in obj) {
|
||||
// attrs.push(`(min-items ${obj.minItems})`);
|
||||
// }
|
||||
|
||||
// if ('maxItems' in obj) {
|
||||
// attrs.push(`(max-items ${obj.maxItems})`);
|
||||
// }
|
||||
|
||||
// if ('uniqueItems' in obj) {
|
||||
// attrs.push('(unique-items)');
|
||||
// }
|
||||
|
||||
// if ('format' in obj) {
|
||||
// attrs.push(`(format ${obj.format})`);
|
||||
// }
|
||||
|
||||
// if ('pattern' in obj) {
|
||||
// attrs.push(`(pattern ${regex(obj.pattern)})`);
|
||||
// }
|
||||
|
||||
// if ('minLength' in obj) {
|
||||
// attrs.push(`(min-length ${obj.minLength})`);
|
||||
// }
|
||||
|
||||
// if ('maxLength' in obj) {
|
||||
// attrs.push(`(max-length ${obj.maxLength})`);
|
||||
// }
|
||||
|
||||
// if ('contentMediaType' in obj) {
|
||||
// attrs.push(`(content-media-type ${str(obj.contentMediaType)})`);
|
||||
// }
|
||||
|
||||
// if ('contentEncoding' in obj) {
|
||||
// attrs.push(`(content-encoding ${str(obj.contentEncoding)})`);
|
||||
// }
|
||||
|
||||
// chunks.push(render_inline_list(attrs, indent_depth + 1));
|
||||
|
||||
// return chunks;
|
||||
// }
|
||||
|
||||
// function render_ref(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const chunks = render_basic_type_and_attributes(obj, `<${str(obj.$ref)}>`, indent_depth, inline);
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_any(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const chunks = render_basic_type_and_attributes(obj, 'any', indent_depth, inline);
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_basic(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const chunks = render_basic_type_and_attributes(obj, null, indent_depth, inline);
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_array(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const chunks = render_basic_type_and_attributes(obj, null, indent_depth, inline);
|
||||
|
||||
// if (obj.items) {
|
||||
// if (Array.isArray(obj.items)) {
|
||||
// chunks.push(' [\n');
|
||||
// chunks.push(render_array_tuple(obj, indent_depth + 1));
|
||||
// chunks.push(indent + ']');
|
||||
// }
|
||||
|
||||
// else {
|
||||
// chunks.push(' {\n');
|
||||
// chunks.push(render_comment_if_needed(obj.items, indent_depth + 1));
|
||||
// chunks.push(render_type(obj.items, indent_depth + 1, false));
|
||||
// chunks.push(indent + '}');
|
||||
// }
|
||||
// }
|
||||
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_array_tuple(obj: JSONSchema, indent_depth = 0) {
|
||||
// const chunks: string[] = [ ];
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
|
||||
// for (const type of (obj.items as JSONSchemaDefinition[])) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(type, indent_depth));
|
||||
// chunks.push(indent + render_type(type, indent_depth) + '\n');
|
||||
// }
|
||||
|
||||
// if (obj.additionalItems) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(obj.additionalItems, indent_depth));
|
||||
// chunks.push(indent + '... ' + render_type(obj.additionalItems, indent_depth) + '\n');
|
||||
// }
|
||||
|
||||
// return chunks.join('');
|
||||
// }
|
||||
|
||||
// function render_object(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const chunks = render_basic_type_and_attributes(obj, null, indent_depth, inline);
|
||||
|
||||
// if (obj.properties || obj.additionalProperties || obj.patternProperties) {
|
||||
// chunks.push(' {\n');
|
||||
// chunks.push(render_object_properties(obj, indent_depth + 1));
|
||||
// chunks.push(indent + '}');
|
||||
// }
|
||||
|
||||
// else if (Array.isArray(obj.required)) {
|
||||
// const values = obj.required.map((value) => JSON.stringify(value));
|
||||
// const value_list = render_inline_list(values, 1);
|
||||
// chunks.push(` (required${value_list})`);
|
||||
// }
|
||||
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_object_properties(obj: JSONSchema, indent_depth = 0) {
|
||||
// const chunks: string[] = [ ];
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const required = new Set(Array.isArray(obj.required) ? obj.required : [ ]);
|
||||
|
||||
// if (obj.properties) {
|
||||
// for (const [name, type] of Object.entries(obj.properties) as [string, JSONSchema['properties'][string]][]) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// const optional_ind = required.has(name) ? '' : '?';
|
||||
// chunks.push(render_comment_if_needed(type, indent_depth));
|
||||
// chunks.push(indent + name + optional_ind + ': ' + render_type(type, indent_depth) + '\n');
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (obj.patternProperties) {
|
||||
// for (const [name, type] of Object.entries(obj.patternProperties) as [string, JSONSchema['properties'][string]][]) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(type, indent_depth));
|
||||
// chunks.push(indent + `['${name}']: ` + render_type(type, indent_depth) + '\n');
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (obj.additionalProperties) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(obj.additionalProperties, indent_depth));
|
||||
// chunks.push(indent + '[*]: ' + render_type(obj.additionalProperties, indent_depth) + '\n');
|
||||
// }
|
||||
|
||||
// return chunks.join('');
|
||||
// }
|
||||
|
||||
// function render_one_of(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const chunks: string[] = [ (inline ? '' : indent) + 'one_of' ];
|
||||
|
||||
// chunks.push(' {\n');
|
||||
// render_type_list(chunks, obj.oneOf, indent_depth);
|
||||
// chunks.push(indent + '}');
|
||||
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_all_of(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const chunks: string[] = [ (inline ? '' : indent) + 'all_of' ];
|
||||
|
||||
// chunks.push(' {\n');
|
||||
// render_type_list(chunks, obj.allOf, indent_depth);
|
||||
// chunks.push(indent + '}');
|
||||
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_any_of(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const chunks: string[] = [ (inline ? '' : indent) + 'any_of' ];
|
||||
|
||||
// chunks.push(' {\n');
|
||||
// render_type_list(chunks, obj.anyOf, indent_depth);
|
||||
// chunks.push(indent + '}');
|
||||
|
||||
// return chunks.join('') + (inline ? '' : '\n');
|
||||
// }
|
||||
|
||||
// function render_not(obj: JSONSchema, indent_depth = 0, inline = true) {
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const prefix = inline ? '' : indent;
|
||||
// const suffix = inline ? '' : '\n';
|
||||
// return prefix + 'not ' + render_type(obj.not, indent_depth, true) + suffix;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // ===== Rendering Utils =====
|
||||
|
||||
// function infer_type(obj: JSONSchema) {
|
||||
// return (obj.properties || obj.additionalProperties || obj.required || 'minimumProperties' in obj || 'maximumProperties' in obj) ? 'object'
|
||||
// : (obj.items || obj.additionalItems || 'minimumItems' in obj || 'maximumItems' in obj) ? 'array'
|
||||
// : ('minimum' in obj || 'maximum' in obj || 'exclusiveMinimum' in obj || 'exclusiveMaximum' in obj) ? 'number'
|
||||
// : ('minLength' in obj || 'maxLength' in obj) ? 'string'
|
||||
// : null
|
||||
// ;
|
||||
// }
|
||||
|
||||
// function render_type_list(chunks: string[], types: JSONSchemaDefinition[], indent_depth = 0) {
|
||||
// for (const type of types) {
|
||||
// if (typeof type === 'object') {
|
||||
// // skip the extra newline before the first entry
|
||||
// if (chunks.length > 2) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(type, indent_depth + 1));
|
||||
// chunks.push(render_type(type, indent_depth + 1, false));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// function render_definitions(obj: JSONSchema, indent_depth = 0) {
|
||||
// const chunks: string[] = [ ];
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
|
||||
// type Def = Exclude<JSONSchema['definitions'][string], boolean>;
|
||||
// for (const [name, type] of Object.entries(obj.definitions) as [string, Def][]) {
|
||||
// if (chunks.length) {
|
||||
// chunks.push('\n');
|
||||
// }
|
||||
|
||||
// chunks.push(render_comment_if_needed(type, indent_depth));
|
||||
// chunks.push(indent + 'def ' + name + ': ' + render_type(type, indent_depth) + '\n');
|
||||
// }
|
||||
|
||||
// return chunks.join('');
|
||||
// }
|
||||
|
||||
// function render_inline_list(items: string[], indent_depth = 0) {
|
||||
// const lines: string[] = [ ];
|
||||
// const indent = indent_with.repeat(indent_depth);
|
||||
// const line_max = 100;
|
||||
// const first_line_max = 85;
|
||||
|
||||
// let line = '';
|
||||
|
||||
// for (const item of items) {
|
||||
// if (item.includes('\n')) {
|
||||
// const sub_lines = item.split('\n');
|
||||
// const first_line = sub_lines[0];
|
||||
// const last_line = sub_lines[sub_lines.length - 1];
|
||||
// const middle_lines = sub_lines.slice(1, -1);
|
||||
|
||||
// add_item(first_line);
|
||||
// lines.push(line + '\n');
|
||||
|
||||
// for (const item of middle_lines) {
|
||||
// lines.push(indent + item + '\n');
|
||||
// }
|
||||
|
||||
// line = indent + last_line;
|
||||
// }
|
||||
|
||||
// else {
|
||||
// add_item(item);
|
||||
// }
|
||||
// }
|
||||
|
||||
// function add_item(item: string) {
|
||||
// const new_length = line.length + item.length + 1;
|
||||
// const max_length = lines.length ? line_max : first_line_max;
|
||||
|
||||
// if (line && new_length > max_length) {
|
||||
// lines.push(line + '\n');
|
||||
// line = indent + item;
|
||||
// }
|
||||
|
||||
// else {
|
||||
// line += ' ' + item;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (line) {
|
||||
// lines.push(line);
|
||||
// }
|
||||
|
||||
// return lines.join('');
|
||||
// }
|
||||
|
||||
// function str(str: string) {
|
||||
// return JSON.stringify(str) as `"${string}"`;
|
||||
// }
|
||||
|
||||
// function regex(str: string) {
|
||||
// return "'" + str + "'";
|
||||
// }
|
Reference in New Issue
Block a user