Skip to content

Commit

Permalink
feat(schema): add ability to view complete signature of every api nod…
Browse files Browse the repository at this point in the history
…e including docs (#9206)
  • Loading branch information
luvkapur authored Sep 18, 2024
1 parent 44d5e0f commit 8eb6644
Show file tree
Hide file tree
Showing 49 changed files with 703 additions and 69 deletions.
50 changes: 49 additions & 1 deletion components/entities/semantic-schema/api-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class APISchema extends SchemaNode {
return '';
}

return `${chalk.green.bold(sectionName)}\n${objects.map((c) => c.toString()).join('\n')}\n\n`;
return `${chalk.green.bold(sectionName)}\n${objects.map((c) => c.toString({ color: true })).join('\n')}\n\n`;
};

return (
Expand All @@ -95,6 +95,54 @@ export class APISchema extends SchemaNode {
);
}

toFullSignature(options: { showDocs?: boolean; showTitles?: boolean } = { showDocs: true }): string {
const title = `API Schema of ${this.componentId.toString()}\n\n`;

const exportGroups: { [key: string]: SchemaNode[] } = {};

for (const exp of this.module.exports) {
const node = ExportSchema.isExportSchema(exp) ? exp.exportNode : exp;
const constructorName = node.constructor.name;

if (!exportGroups[constructorName]) {
exportGroups[constructorName] = [];
}

exportGroups[constructorName].push(exp);
}

let output = options.showTitles ? title : '';

for (const [sectionName, exports] of Object.entries(exportGroups)) {
const readableSectionName = options.showTitles ? this.getReadableSectionName(sectionName) : '';

output += `${readableSectionName}\n\n`;

const sectionBody = exports.map((exp) => exp.toFullSignature(options)).join('\n\n');

output += `${sectionBody}\n\n`;
}

return output.trim();
}

private getReadableSectionName(constructorName: string): string {
const sectionNameMap: { [key: string]: string } = {
ModuleSchema: 'Namespaces',
ClassSchema: 'Classes',
InterfaceSchema: 'Interfaces',
FunctionLikeSchema: 'Functions',
VariableLikeSchema: 'Variables',
TypeSchema: 'Types',
EnumSchema: 'Enums',
TypeRefSchema: 'Type References',
UnresolvedSchema: 'Unresolved',
ReactSchema: 'React Components',
};

return sectionNameMap[constructorName] || constructorName;
}

listSignatures() {
return this.module.exports.map((exp) => exp.signature);
}
Expand Down
6 changes: 4 additions & 2 deletions components/entities/semantic-schema/schema-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export interface ISchemaNode {
signature?: string;
name?: string;
toObject(): Record<string, any>;
toString(): string;
toString(options?: { color?: boolean }): string;
toFullSignature(options?: { showDocs?: boolean }): string;
getNodes(): SchemaNode[];
findNode(predicate: (node: SchemaNode) => boolean, visitedNodes?: Set<SchemaNode>): SchemaNode | undefined;
getAllNodesRecursively(visitedNodes?: Set<SchemaNode>): SchemaNode[];
Expand Down Expand Up @@ -44,7 +45,8 @@ export abstract class SchemaNode implements ISchemaNode {
);
}

abstract toString(): string;
abstract toString(options?: { color?: boolean }): string;
abstract toFullSignature(options?: { showDocs?: boolean }): string;

