first commit

This commit is contained in:
2023-05-13 18:44:28 -07:00
commit b2fb73fd2a
6 changed files with 1496 additions and 0 deletions

575
src/index.ts Normal file
View 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 + "'";
// }