Skip to content

Commit

Permalink
feat(Schema): Ignore schema (#8559)
Browse files Browse the repository at this point in the history
  • Loading branch information
luvkapur authored Feb 21, 2024
1 parent 5f74b6f commit 48315d1
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 21 deletions.
14 changes: 14 additions & 0 deletions components/entities/semantic-schema/schemas/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,18 @@ export class ClassSchema extends SchemaNode {
decorators
);
}

static fromSchema(node: ClassSchema, memberTransformer: (_node: SchemaNode) => SchemaNode = (_node) => _node) {
return new ClassSchema(
node.name,
node.members.map(memberTransformer),
node.location,
node.signature,
node.doc,
node.typeParams,
node.extendsNodes,
node.implementNodes,
node.decorators
);
}
}
39 changes: 39 additions & 0 deletions components/entities/semantic-schema/schemas/ignored.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { DocSchema, SchemaRegistry } from '..';
import { SchemaLocation, SchemaNode } from '../schema-node';

export class IgnoredSchema extends SchemaNode {
public location: SchemaLocation;
public doc?: DocSchema;
public name?: string;

constructor(public readonly node: SchemaNode) {
super();
this.location = node.location;
this.doc = node.doc;
this.name = node.name;
}

getNodes() {
return [];
}

getAllNodesRecursively(): SchemaNode[] {
return [];
}

toString() {
return '';
}

toObject() {
return {
...super.toObject(),
node: this.node.toObject(),
};
}

static fromObject(obj: Record<string, any>): IgnoredSchema {
const node = SchemaRegistry.fromObject(obj.node);
return new IgnoredSchema(node);
}
}
1 change: 1 addition & 0 deletions components/entities/semantic-schema/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ export { ArrayLiteralExpressionSchema } from './array-literal-expression';
export { PropertyAssignmentSchema } from './property-assignment';
export { DecoratorSchema } from './decorator';
export { LiteralValueSchema } from './literal-value';
export { IgnoredSchema } from './ignored';
export * from './docs';
9 changes: 8 additions & 1 deletion scopes/envs/envs/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { DependencyDetector, EnvPolicyConfigObject } from '@teambit/depende
import type { Capsule } from '@teambit/isolator';
import type { Component } from '@teambit/component';
import { EnvPreviewConfig } from '@teambit/preview';
import { SchemaNodeTransformer, SchemaTransformer } from '@teambit/typescript';

export type EnvDescriptor = {
type: string;
Expand Down Expand Up @@ -47,7 +48,13 @@ export interface Environment {
/**
* Returns a schema generator instance
*/
getSchemaExtractor?: (config?: any, tsserverPath?: string, contextPath?: string) => SchemaExtractor;
getSchemaExtractor?: (
config?: any,
tsserverPath?: string,
contextPath?: string,
schemaTransformers?: SchemaTransformer[],
apiTransformers?: SchemaNodeTransformer[]
) => SchemaExtractor;

/**
* Returns the dev patterns to match doc files
Expand Down
13 changes: 11 additions & 2 deletions scopes/semantics/schema/schema.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { BuilderMain, BuilderAspect } from '@teambit/builder';
import { Workspace, WorkspaceAspect } from '@teambit/workspace';
import { ScopeAspect, ScopeMain } from '@teambit/scope';
import { Formatter } from '@teambit/formatter';
import { SchemaNodeTransformer, SchemaTransformer } from '@teambit/typescript';
import { Parser } from './parser';
import { SchemaAspect } from './schema.aspect';
import { SchemaExtractor } from './schema-extractor';
Expand Down Expand Up @@ -110,7 +111,9 @@ export class SchemaMain {
alwaysRunExtractor = false,
tsserverPath?: string,
contextPath?: string,
skipInternals?: boolean
skipInternals?: boolean,
schemaTransformers?: SchemaTransformer[],
apiTransformers?: SchemaNodeTransformer[]
): Promise<APISchema> {
if (this.config.disabled) {
return APISchema.empty(component.id as any);
Expand All @@ -128,7 +131,13 @@ export class SchemaMain {
if (typeof env.getSchemaExtractor === 'undefined') {
throw new Error(`No SchemaExtractor defined for ${env.name}`);
}
const schemaExtractor: SchemaExtractor = env.getSchemaExtractor(undefined, tsserverPath, contextPath);
const schemaExtractor: SchemaExtractor = env.getSchemaExtractor(
undefined,
tsserverPath,
contextPath,
schemaTransformers,
apiTransformers
);

const result = await schemaExtractor.extract(component, { formatter, tsserverPath, contextPath, skipInternals });
if (shouldDisposeResourcesOnceDone) schemaExtractor.dispose();
Expand Down
12 changes: 12 additions & 0 deletions scopes/typescript/typescript/extractor-options.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SchemaNodeTransformer, SchemaTransformer } from './schema-transformer';

export type ExtractorOptions = {
/**
* name of the string.
Expand All @@ -18,4 +20,14 @@ export type ExtractorOptions = {
* typescript compiler options. always overrides all.
*/
compilerOptions?: string;

/**
* schema transformers.
*/
schemaTransformers?: SchemaTransformer[];

/**
* api transformers.
*/
apiTransformers?: SchemaNodeTransformer[];
};
7 changes: 6 additions & 1 deletion scopes/typescript/typescript/schema-extractor-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
InferenceTypeSchema,
Location,
DocSchema,
IgnoredSchema,
} from '@teambit/semantics.entities.semantic-schema';
import isRelativeImport from '@teambit/legacy/dist/utils/is-relative-import';
import { ComponentDependency } from '@teambit/dependency-resolver';
Expand Down Expand Up @@ -492,7 +493,11 @@ export class SchemaExtractorContext {
}

