Skip to content

Commit 067388b

Browse files
author
t.kosminov
committed
change vscode debug config, add subscriptions support, add auto select tables pk in loaders, add peer deps
1 parent 8bc4c49 commit 067388b

File tree

13 files changed

+886
-477
lines changed

13 files changed

+886
-477
lines changed

.vscode/launch.json

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"type": "pwa-node",
8+
"type": "node",
99
"request": "launch",
10-
"name": "Launch Program",
11-
"skipFiles": [
12-
"<node_internals>/**"
10+
"name": "debug",
11+
"cwd": "${workspaceFolder}",
12+
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ts-node",
13+
"args": [
14+
"${workspaceFolder}/src/main.ts",
15+
"--runInBand",
16+
"--no-cache",
1317
],
14-
"program": "${workspaceFolder}/src/main.ts"
18+
"runtimeArgs": [
19+
"--files",
20+
"-r",
21+
"${workspaceFolder}/node_modules/tsconfig-paths/register"
22+
],
23+
"env": {
24+
"NODE_ENV": "development",
25+
"TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json"
26+
},
1527
}
1628
]
1729
}

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,21 @@ import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
4848
...
4949
import { Request } from 'express';
5050
import { DataSource } from 'typeorm';
51+
import { setDataSource } from 'nestjs-graphql-easy' // <-- ADD
5152
5253
@Injectable()
5354
export class GraphqlOptions implements GqlOptionsFactory {
54-
constructor(private readonly dataSource: DataSource) {} // <-- ADD
55+
constructor(private readonly dataSource: DataSource) { // <-- ADD
56+
setDataSource(this.dataSource); // <-- ADD
57+
}
5558

5659
public createGqlOptions(): Promise<ApolloDriverConfig> | ApolloDriverConfig {
5760
return {
5861
...
5962
driver: ApolloDriver,
6063
context: ({ req }: { req: Request }) => ({
6164
req,
62-
data_source: this.dataSource, // <-- ADD
65+
data_source: this.dataSource, // <-- DEPRECATED. But this will still work if no subscriptions are used
6366
}),
6467
...
6568
};

lib/error/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,19 @@ export const bad_request = (data?: IErrData) => {
2020

2121
return err;
2222
};
23+
24+
export const invalid_data_source = (data?: IErrData) => {
25+
const err = new HttpException(
26+
{
27+
status: 500,
28+
error: data?.msg || 'INVALID_DATA_SOURCE',
29+
},
30+
500
31+
);
32+
33+
if (data?.raise) {
34+
throw err;
35+
}
36+
37+
return err;
38+
};

lib/loader/decorator.loader.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { underscore } from '../helper';
99
import { IFilterValue, IParsedFilter, parseFilter } from '../filter/parser.filter';
1010
import { IOrderValue, IParsedOrder, parseOrder } from '../order/parser.order';
1111
import { IPaginationValue, IParsedPagination, parsePagination } from '../pagination/parser.pagination';
12-
import { getTableColumns, getTableForeignKeys } from '../store';
12+
import { getTableColumns, getTableForeignKeys, getTablePrimaryKeys } from '../store';
13+
import { invalid_data_source } from '../error';
1314

1415
import { manyToOneLoader } from './many-to-one.loader';
1516
import { oneToManyLoader } from './one-to-many.loader';
@@ -44,6 +45,12 @@ export interface IPrivateLoaderData extends ILoaderData {
4445
entity_manager?: EntityManager;
4546
}
4647

48+
let data_source: DataSource = null;
49+
50+
export function setDataSource(ds: DataSource) {
51+
data_source = ds;
52+
}
53+
4754
export const Loader = createParamDecorator((data: ILoaderData, ctx: ExecutionContext) => {
4855
const args = ctx.getArgs();
4956

@@ -89,16 +96,27 @@ export const Loader = createParamDecorator((data: ILoaderData, ctx: ExecutionCon
8996
const selected_fields = recursiveSelectedFields(_data, info.fieldNodes, info.fragments);
9097
const entity_table_columns = getTableColumns(entity_class_name);
9198
const entity_table_foreign_keys = getTableForeignKeys(entity_class_name);
99+
const entity_table_primary_keys = getTablePrimaryKeys(entity_class_name);
92100

93101
const selected_columns = new Set(Array.from(selected_fields).filter((field) => entity_table_columns.has(field)));
94102

95103
entity_table_foreign_keys.forEach((fk) => {
96104
selected_columns.add(fk);
97105
});
98106

107+
entity_table_primary_keys.forEach((pk) => {
108+
selected_columns.add(pk);
109+
});
110+
99111
if (!_data.entity_manager) {
100112
if (!gctx['entity_manager']) {
101-
gctx['entity_manager'] = gctx.data_source.createEntityManager();
113+
if (data_source) {
114+
gctx['entity_manager'] = data_source.createEntityManager();
115+
} else if (gctx?.data_source) {
116+
gctx['entity_manager'] = gctx.data_source.createEntityManager();
117+
} else {
118+
invalid_data_source({ raise: true });
119+
}
102120
}
103121

104122
_data.entity_manager = gctx['entity_manager'];

lib/loader/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { Loader, ELoaderType, ILoaderData } from './decorator.loader';
1+
export { Loader, ELoaderType, ILoaderData, setDataSource } from './decorator.loader';

lib/store/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ export {
99
PrimaryGeneratedColumn,
1010
getTableColumns,
1111
getTableForeignKeys,
12+
getTablePrimaryKeys,
1213
} from './typeorm';

lib/store/typeorm.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export const table_columns: Map<string, Set<string>> = new Map();
4040
*/
4141
export const table_foreign_keys: Map<string, Set<string>> = new Map();
4242

43+
/**
44+
* Map<entity_class_name, Set<entity_column_name>>
45+
*/
46+
export const table_primary_keys: Map<string, Set<string>> = new Map();
47+
4348
export function getTableColumns(entity_class_name: string) {
4449
if (table_columns.has(entity_class_name)) {
4550
return table_columns.get(entity_class_name);
@@ -80,6 +85,28 @@ export function getTableForeignKeys(entity_class_name: string) {
8085
return table_foreign_keys.get(entity_class_name) || new Set();
8186
}
8287

88+
export function getTablePrimaryKeys(entity_class_name: string) {
89+
if (table_primary_keys.has(entity_class_name)) {
90+
return table_primary_keys.get(entity_class_name);
91+
}
92+
93+
const typeormArgs = getMetadataArgsStorage();
94+
95+
typeormArgs.columns.forEach((col) => {
96+
if (col.options?.primary) {
97+
if (!table_primary_keys.has(col.target['name'])) {
98+
table_primary_keys.set(col.target['name'], new Set([]));
99+
}
100+
101+
const fks = table_primary_keys.get(col.target['name']);
102+
103+
fks.add(col.propertyName);
104+
}
105+
});
106+
107+
return table_primary_keys.get(entity_class_name) || new Set();
108+
}
109+
83110
export function PolymorphicColumn(): PropertyDecorator {
84111
return (prototype: any, property_key: string) => {
85112
if (!table_foreign_keys.has(prototype['constructor']['name'])) {

0 commit comments

Comments
 (0)