import { MDAST } from 'mdast'; import { UNIST } from 'unist'; import * as mdToString from 'mdast-util-to-string'; import * as jsyaml from 'js-yaml'; export let schema = ` type Query { documents(idFilter: String = ""): [Root] } type Root { id: ID type: String folder(depth: Int = 1): String metadata(key: String): String heading(depth: Int = 0): Heading headings(depth: Int = 0): [Heading] paragraph: Paragraph paragraphs: [Paragraph] link: Link links: [Link] text: Text texts: [Text] children: [Node] } type Heading { depth: Int plaintext: String paragraph: Paragraph paragraphs: [Paragraph] link: Link links: [Link] children: [Node] } type Paragraph { plaintext: String } type Link { plaintext: String title: String url: String paragraph: Paragraph paragraphs: [Paragraph] text: Text texts: [Text] } type Text { value: String } type Node { type: String children: [Node] } `; export class Node { constructor(private orig: UNIST.Node) {} type(): string { return this.orig.type; } depth(): number { return this.orig['depth'] || null; } lang(): string { return this.orig['lang'] || null; } ordered(): boolean { return this.orig['ordered'] || null; } start(): number { return this.orig['start'] || null; } loose(): boolean { return this.orig['loose'] || null; } align(): MDAST.AlignType { return this.orig['align'] || null; } title(): string { return this.orig['title'] || null; } url(): string { return this.orig['title'] || null; } children(): Node[] { if (this.orig['children']) { return this.orig['children'].map(x => new Node(x)); } else { return null; } } } export class Parent { constructor(protected orig: UNIST.Parent) {} plaintext(): string { return mdToString(this.orig); } paragraph(): Paragraph { return new Paragraph( this.orig.children.find( (ch: UNIST.Node) => (ch.type === 'paragraph') )); } paragraphs(): Paragraph[] { return this.orig.children.filter( (ch: UNIST.Node) => (ch.type === 'paragraph') ) .map(ch => new Paragraph( ch)); } link(): Link { return new Link( this.orig.children.find( (ch: UNIST.Node) => (ch.type === 'link') )); } links(): Link[] { return this.orig.children.filter( (ch: UNIST.Node) => (ch.type === 'link') ) .map(ch => new Link( ch)); } text(): Text { return new Text( this.orig.children.find( (ch: UNIST.Node) => (ch.type === 'text') )); } texts(): Text[] { return this.orig.children.filter( (ch: UNIST.Node) => (ch.type === 'text') ) .map(ch => new Text( ch)); } } export class Root extends Parent { _meta: {}; id: string; type(): string { return 'root'; } folder(args): string { const depth = args['depth']; const relPath = this.id.substring(this.id.indexOf('docs')); const pathSegments = relPath.split(/[\\\/]/); return pathSegments[depth]; } metadata(args): string { if (!this._meta) { const yamlElement: any = this.orig.children.find( (ch: UNIST.Node) => (ch.type === 'yaml') ); if (yamlElement) { this._meta = jsyaml.safeLoad(yamlElement.value); } else { this._meta = {}; } } if (this._meta[args['key']]) { return this._meta[args['key']]; } else { return ''; } } heading(args): Heading { const depth = args['depth']; return new Heading( this.orig.children.find( (ch: UNIST.Node) => (ch.type === 'heading') && ((depth === 0) || (depth === ( ch).depth)) )); } headings(args): Heading[] { const depth = args['depth']; return this.orig.children.filter( (ch: UNIST.Node) => (ch.type === 'heading') && ((depth === 0) || (depth === ( ch).depth))) .map(ch => new Heading( ch)); } } export class Heading extends Parent { depth(): number { return ( this.orig).depth; } } export class Paragraph extends Parent { } export class Link extends Parent { title(): string { return ( this.orig).title; } url(): string { return ( this.orig).url; } } export class Text { constructor(protected orig: MDAST.TextNode) {} value(): String { return this.orig.value; } } const libNamesRegex = /content-services|core|extensions|insights|process-services|process-services-cloud/; export class Docset { public docs: Root[]; constructor(mdCache) { this.docs = []; const pathnames = Object.keys(mdCache); pathnames.forEach(pathname => { if (!pathname.match(/README/) && pathname.match(libNamesRegex) ) { const doc = new Root(mdCache[pathname].mdInTree); doc.id = pathname.replace(/\\/g, '/'); this.docs.push(doc); } }); } documents(args): Root[] { if (args['idFilter'] === '') { return this.docs; } else { return this.docs.filter(doc => doc.id.indexOf(args['idFilter'] + '/') !== -1); } } size(): number { return this.docs.length; } }