Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: add graphql class decorators #58

Merged
merged 6 commits into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/models/common/decorators/property/classGraphql.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'reflect-metadata';
import { getTsTypesMapping } from '../../../layerMetadata/decorators/property/tsTypes.decorator';
import { IPropGraphQLMapping } from '../../interfaces/propGraphQLMapping.interface';
import { getGraphQLMapping } from './graphql.decorator';

const graphQLMetadataKey = Symbol('graphqlclassmapping');
type KeyValueDict = Record<string, unknown>;
const target = {};

export interface IGraphQLClassMapping {
name: string;
fields: IPropGraphQLMapping[];
}

export function graphqlClass(): ClassDecorator {
// eslint-disable-next-line @typescript-eslint/ban-types
return <TFunction extends Function>(graphqlmapping: TFunction) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const classInstance = new (graphqlmapping as any)();
const classData: IGraphQLClassMapping = {
fields: getGraphQLMappings(classInstance),
name: graphqlmapping.name,
};

const classDataList = getGraphQLClassMapping() ?? [];
classDataList.push(classData);
Reflect.defineMetadata(graphQLMetadataKey, classDataList, target);
return graphqlmapping;
};
}

export function getGraphQLClassMapping(): IGraphQLClassMapping[] | undefined {
return Reflect.getMetadata(graphQLMetadataKey, target) as IGraphQLClassMapping[];
}

export function getGraphQLMappings(object: KeyValueDict): IPropGraphQLMapping[] {
const ret = [];
for (const prop in object) {
const graphQLMap = getGraphQLMapping(object, prop);
const tsTypesMap = getTsTypesMapping(object, prop);
if (graphQLMap && tsTypesMap) {
ret.push({
prop: prop,
...graphQLMap,
...tsTypesMap,
});
}
}
return ret;
}
16 changes: 16 additions & 0 deletions src/models/common/decorators/property/graphql.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'reflect-metadata';

const graphQLMetadataKey = Symbol('graphqlmapping');

export interface IGraphQLMapping {
nullable?: boolean;
}

export function graphql(graphqlmapping?: IGraphQLMapping): PropertyDecorator {
const defaultMapping: IGraphQLMapping = { nullable: false };
return Reflect.metadata(graphQLMetadataKey, graphqlmapping ?? defaultMapping);
}

export function getGraphQLMapping<T>(target: T, propertyKey: string): IGraphQLMapping | undefined {
return Reflect.getMetadata(graphQLMetadataKey, target, propertyKey) as IGraphQLMapping;
}
6 changes: 6 additions & 0 deletions src/models/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './decorators/property/graphql.decorator';
export * from './decorators/property/classGraphql.decorator';
export * from './interfaces/ormCatalog.interface';
export * from './interfaces/propCatalogDBMapping.interface';
export * from './interfaces/propGraphQLMapping.interface';
export * from '../layerMetadata/link';
6 changes: 0 additions & 6 deletions src/models/common/interfaces/link.interface.ts

This file was deleted.

6 changes: 6 additions & 0 deletions src/models/common/interfaces/propGraphQLMapping.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { IGraphQLMapping } from '../decorators/property/graphql.decorator';
import { ITsTypesMapping } from '../../layerMetadata/decorators/property/tsTypes.decorator';

export interface IPropGraphQLMapping extends IGraphQLMapping, ITsTypesMapping {
prop: string;
}
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './common/index';
export * from './layerMetadata/index';
export * from './discreteIngestion/index';
export * from './layerMetadata/pycswLayerCatalogRecord';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'reflect-metadata';
import { TsTypes } from './tsTypes.decorator';
import { IDescribeTsType } from './tsTypes.decorator';

const catalogDbMetadataKey = Symbol('catalogdbmapping');

Expand All @@ -15,7 +15,7 @@ export interface IColumnProps {
}

export interface IFieldProps {
overrideType?: TsTypes;
overrideType?: IDescribeTsType;
}