getNodes(): SchemaNode[] {
return [this];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ export class ArrayLiteralExpressionSchema extends SchemaNode {
toString(): string {
return `[${this.members.join(', ')}]`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
const membersStr = this.members.map((member) => member.toFullSignature(options)).join(', ');
return `[${membersStr}]`;
}
}
56 changes: 52 additions & 4 deletions components/entities/semantic-schema/schemas/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,58 @@ export class ClassSchema extends SchemaNode {
return this.members;
}

toString() {
const membersStr = this.members.map((m) => `* ${m.toString()}`).join('\n');
const decoratorsStr = this.decorators?.map((decorator) => decorator.toString()).join('\n');
return `${this.decorators ? `${decoratorsStr}\n` : ''}${chalk.bold.underline(this.name)}\n${membersStr}`;
toString(options?: { color?: boolean }): string {
const boldUnderline = options?.color ? chalk.bold.underline : (str: string) => str;
const membersStr = this.members.map((m) => `* ${m.toString(options)}`).join('\n');
const decoratorsStr = this.decorators?.map((decorator) => decorator.toString(options)).join('\n');
return `${this.decorators ? `${decoratorsStr}\n` : ''}${boldUnderline(this.name)}\n${membersStr}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
let result = '';

if (options?.showDocs && this.doc) {
result += `${this.doc.toFullSignature()}\n`;
}

const decoratorsStr = this.decorators?.map((decorator) => decorator.toFullSignature(options)).join('\n');
if (decoratorsStr) {
result += `${decoratorsStr}\n`;
}

let classDeclaration = `class ${this.name}`;

if (this.typeParams && this.typeParams.length > 0) {
classDeclaration += `<${this.typeParams.join(', ')}>`;
}

if (this.extendsNodes && this.extendsNodes.length > 0) {
const extendsStr = this.extendsNodes.map((node) => node.toFullSignature(options)).join(', ');
classDeclaration += ` extends ${extendsStr}`;
}

if (this.implementNodes && this.implementNodes.length > 0) {
const implementsStr = this.implementNodes.map((node) => node.toFullSignature(options)).join(', ');
classDeclaration += ` implements ${implementsStr}`;
}

result += `${classDeclaration} {\n`;

const membersStr = this.members
.map((member) => {
const memberStr = member.toFullSignature(options);
return memberStr
.split('\n')
.map((line) => ` ${line}`)
.join('\n');
})
.join('\n');

result += `${membersStr}\n`;

result += `}`;

return result;
}

toObject() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ export class ConditionalTypeSchema extends SchemaNode {
return `${this.checkType.toString()} extends ${this.extendsType.toString()} ? ${this.trueType.toString()} : ${this.falseType.toString()}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
const checkTypeStr = this.checkType.toFullSignature(options);
const extendsTypeStr = this.extendsType.toFullSignature(options);
const trueTypeStr = this.trueType.toFullSignature(options);
const falseTypeStr = this.falseType.toFullSignature(options);

return `${checkTypeStr} extends ${extendsTypeStr} ? ${trueTypeStr} : ${falseTypeStr}`;
}

toObject() {
return {
...super.toObject(),
Expand Down
15 changes: 14 additions & 1 deletion components/entities/semantic-schema/schemas/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,24 @@ export class DecoratorSchema extends SchemaNode {
}

toString() {
// name and args
const argsStr = this.args?.map((arg) => arg.toString()).join(', ');
return `@${this.name}${argsStr ? `(${argsStr})` : ''}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
let result = '';

if (options?.showDocs && this.doc) {
result += `${this.doc.toFullSignature()}\n`;
}

const argsStr = this.args?.map((arg) => arg.toFullSignature(options)).join(', ');

result += `@${this.name}${argsStr ? `(${argsStr})` : ''}`;

return result;
}

toObject() {
return {
...super.toObject(),
Expand Down
20 changes: 20 additions & 0 deletions components/entities/semantic-schema/schemas/docs/doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ export class DocSchema extends SchemaNode {
return `${comment}${tags}`;
}

toFullSignature(): string {
const lines: string[] = [];

if (this.comment) {
lines.push(...this.comment.split('\n').map((line) => ` * ${line.trim()}`));
}

if (this.tags && this.tags.length > 0) {
for (const tag of this.tags) {
lines.push(` * ${tag.toString().trim()}`);
}
}

if (lines.length === 0) {
return '';
}

return `/**\n${lines.join('\n')}\n */`;
}

hasTag(tagName: TagName) {
return Boolean(this.findTag(tagName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export class PropertyLikeTagSchema extends TagSchema {
return `@${this.tagName} ${this.name}${type} ${comment}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
const typeStr = this.type ? ` {${this.type.toFullSignature(options)}} ` : '';
const comment = this.comment ? ` ${this.comment}` : '';
return `@${this.tagName} ${this.name}${typeStr}${comment}`;
}

toObject() {
return {
...super.toObject(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export class ReturnTagSchema extends TagSchema {
return `@${this.tagName}${comment}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
const typeStr = this.type ? ` {${this.type.toFullSignature(options)}}` : '';
const comment = this.comment ? ` ${this.comment}` : '';
return `@${this.tagName}${typeStr}${comment}`;
}

toObject() {
return {
...super.toObject(),
Expand Down
4 changes: 4 additions & 0 deletions components/entities/semantic-schema/schemas/docs/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export class TagSchema extends SchemaNode {
return `@${this.tagName}${comment}`;
}

toFullSignature(): string {
return this.toString();
}

static fromObject(obj: Record<string, any>): TagSchema {
const location = obj.location;
const tagName = obj.tagName;
Expand Down
16 changes: 16 additions & 0 deletions components/entities/semantic-schema/schemas/enum-member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ export class EnumMemberSchema extends SchemaNode {
return `${this.name}=${this.value}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
let result = '';

if (options?.showDocs && this.doc) {
result += `${this.doc.toFullSignature()}\n`;
}

if (this.value !== undefined) {
result += `${this.name} = ${this.value}`;
} else {
result += `${this.name}`;
}

return result;
}

toObject() {
return {
...super.toObject(),
Expand Down
30 changes: 27 additions & 3 deletions components/entities/semantic-schema/schemas/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,33 @@ export class EnumSchema extends SchemaNode {
return this.members;
}

toString() {
const membersStr = this.members.map((m) => `* ${m.toString()}`).join('\n');
return `${chalk.bold.underline(this.name)}\n${membersStr}`;
toString(options) {
const boldUnderline = options?.color ? chalk.bold.underline : (str: string) => str;
const membersStr = this.members.map((m) => `* ${m.toString(options)}`).join('\n');
return `${boldUnderline(this.name)}\n${membersStr}`;
}

toFullSignature(options?: { showDocs?: boolean }): string {
let result = '';

if (options?.showDocs && this.doc) {
result += `${this.doc.toFullSignature()}\n`;
}

result += `enum ${this.name} {\n`;

const membersStr = this.members
.map((member) => {
const memberStr = member.toFullSignature(options);
return ` ${memberStr}`;
})
.join(',\n');

result += `${membersStr}\n`;

result += `}`;

return result;
}

toObject() {
Expand Down
46 changes: 42 additions & 4 deletions components/entities/semantic-schema/schemas/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class ExportSchema extends SchemaNode {
alias?: string;
exportNode: SchemaNode;
readonly doc?: DocSchema;
readonly signature?: string;

constructor(
readonly location: SchemaLocation,
Expand All @@ -18,13 +19,50 @@ export class ExportSchema extends SchemaNode {
this.exportNode = exportNode;
this.alias = alias;
this.doc = doc;
this.signature = exportNode.signature || this.toFullSignature();
}

toString() {
if (this.alias) {
return `${this.name} as ${this.alias}`;
toString(options?: { color?: boolean }): string {
let signature = '';

const alias = this.alias || this.name;
const originalName = this.exportNode.name || this.name;

if (alias !== originalName) {
signature += `export { ${originalName} as ${alias} };\n`;
} else {
signature += `export { ${originalName} };\n`;
}
return `${this.name}`;

const exportNodeSignature = this.exportNode.toString(options);

signature += `\n${exportNodeSignature}`;

return signature;
}

toFullSignature(options?: { showDocs?: boolean }): string {
let signature = '';

if (options?.showDocs && this.doc) {
const docString = this.doc.toFullSignature();
signature += `${docString}\n`;
}

const alias = this.alias || this.name;
const originalName = this.exportNode.name || this.name;

if (alias !== originalName) {
signature += `export { ${originalName} as ${alias} };\n`;
} else {
signature += `export { ${originalName} };\n`;
}

const exportNodeSignature = this.exportNode.toFullSignature(options);

signature += `\n${exportNodeSignature}`;

return signature;
}

toObject() {
Expand Down
Loading

0 comments on commit 8eb6644

Please sign in to comment.