const apiTransformer = this.extractor.getAPITransformer(schemaNode);
return apiTransformer ? apiTransformer.transform(schemaNode, this) : schemaNode;
let transformedApi = apiTransformer ? await apiTransformer.transform(schemaNode, this) : schemaNode;
if (!transformedApi) {
transformedApi = new IgnoredSchema(schemaNode);
}
return transformedApi;
}

private getCompIdByPkgName(pkgName: string): ComponentID | undefined {
Expand Down
3 changes: 1 addition & 2 deletions scopes/typescript/typescript/schema-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export type SchemaTransformer = {
predicate(node: Node): boolean;

getIdentifiers(node: Node, context: SchemaExtractorContext): Promise<Identifier[]>;

/**
* transform the node into JSONSchema.
*/
Expand All @@ -19,5 +18,5 @@ export type SchemaTransformer = {

export type SchemaNodeTransformer = {
predicate(node: SchemaNode): boolean;
transform(node: SchemaNode, context: SchemaExtractorContext): Promise<SchemaNode>;
transform(node: SchemaNode, context: SchemaExtractorContext): Promise<SchemaNode | null>;
};
41 changes: 29 additions & 12 deletions scopes/typescript/typescript/typescript.extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import { SchemaExtractor, SchemaExtractorOptions } from '@teambit/schema';
import { TsserverClient } from '@teambit/ts-server';
import type { Workspace } from '@teambit/workspace';
import { ComponentDependency, DependencyResolverMain } from '@teambit/dependency-resolver';
import { SchemaNode, APISchema, ModuleSchema, UnImplementedSchema } from '@teambit/semantics.entities.semantic-schema';
import {
SchemaNode,
APISchema,
ModuleSchema,
UnImplementedSchema,
IgnoredSchema,
} from '@teambit/semantics.entities.semantic-schema';
import { Component } from '@teambit/component';
import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
import { EnvContext } from '@teambit/envs';
Expand All @@ -14,19 +20,20 @@ import { AspectLoaderAspect, AspectLoaderMain, getCoreAspectPackageName } from '
import { ScopeMain } from '@teambit/scope';
import pMapSeries from 'p-map-series';
import { compact, flatten } from 'lodash';
import { TypescriptMain, SchemaTransformerSlot, APITransformerSlot } from './typescript.main.runtime';
import { TypescriptMain } from './typescript.main.runtime';
import { TransformerNotFound } from './exceptions';
import { SchemaExtractorContext } from './schema-extractor-context';
import { Identifier } from './identifier';
import { IdentifierList } from './identifier-list';
import { ExtractorOptions } from './extractor-options';
import { TypescriptAspect } from './typescript.aspect';
import { SchemaNodeTransformer, SchemaTransformer } from './schema-transformer';

export class TypeScriptExtractor implements SchemaExtractor {
constructor(
private tsconfig: any,
private schemaTransformerSlot: SchemaTransformerSlot,
private apiTransformerSlot: APITransformerSlot,
private schemaTransformers: SchemaTransformer[],
private apiTransformers: SchemaNodeTransformer[],
private tsMain: TypescriptMain,
private rootTsserverPath: string,
private rootContextPath: string,
Expand Down Expand Up @@ -179,7 +186,11 @@ export class TypeScriptExtractor implements SchemaExtractor {

async transformAPI(schema: SchemaNode, context: SchemaExtractorContext): Promise<SchemaNode> {
const apiTransformer = this.getAPITransformer(schema);
return apiTransformer ? apiTransformer.transform(schema, context) : schema;
const transformedApi = apiTransformer ? await apiTransformer.transform(schema, context) : schema;
if (!transformedApi) {
return new IgnoredSchema(schema);
}
return transformedApi;
}

async getComponentIDByPath(file: string) {
Expand All @@ -200,8 +211,7 @@ export class TypeScriptExtractor implements SchemaExtractor {
* select the correct transformer for a node.
*/
getTransformer(node: Node, context: SchemaExtractorContext) {
const transformers = flatten(this.schemaTransformerSlot.values());
const transformer = transformers.find((singleTransformer) => {
const transformer = this.schemaTransformers.find((singleTransformer) => {
return singleTransformer.predicate(node);
});
if (!transformer) {
Expand All @@ -213,8 +223,7 @@ export class TypeScriptExtractor implements SchemaExtractor {
}

getAPITransformer(node: SchemaNode) {
const transformers = flatten(this.apiTransformerSlot.values());
const transformer = transformers.find((singleTransformer) => {
const transformer = this.apiTransformers.find((singleTransformer) => {
return singleTransformer.predicate(node);
});
if (!transformer) {
Expand All @@ -229,14 +238,22 @@ export class TypeScriptExtractor implements SchemaExtractor {
const tsconfig = getTsconfig(options.tsconfig)?.config || { compilerOptions: options.compilerOptions };
const tsMain = context.getAspect<TypescriptMain>(TypescriptAspect.id);
const aspectLoaderMain = context.getAspect<AspectLoaderMain>(AspectLoaderAspect.id);

// When loading the env from a scope you don't have a workspace
const rootPath = tsMain.workspace?.path || tsMain.scope.path || '';

const schemaTransformersFromOptions = options.schemaTransformers || [];
const schemaTransformersFromAspect = flatten(Array.from(tsMain.schemaTransformerSlot.values()));

const apiTransformersFromOptions = options.apiTransformers || [];
const apiTransformersFromAspect = flatten(Array.from(tsMain.apiTransformerSlot.values()));

const schemaTransformers = [...schemaTransformersFromOptions, ...schemaTransformersFromAspect];
const apiTransformers = [...apiTransformersFromOptions, ...apiTransformersFromAspect];

return new TypeScriptExtractor(
tsconfig,
tsMain.schemaTransformerSlot,
tsMain.apiTransformerSlot,
schemaTransformers,
apiTransformers,
tsMain,
rootPath,
rootPath,
Expand Down
19 changes: 16 additions & 3 deletions scopes/typescript/typescript/typescript.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { Component, ComponentID } from '@teambit/component';
import { BuilderAspect, BuilderMain } from '@teambit/builder';
import { EnvsAspect, EnvsMain } from '@teambit/envs';
import { ScopeMain, ScopeAspect } from '@teambit/scope';
import { flatten } from 'lodash';
import { TypeScriptExtractor } from './typescript.extractor';
import { TypeScriptCompilerOptions } from './compiler-options';
import { TypescriptAspect } from './typescript.aspect';
Expand Down Expand Up @@ -225,11 +226,23 @@ export class TypescriptMain {
/**
* create an instance of a typescript semantic schema extractor.
*/
createSchemaExtractor(tsconfig: any, tsserverPath?: string, contextPath?: string): SchemaExtractor {
createSchemaExtractor(
tsconfig: any,
tsserverPath?: string,
contextPath?: string,
schemaTransformers: SchemaTransformer[] = [],
apiTransformers: SchemaNodeTransformer[] = []
): SchemaExtractor {
const schemaTransformersFromSlot = flatten(Array.from(this.schemaTransformerSlot.values()));
const apiTransformersFromSlot = flatten(Array.from(this.apiTransformerSlot.values()));

const allSchemaTransformers = schemaTransformers.concat(schemaTransformersFromSlot);
const allApiTransformers = apiTransformers.concat(apiTransformersFromSlot);

return new TypeScriptExtractor(
tsconfig,
this.schemaTransformerSlot,
this.apiTransformerSlot,
allSchemaTransformers,
allApiTransformers,
this,
tsserverPath || this.workspace?.path || '',
contextPath || this.workspace?.path || '',
Expand Down

0 comments on commit 48315d1

Please sign in to comment.