export interface ICatalogDBMapping {
Expand Down
56 changes: 48 additions & 8 deletions src/models/layerMetadata/decorators/property/tsTypes.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,58 @@ import 'reflect-metadata';

const tsTypesMetadataKey = Symbol('catalogdbmapping');

export enum TsTypes {
STRING = 'string',
BOOLEAN = 'boolean',
DATE = 'Date',
NUMBER = 'number',
export enum PropertiesTypes {
PRIMITIVE = 'primitive',
ENUM = 'enum',
CLASS = 'class',
ARRAY = 'array',
OBJECT = 'object',
LINK = 'Link',
LINKS = 'Link[]',
}
export interface IDescribeTsType {
value: string;
type: PropertiesTypes;
importFromPackage?: string;
}

/* eslint-disable @typescript-eslint/naming-convention */
export const TsTypes: Record<string, IDescribeTsType> = {
STRING: {
value: 'string',
type: PropertiesTypes.PRIMITIVE,
},
BOOLEAN: {
value: 'boolean',
type: PropertiesTypes.PRIMITIVE,
},
DATE: {
value: 'Date',
type: PropertiesTypes.PRIMITIVE,
},
NUMBER: {
value: 'number',
type: PropertiesTypes.PRIMITIVE,
},
OBJECT: {
value: 'object',
type: PropertiesTypes.OBJECT,
},
LINK: {
value: 'Link',
type: PropertiesTypes.CLASS,
},
LINKS: {
value: 'Link',
type: PropertiesTypes.ARRAY,
},
SENSORTYPE: {
value: 'SensorType',
type: PropertiesTypes.ENUM,
importFromPackage: '@map-colonies/mc-model-types',
},
};
/* eslint-enable @typescript-eslint/naming-convention */
export interface ITsTypesMapping {
mappingType: TsTypes;
mappingType: IDescribeTsType;
}

export function tsTypes(tsTypesMapping: ITsTypesMapping): PropertyDecorator {
Expand Down
2 changes: 1 addition & 1 deletion src/models/layerMetadata/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export * from './layerMetadata';
export * from './layerMetadata-StatusFields';

export { IShpMapping, ShapeFileType } from './decorators/property/shp.decorator';
export { TsTypes } from './decorators/property/tsTypes.decorator';
export { TsTypes, IDescribeTsType, PropertiesTypes } from './decorators/property/tsTypes.decorator';
export { IPYCSWMapping } from './decorators/property/csw.decorator';
export { IColumnProps } from './decorators/property/catalogDB.decorator';
export { IOrmCatalog } from '../common/interfaces/ormCatalog.interface';
39 changes: 38 additions & 1 deletion src/models/layerMetadata/layerMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GeoJSON } from 'geojson';
import { IPropCatalogDBMapping } from '../common/interfaces/propCatalogDBMapping.interface';
import { graphql } from '../common/decorators/property/graphql.decorator';
import { getPyCSWMapping, IPYCSWMapping, pycsw } from './decorators/property/csw.decorator';
import { getShpMapping, IShpMapping, ShapeFileType, shpMapping } from './decorators/property/shp.decorator';
import { getCatalogDBMapping, ICatalogDBMapping, catalogDB } from './decorators/property/catalogDB.decorator';
Expand Down Expand Up @@ -58,6 +59,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public source?: string = undefined;

/**
Expand All @@ -82,6 +86,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public sourceName?: string = undefined;

/**
Expand All @@ -106,6 +113,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.DATE,
})
@graphql({
nullable: true,
})
public updateDate?: Date = undefined;

/**
Expand All @@ -130,6 +140,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.NUMBER,
})
@graphql({
nullable: true,
})
public resolution?: number = undefined;

/**
Expand All @@ -155,6 +168,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.NUMBER,
})
@graphql({
nullable: true,
})
public ep90?: number = undefined;

/**
Expand All @@ -177,7 +193,10 @@ export class LayerMetadata implements ILayerMetadata {
valuePath: 'features[0].properties.SensorType',
})
@tsTypes({
mappingType: TsTypes.STRING,
mappingType: TsTypes.SENSORTYPE,
})
@graphql({
nullable: true,
})
public sensorType?: SensorType = undefined;

Expand All @@ -204,6 +223,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.NUMBER,
})
@graphql({
nullable: true,
})
public rms?: number = undefined;

/**
Expand All @@ -229,6 +251,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public scale?: string = undefined;

/**
Expand All @@ -254,6 +279,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public dsc?: string = undefined;

/**
Expand All @@ -279,6 +307,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.OBJECT,
})
@graphql({
nullable: true,
})
public geometry?: GeoJSON = undefined;

/**
Expand All @@ -300,6 +331,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public id?: string = undefined;

/**
Expand All @@ -321,6 +355,9 @@ export class LayerMetadata implements ILayerMetadata {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public version?: string = undefined;

public static getPyCSWMapping(prop: string): IPYCSWMapping | undefined {
Expand Down
34 changes: 34 additions & 0 deletions src/models/layerMetadata/link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { graphqlClass } from '../common/decorators/property/classGraphql.decorator';
import { graphql } from '../common/decorators/property/graphql.decorator';
import { TsTypes, tsTypes } from './decorators/property/tsTypes.decorator';

@graphqlClass()
export class Link {
@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public name?: string = undefined;

@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql({
nullable: true,
})
public description?: string = undefined;

@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql()
public protocol?: string = undefined;

@tsTypes({
mappingType: TsTypes.STRING,
})
@graphql()
public url?: string = undefined;
}
Loading