@tinkerstack/graphql-annotation 0.0.4 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,47 +1,47 @@
1
- import { DynamicModule, Module } from "@nestjs/common";
2
- import { DiscoveryModule } from "@nestjs/core";
3
- import { GraphQLAnnotationResolver } from "./annotation.resolver";
4
- import { GraphQLAnnotatedSchemaLoader } from "./annotation.loader";
5
- import { ResolverDiscoveryService } from "./resolver.explorer";
6
- import {
7
- ANNOTATION_RESOLVER_METADATA,
8
- GraphQLAnnotationResolverMetadata,
9
- } from "./annotation.constants";
10
-
11
- @Module({})
12
- export class GraphQLAnnotationModule {
13
- static forRoot(opts?: { serveAnnotations?: false }): DynamicModule;
14
- static forRoot(opts: {
15
- serveAnnotations: true;
16
- serveConfig: GraphQLAnnotationResolverMetadata;
17
- }): DynamicModule;
18
- static forRoot(opts?: {
19
- serveAnnotations?: boolean;
20
- serveConfig?: GraphQLAnnotationResolverMetadata;
21
- }): DynamicModule {
22
- if (opts?.serveAnnotations)
23
- return {
24
- global: true,
25
- module: GraphQLAnnotationModule,
26
- imports: [DiscoveryModule],
27
- providers: [
28
- ResolverDiscoveryService,
29
- GraphQLAnnotatedSchemaLoader,
30
- {
31
- provide: ANNOTATION_RESOLVER_METADATA,
32
- useValue: opts.serveConfig!,
33
- },
34
- GraphQLAnnotationResolver,
35
- ],
36
- exports: [GraphQLAnnotatedSchemaLoader],
37
- };
38
-
39
- return {
40
- global: true,
41
- module: GraphQLAnnotationModule,
42
- imports: [DiscoveryModule],
43
- providers: [ResolverDiscoveryService, GraphQLAnnotatedSchemaLoader],
44
- exports: [GraphQLAnnotatedSchemaLoader],
45
- };
46
- }
47
- }
1
+ import { DynamicModule, Module } from "@nestjs/common";
2
+ import { DiscoveryModule } from "@nestjs/core";
3
+ import { GraphQLAnnotationResolver } from "./annotation.resolver";
4
+ import { GraphQLAnnotatedSchemaLoader } from "./annotation.loader";
5
+ import { ResolverDiscoveryService } from "./resolver.explorer";
6
+ import {
7
+ ANNOTATION_RESOLVER_METADATA,
8
+ GraphQLAnnotationResolverMetadata,
9
+ } from "./annotation.constants";
10
+
11
+ @Module({})
12
+ export class GraphQLAnnotationModule {
13
+ static forRoot(opts?: { serveAnnotations?: false }): DynamicModule;
14
+ static forRoot(opts: {
15
+ serveAnnotations: true;
16
+ serveConfig: GraphQLAnnotationResolverMetadata;
17
+ }): DynamicModule;
18
+ static forRoot(opts?: {
19
+ serveAnnotations?: boolean;
20
+ serveConfig?: GraphQLAnnotationResolverMetadata;
21
+ }): DynamicModule {
22
+ if (opts?.serveAnnotations)
23
+ return {
24
+ global: true,
25
+ module: GraphQLAnnotationModule,
26
+ imports: [DiscoveryModule],
27
+ providers: [
28
+ ResolverDiscoveryService,
29
+ GraphQLAnnotatedSchemaLoader,
30
+ {
31
+ provide: ANNOTATION_RESOLVER_METADATA,
32
+ useValue: opts.serveConfig!,
33
+ },
34
+ GraphQLAnnotationResolver,
35
+ ],
36
+ exports: [GraphQLAnnotatedSchemaLoader],
37
+ };
38
+
39
+ return {
40
+ global: true,
41
+ module: GraphQLAnnotationModule,
42
+ imports: [DiscoveryModule],
43
+ providers: [ResolverDiscoveryService, GraphQLAnnotatedSchemaLoader],
44
+ exports: [GraphQLAnnotatedSchemaLoader],
45
+ };
46
+ }
47
+ }
@@ -1,87 +1,87 @@
1
- import { Inject, Injectable, Logger, OnModuleInit } from "@nestjs/common";
2
- import { MetadataScanner } from "@nestjs/core";
3
- import { Field, ObjectType, Query, Resolver } from "@nestjs/graphql";
4
- import { GraphQLJSONObject } from "graphql-scalars";
5
- import "reflect-metadata";
6
- import type {
7
- AnnotationInfo,
8
- GraphQLAnnotationResolverMetadata,
9
- GraphQLResolversAnnotations,
10
- } from "./annotation.constants";
11
- import {
12
- ANNOTATION_METADATA,
13
- ANNOTATION_RESOLVER_METADATA,
14
- } from "./annotation.constants";
15
- import { ResolverDiscoveryService } from "./resolver.explorer";
16
-
17
- @ObjectType()
18
- export class GraphQLAnnotationMeta {
19
- @Field(() => String)
20
- name: string;
21
-
22
- @Field(() => GraphQLJSONObject, { name: "resolvers" })
23
- resolvers: GraphQLResolversAnnotations;
24
- }
25
-
26
- export const ANNOTATION_QUERY_NAME = "_annotations";
27
-
28
- @Resolver()
29
- @Injectable()
30
- export class GraphQLAnnotationResolver implements OnModuleInit {
31
- private _logger = new Logger("GraphQLAnnotationModule");
32
-
33
- constructor(
34
- private readonly metadataScanner: MetadataScanner,
35
- private readonly resolverDiscoveryService: ResolverDiscoveryService,
36
- @Inject(ANNOTATION_RESOLVER_METADATA)
37
- private readonly meta: GraphQLAnnotationResolverMetadata,
38
- ) {}
39
-
40
- @Query(() => GraphQLAnnotationMeta, {
41
- name: ANNOTATION_QUERY_NAME,
42
- })
43
- async getGraphQLAnnotations() {
44
- return {
45
- ...this.meta,
46
- resolvers: this.resolverAnnotations,
47
- } satisfies GraphQLAnnotationMeta;
48
- }
49
-
50
- private resolverAnnotations = {} as GraphQLResolversAnnotations;
51
- async onModuleInit() {
52
- this.resolverAnnotations = this.compileResolversAnnotations();
53
- }
54
-
55
- private compileResolversAnnotations() {
56
- const instances = this.resolverDiscoveryService.explore();
57
- const resolversAnnotations = {} as GraphQLResolversAnnotations;
58
-
59
- for (const { instance } of instances)
60
- for (const methodName of this.metadataScanner.getAllMethodNames(
61
- Object.getPrototypeOf(instance),
62
- )) {
63
- const annotations = [
64
- ...Object.values(
65
- Reflect.getMetadata(ANNOTATION_METADATA, instance[methodName]) ??
66
- {},
67
- ),
68
- ...Object.values(
69
- Reflect.getMetadata(
70
- ANNOTATION_METADATA,
71
- instance.constructor,
72
- methodName,
73
- ) ?? {},
74
- ),
75
- ] as AnnotationInfo[];
76
-
77
- if (annotations.length <= 0) continue;
78
-
79
- resolversAnnotations[methodName] = annotations;
80
- this._logger.log(
81
- `Discovered annotated resolver "${instance.constructor.name}.${methodName}" with ${annotations.length} annotation(s)`,
82
- );
83
- }
84
-
85
- return resolversAnnotations;
86
- }
87
- }
1
+ import { Inject, Injectable, Logger, OnModuleInit } from "@nestjs/common";
2
+ import { MetadataScanner } from "@nestjs/core";
3
+ import { Field, ObjectType, Query, Resolver } from "@nestjs/graphql";
4
+ import { GraphQLJSONObject } from "graphql-scalars";
5
+ import "reflect-metadata";
6
+ import type {
7
+ AnnotationInfo,
8
+ GraphQLAnnotationResolverMetadata,
9
+ GraphQLResolversAnnotations,
10
+ } from "./annotation.constants";
11
+ import {
12
+ ANNOTATION_METADATA,
13
+ ANNOTATION_RESOLVER_METADATA,
14
+ } from "./annotation.constants";
15
+ import { ResolverDiscoveryService } from "./resolver.explorer";
16
+
17
+ @ObjectType()
18
+ export class GraphQLAnnotationMeta {
19
+ @Field(() => String)
20
+ name: string;
21
+
22
+ @Field(() => GraphQLJSONObject, { name: "resolvers" })
23
+ resolvers: GraphQLResolversAnnotations;
24
+ }
25
+
26
+ export const ANNOTATION_QUERY_NAME = "_annotations";
27
+
28
+ @Resolver()
29
+ @Injectable()
30
+ export class GraphQLAnnotationResolver implements OnModuleInit {
31
+ private _logger = new Logger("GraphQLAnnotationModule");
32
+
33
+ constructor(
34
+ private readonly metadataScanner: MetadataScanner,
35
+ private readonly resolverDiscoveryService: ResolverDiscoveryService,
36
+ @Inject(ANNOTATION_RESOLVER_METADATA)
37
+ private readonly meta: GraphQLAnnotationResolverMetadata,
38
+ ) {}
39
+
40
+ @Query(() => GraphQLAnnotationMeta, {
41
+ name: ANNOTATION_QUERY_NAME,
42
+ })
43
+ async getGraphQLAnnotations() {
44
+ return {
45
+ ...this.meta,
46
+ resolvers: this.resolverAnnotations,
47
+ } satisfies GraphQLAnnotationMeta;
48
+ }
49
+
50
+ private resolverAnnotations = {} as GraphQLResolversAnnotations;
51
+ async onModuleInit() {
52
+ this.resolverAnnotations = this.compileResolversAnnotations();
53
+ }
54
+
55
+ private compileResolversAnnotations() {
56
+ const instances = this.resolverDiscoveryService.explore();
57
+ const resolversAnnotations = {} as GraphQLResolversAnnotations;
58
+
59
+ for (const { instance } of instances)
60
+ for (const methodName of this.metadataScanner.getAllMethodNames(
61
+ Object.getPrototypeOf(instance),
62
+ )) {
63
+ const annotations = [
64
+ ...Object.values(
65
+ Reflect.getMetadata(ANNOTATION_METADATA, instance[methodName]) ??
66
+ {},
67
+ ),
68
+ ...Object.values(
69
+ Reflect.getMetadata(
70
+ ANNOTATION_METADATA,
71
+ instance.constructor,
72
+ methodName,
73
+ ) ?? {},
74
+ ),
75
+ ] as AnnotationInfo[];
76
+
77
+ if (annotations.length <= 0) continue;
78
+
79
+ resolversAnnotations[methodName] = annotations;
80
+ this._logger.log(
81
+ `Discovered annotated resolver "${instance.constructor.name}.${methodName}" with ${annotations.length} annotation(s)`,
82
+ );
83
+ }
84
+
85
+ return resolversAnnotations;
86
+ }
87
+ }
@@ -1,48 +1,48 @@
1
- import { buildHTTPExecutor } from "@graphql-tools/executor-http";
2
- import { schemaFromExecutor } from "@graphql-tools/wrap";
3
- import type { SubschemaConfig } from "@graphql-tools/delegate";
4
-
5
- export async function loadGraphQLSchema(url: string) {
6
- const executor = buildHTTPExecutor({
7
- endpoint: url,
8
- });
9
- return {
10
- schema: await schemaFromExecutor(executor),
11
- executor, // Has to be included.
12
- } as SubschemaConfig;
13
- }
14
-
15
- export function split<TItem, TFilteredItem extends TItem = TItem>(
16
- array: Array<TItem>,
17
- predicate: (item: TItem) => item is TFilteredItem,
18
- ) {
19
- const match = [] as TItem[];
20
- const rest = [] as TItem[];
21
- array.forEach((item) => {
22
- const matchedPredicate = predicate(item);
23
- const target = matchedPredicate ? match : rest;
24
- target.push(item);
25
- });
26
-
27
- return [
28
- match as TFilteredItem[],
29
- rest as Exclude<TItem, TFilteredItem>[],
30
- ] as const;
31
- }
32
-
33
- export function shallowMerge<TObj extends Record<string, any>[]>(
34
- objects: [...TObj],
35
- ) {
36
- type MergeObjectTuples<T> = T extends [infer THead, ...infer TRest]
37
- ? THead & MergeObjectTuples<TRest>
38
- : unknown;
39
-
40
- const res = {} as TObj;
41
- objects.forEach((o) => Object.assign(res, o));
42
- return res as MergeObjectTuples<TObj>;
43
- }
44
-
45
- export function isPlainObject(obj: any): obj is Record<PropertyKey, any> {
46
- const prototype = Object.getPrototypeOf(obj);
47
- return prototype === Object.getPrototypeOf({}) || prototype === null;
48
- }
1
+ import { buildHTTPExecutor } from "@graphql-tools/executor-http";
2
+ import { schemaFromExecutor } from "@graphql-tools/wrap";
3
+ import type { SubschemaConfig } from "@graphql-tools/delegate";
4
+
5
+ export async function loadGraphQLSchema(url: string) {
6
+ const executor = buildHTTPExecutor({
7
+ endpoint: url,
8
+ });
9
+ return {
10
+ schema: await schemaFromExecutor(executor),
11
+ executor, // Has to be included.
12
+ } as SubschemaConfig;
13
+ }
14
+
15
+ export function split<TItem, TFilteredItem extends TItem = TItem>(
16
+ array: Array<TItem>,
17
+ predicate: (item: TItem) => item is TFilteredItem,
18
+ ) {
19
+ const match = [] as TItem[];
20
+ const rest = [] as TItem[];
21
+ array.forEach((item) => {
22
+ const matchedPredicate = predicate(item);
23
+ const target = matchedPredicate ? match : rest;
24
+ target.push(item);
25
+ });
26
+
27
+ return [
28
+ match as TFilteredItem[],
29
+ rest as Exclude<TItem, TFilteredItem>[],
30
+ ] as const;
31
+ }
32
+
33
+ export function shallowMerge<TObj extends Record<string, any>[]>(
34
+ objects: [...TObj],
35
+ ) {
36
+ type MergeObjectTuples<T> = T extends [infer THead, ...infer TRest]
37
+ ? THead & MergeObjectTuples<TRest>
38
+ : unknown;
39
+
40
+ const res = {} as TObj;
41
+ objects.forEach((o) => Object.assign(res, o));
42
+ return res as MergeObjectTuples<TObj>;
43
+ }
44
+
45
+ export function isPlainObject(obj: any): obj is Record<PropertyKey, any> {
46
+ const prototype = Object.getPrototypeOf(obj);
47
+ return prototype === Object.getPrototypeOf({}) || prototype === null;
48
+ }
@@ -1,4 +1,4 @@
1
- export * from "./annotation.decorators";
2
- export * from "./annotation.constants";
3
- export * from "./annotation.loader";
4
- export * from "./annotation.module";
1
+ export * from "./annotation.decorators";
2
+ export * from "./annotation.constants";
3
+ export * from "./annotation.loader";
4
+ export * from "./annotation.module";
@@ -1,31 +1,31 @@
1
- import { Injectable } from "@nestjs/common";
2
- import { DiscoveryService } from "@nestjs/core";
3
- import { InstanceWrapper } from "@nestjs/core/injector/instance-wrapper";
4
- import { RESOLVER_TYPE_METADATA } from "@nestjs/graphql";
5
-
6
- @Injectable()
7
- export class ResolverDiscoveryService {
8
- constructor(
9
- // NOTE: use `ModulesContainer` if robust module exclusion is needed
10
- private readonly discoveryService: DiscoveryService,
11
- ) {}
12
-
13
- public explore() {
14
- // Discovery logic is derived from https://github.com/nestjs/graphql/blob/51d3e1cbc827124a8b0e79370e26abfc5d9bd154/packages/graphql/lib/services/resolvers-explorer.service.ts#L47
15
- const wrappedProviders = this.discoveryService.getProviders();
16
- return wrappedProviders.flatMap((wrapped) => {
17
- const { instance } = wrapped;
18
- if (!instance) return []; // Otherwise will error on `getMetadata` due to `undefined`
19
-
20
- // Don't get because the name can be `undefined`
21
- // Not sure how on their lib still function even in case of `undefined`, probably in filtering
22
- const isResolver = Reflect.hasMetadata(
23
- RESOLVER_TYPE_METADATA,
24
- instance.constructor,
25
- );
26
- if (!isResolver) return []; // Skip non-resolvers
27
-
28
- return wrapped;
29
- }) as InstanceWrapper[];
30
- }
31
- }
1
+ import { Injectable } from "@nestjs/common";
2
+ import { DiscoveryService } from "@nestjs/core";
3
+ import { InstanceWrapper } from "@nestjs/core/injector/instance-wrapper";
4
+ import { RESOLVER_TYPE_METADATA } from "@nestjs/graphql";
5
+
6
+ @Injectable()
7
+ export class ResolverDiscoveryService {
8
+ constructor(
9
+ // NOTE: use `ModulesContainer` if robust module exclusion is needed
10
+ private readonly discoveryService: DiscoveryService,
11
+ ) {}
12
+
13
+ public explore() {
14
+ // Discovery logic is derived from https://github.com/nestjs/graphql/blob/51d3e1cbc827124a8b0e79370e26abfc5d9bd154/packages/graphql/lib/services/resolvers-explorer.service.ts#L47
15
+ const wrappedProviders = this.discoveryService.getProviders();
16
+ return wrappedProviders.flatMap((wrapped) => {
17
+ const { instance } = wrapped;
18
+ if (!instance) return []; // Otherwise will error on `getMetadata` due to `undefined`
19
+
20
+ // Don't get because the name can be `undefined`
21
+ // Not sure how on their lib still function even in case of `undefined`, probably in filtering
22
+ const isResolver = Reflect.hasMetadata(
23
+ RESOLVER_TYPE_METADATA,
24
+ instance.constructor,
25
+ );
26
+ if (!isResolver) return []; // Skip non-resolvers
27
+
28
+ return wrapped;
29
+ }) as InstanceWrapper[];
30
+ }
31
+ }
@@ -1 +1 @@
1
- export * from "./core";
1
+ export * from "./core";
@@ -1,5 +1,5 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": { "incremental": false },
4
- "exclude": ["node_modules", "test", "dist", "**/*spec.ts", "src/example"]
5
- }
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": { "incremental": false },
4
+ "exclude": ["node_modules", "test", "dist", "**/*spec.ts", "src/example"]
5
+ }
package/tsconfig.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "ts-node": {
3
- "require": ["tsconfig-paths/register"] // configuration for typeorm migration
4
- },
5
- "compilerOptions": {
6
- "jsx": "react",
7
- "module": "commonjs",
8
- "declaration": true,
9
- "removeComments": true,
10
- "emitDecoratorMetadata": true,
11
- "experimentalDecorators": true,
12
- "allowSyntheticDefaultImports": true,
13
- "target": "ES2022",
14
- "sourceMap": true,
15
- "outDir": "./dist",
16
- "baseUrl": "./",
17
- "incremental": true,
18
- "skipLibCheck": true,
19
- "strictNullChecks": true,
20
- "noImplicitAny": false,
21
- "strictBindCallApply": false,
22
- "forceConsistentCasingInFileNames": false,
23
- "noFallthroughCasesInSwitch": false,
24
- "esModuleInterop": true,
25
- "importHelpers": true,
26
- "paths": {
27
- "@/*": ["src/*"]
28
- }
29
- }
30
- }
1
+ {
2
+ "ts-node": {
3
+ "require": ["tsconfig-paths/register"] // configuration for typeorm migration
4
+ },
5
+ "compilerOptions": {
6
+ "jsx": "react",
7
+ "module": "commonjs",
8
+ "declaration": true,
9
+ "removeComments": true,
10
+ "emitDecoratorMetadata": true,
11
+ "experimentalDecorators": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "target": "ES2022",
14
+ "sourceMap": true,
15
+ "outDir": "./dist",
16
+ "baseUrl": "./",
17
+ "incremental": true,
18
+ "skipLibCheck": true,
19
+ "strictNullChecks": true,
20
+ "noImplicitAny": false,
21
+ "strictBindCallApply": false,
22
+ "forceConsistentCasingInFileNames": false,
23
+ "noFallthroughCasesInSwitch": false,
24
+ "esModuleInterop": true,
25
+ "importHelpers": true,
26
+ "paths": {
27
+ "@/*": ["src/*"]
28
+ }
29
+ }
30
+ }
package/tsup.config.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- tsconfig: "tsconfig.build.json",
5
- entry: ["src/index.ts"],
6
- format: ["esm", "cjs"],
7
- outDir: "dist",
8
- dts: true,
9
- clean: true,
10
- });
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ tsconfig: "tsconfig.build.json",
5
+ entry: ["src/index.ts"],
6
+ format: ["esm", "cjs"],
7
+ outDir: "dist",
8
+ dts: true,
9
+ clean: true,
10
+ });
@@ -1,20 +0,0 @@
1
-
2
- > @tinkerstack/graphql-annotation@0.0.4 build C:\Users\mori\Documents\Work\tinkerstack\packages\graphql-annotation
3
- > tsup
4
-
5
- CLI Building entry: src/index.ts
6
- CLI Using tsconfig: tsconfig.build.json
7
- CLI tsup v8.5.1
8
- CLI Using tsup config: C:\Users\mori\Documents\Work\tinkerstack\packages\graphql-annotation\tsup.config.ts
9
- CLI Target: es2022
10
- CLI Cleaning output folder
11
- ESM Build start
12
- CJS Build start
13
- CJS dist\index.js 21.41 KB
14
- CJS ⚡️ Build success in 137ms
15
- ESM dist\index.mjs 19.48 KB
16
- ESM ⚡️ Build success in 137ms
17
- DTS Build start
18
- DTS ⚡️ Build success in 3496ms
19
- DTS dist\index.d.mts 3.00 KB
20
- DTS dist\index.d.ts 3.00 KB