UNPKG

kompendium

Version:

Documentation generator for Stencil components

168 lines (167 loc) 5.29 kB
import { isExample } from "./menu"; import negate from "lodash/negate"; import startCase from "lodash/startCase"; import zipObject from "lodash/zipObject"; import pick from "lodash/pick"; const ARRAY_PATTERN = /^(\w+)(<\w+>)?\[\]$|^Array<(.+)>$/; const ENUM_PATTERN = /["'](\w+)["']\s?\|?/g; const ID_PATTERN = /^number \| string$|string \| number$/g; const TS_UTILITY_PATTERN = /(Partial|Required|Readonly|Array)<(.+?)>/g; /** * Create schemas for the components that describe their interface * @param {JsonDocsComponent[]} components the components * @param {TypeDescription[]} types type definitions * @returns {*} list of schemas for the components */ export function createSchemas(components, types) { var _a; const componentSchemas = (components === null || components === void 0 ? void 0 : components.filter(negate(isExample)).map(createSchema(types))) || []; const classSchemas = ((_a = types === null || types === void 0 ? void 0 : types.filter(isClass)) === null || _a === void 0 ? void 0 : _a.map(createSchema(types))) || []; return [...componentSchemas, ...classSchemas]; } const createSchema = (types) => (object) => { const definitions = createDefinitions(types); const properties = createProps(object.props, definitions); const schema = { type: 'object', $id: getSchemaId(object), properties: properties, }; const data = JSON.stringify(properties); const definitionKeys = Object.keys(definitions).filter(isReferenceUsed(data)); if (definitionKeys.length > 0) { schema.definitions = pick(definitions, definitionKeys); } return schema; }; function getSchemaId(object) { if (isClass(object)) { return object.name; } return object.tag; } function createDefinitions(types) { const interfaces = types.filter((type) => type.type === 'interface'); const keys = interfaces.map((i) => i.name); const schemas = interfaces.map((i) => { return { type: 'object', properties: createProps(i.props, {}), }; }); return zipObject(keys, schemas); } function createProps(props, definitions) { const keys = (props === null || props === void 0 ? void 0 : props.map((prop) => prop.name)) || []; const schemas = (props === null || props === void 0 ? void 0 : props.map(createPropSchema(definitions))) || []; return zipObject(keys, schemas); } const createPropSchema = (definitions) => (prop) => { const schema = { type: getSchemaType(prop.type), title: startCase(prop.name), description: prop.docs, }; if (prop.default) { schema.default = getDefaultValue(prop.default, schema.type); } if (schema.type === 'array') { schema.items = getSchemaItems(prop.type, definitions); } if (schema.type === 'object') { const ref = getSchemaPropertiesRef(prop.type, definitions); if (ref) { schema.$ref = ref; } else { schema.additionalProperties = true; } } if (schema.type === 'string') { const oneOf = getOneOf(prop.type); if (oneOf) { schema.oneOf = oneOf; } } return schema; }; function getDefaultValue(value, type) { if (type === 'boolean') { return value === 'true'; } if (type === 'number') { return Number(value); } if (type !== 'string') { return; } if (value === 'null') { return; } return value; } function getSchemaType(propType) { if (['string', 'number', 'boolean'].includes(propType)) { return propType; } if (propType.match(ARRAY_PATTERN)) { return 'array'; } if (propType.match(ENUM_PATTERN) || propType.match(ID_PATTERN)) { return 'string'; } return 'object'; } function getSchemaItems(propType, definitions) { const result = propType.match(ARRAY_PATTERN); const type = getSchemaType(result[1] || result[3]); const items = { type: type, }; if (type === 'object') { const ref = getSchemaPropertiesRef(result[1] || result[3], definitions); if (ref) { items.$ref = ref; } else { items.additionalProperties = true; } } return items; } function getSchemaPropertiesRef(propType, definitions) { const definition = Object.keys(definitions).find((key) => key === propType); if (definition) { return '#/definitions/' + definition; } const type = propType.replace(TS_UTILITY_PATTERN, '$2'); if (type === propType) { return; } return getSchemaPropertiesRef(type, definitions); } function getOneOf(propType) { if (!ENUM_PATTERN.test(propType)) { return; } const oneOf = propType.split('|').map((token) => { const value = token.trim().replace(/["']/g, ''); return { type: 'string', const: value, title: value, }; }); if (!oneOf.length) { return; } return oneOf; } const isReferenceUsed = (data) => (name) => { const ref = '#/definitions/' + name; return data.includes(ref); }; function isClass(type) { return type.type === 'class'; } //# sourceMappingURL=schema.js.map