@ttoss/graphql-api 0.2.0 → 0.3.0

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.
package/README.md CHANGED
@@ -163,6 +163,44 @@ composeWithConnection(AuthorTC, {
163
163
  });
164
164
  ```
165
165
 
166
+ ### Middlewares
167
+
168
+ This package provides a way to add middlewares to your final schema. You can add middlewares compatible with [`graphql-middleware`](https://github.com/dimatill/graphql-middleware) by passing them to the `middlewares` option on `buildSchema` method. For example, you can use [GraphQL Shield](https://the-guild.dev/graphql/shield) to add authorization to your API:
169
+
170
+ ```typescript
171
+ import { buildSchema } from '@ttoss/graphql-api';
172
+ import { allow, deny, shield } from 'graphql-shield';
173
+ import { schemaComposer } from './schemaComposer';
174
+
175
+ const NotAuthorizedError = new Error('Not authorized!');
176
+ /**
177
+ * The error name is the same value `errorType` on GraphQL errors response.
178
+ */
179
+ NotAuthorizedError.name = 'NotAuthorizedError';
180
+
181
+ const permissions = shield(
182
+ {
183
+ Query: {
184
+ '*': deny,
185
+ author: allow,
186
+ },
187
+ Author: {
188
+ id: allow,
189
+ name: allow,
190
+ },
191
+ },
192
+ {
193
+ fallbackRule: deny,
194
+ fallbackError: NotAuthorizedError,
195
+ }
196
+ );
197
+
198
+ const schema = buildSchema({
199
+ schemaComposer,
200
+ middlewares; [permissions],
201
+ })
202
+ ```
203
+
166
204
  ## Building Schema
167
205
 
168
206
  As Relay needs an introspection query to work, this package provides a way to build the GraphQL schema by running `ttoss-graphl-api build-schema`.
@@ -171,6 +209,16 @@ As Relay needs an introspection query to work, this package provides a way to bu
171
209
  ttoss-graphl-api build-schema
172
210
  ```
173
211
 
212
+ You can add the `schema` script to your `package.json`:
213
+
214
+ ```json
215
+ {
216
+ "scripts": {
217
+ "schema": "ttoss-graphl-api build-schema"
218
+ }
219
+ }
220
+ ```
221
+
174
222
  ## How to Create Tests
175
223
 
176
224
  We recommend testing the whole GraphQL API using the `graphql` object and the schema composer to provide the schema. For example:
package/dist/esm/index.js CHANGED
@@ -153,4 +153,25 @@ composeWithRelay(schemaComposer.Query);
153
153
  // src/index.ts
154
154
  import { default as default2 } from "graphql-compose-connection";
155
155
  export * from "graphql-compose";
156
- export { default2 as composeWithConnection, composeWithRelay, fromGlobalId, toGlobalId };
156
+
157
+ // src/buildSchema.ts
158
+ import { applyMiddleware } from "graphql-middleware";
159
+ var buildSchema = ({
160
+ schemaComposer: schemaComposer2,
161
+ middlewares
162
+ }) => {
163
+ if (!schemaComposer2) {
164
+ throw new Error("No schemaComposer provided");
165
+ }
166
+ const schema = schemaComposer2.buildSchema();
167
+ if (middlewares) {
168
+ return applyMiddleware(schema, ...middlewares.map(middleware => {
169
+ if (middleware.generate) {
170
+ return middleware.generate(schema);
171
+ }
172
+ return middleware;
173
+ }));
174
+ }
175
+ return schema;
176
+ };
177
+ export { buildSchema, default2 as composeWithConnection, composeWithRelay, fromGlobalId, toGlobalId };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { ObjectTypeComposer } from 'graphql-compose';
1
+ import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
2
2
  export * from 'graphql-compose';
3
3
  export { default as composeWithConnection } from 'graphql-compose-connection';
4
+ import { GraphQLSchema } from 'graphql';
5
+ import { IMiddleware, IMiddlewareGenerator } from 'graphql-middleware';
4
6
 
5
7
  declare const composeWithRelay: <TContext>(tc: ObjectTypeComposer<any, TContext>) => ObjectTypeComposer<any, TContext>;
6
8
 
@@ -19,4 +21,10 @@ declare const toGlobalId: (type: string, recordId: string | number) => string;
19
21
  */
20
22
  declare const fromGlobalId: (globalId: string) => ResolvedGlobalId;
21
23
 
22
- export { composeWithRelay, fromGlobalId, toGlobalId };
24
+ type BuildSchemaInput<TContext = any> = {
25
+ schemaComposer: SchemaComposer<TContext>;
26
+ middlewares?: (IMiddleware | IMiddlewareGenerator<any, TContext, any>)[];
27
+ };
28
+ declare const buildSchema: ({ schemaComposer, middlewares, }: BuildSchemaInput) => GraphQLSchema;
29
+
30
+ export { BuildSchemaInput, buildSchema, composeWithRelay, fromGlobalId, toGlobalId };
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
39
39
  // src/index.ts
40
40
  var src_exports = {};
41
41
  __export(src_exports, {
42
+ buildSchema: () => buildSchema,
42
43
  composeWithConnection: () => import_graphql_compose_connection.default,
43
44
  composeWithRelay: () => composeWithRelay,
44
45
  fromGlobalId: () => fromGlobalId,
@@ -198,8 +199,30 @@ composeWithRelay(import_graphql_compose4.schemaComposer.Query);
198
199
  // src/index.ts
199
200
  var import_graphql_compose_connection = __toESM(require("graphql-compose-connection"));
200
201
  __reExport(src_exports, require("graphql-compose"), module.exports);
202
+
203
+ // src/buildSchema.ts
204
+ var import_graphql_middleware = require("graphql-middleware");
205
+ var buildSchema = ({
206
+ schemaComposer: schemaComposer2,
207
+ middlewares
208
+ }) => {
209
+ if (!schemaComposer2) {
210
+ throw new Error("No schemaComposer provided");
211
+ }
212
+ const schema = schemaComposer2.buildSchema();
213
+ if (middlewares) {
214
+ return (0, import_graphql_middleware.applyMiddleware)(schema, ...middlewares.map(middleware => {
215
+ if (middleware.generate) {
216
+ return middleware.generate(schema);
217
+ }
218
+ return middleware;
219
+ }));
220
+ }
221
+ return schema;
222
+ };
201
223
  // Annotate the CommonJS export names for ESM import in node:
202
224
  0 && (module.exports = {
225
+ buildSchema,
203
226
  composeWithConnection,
204
227
  composeWithRelay,
205
228
  fromGlobalId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/graphql-api",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A library for building GraphQL APIs.",
5
5
  "author": "ttoss",
6
6
  "contributors": [
@@ -20,6 +20,7 @@
20
20
  "dependencies": {
21
21
  "graphql-compose": "^9.0.10",
22
22
  "graphql-compose-connection": "^8.2.1",
23
+ "graphql-middleware": "^6.1.34",
23
24
  "npmlog": "^7.0.1",
24
25
  "ts-node": "^10.9.1",
25
26
  "yargs": "^17.7.2"
@@ -30,6 +31,7 @@
30
31
  "devDependencies": {
31
32
  "@types/yargs": "^17.0.24",
32
33
  "graphql": "^16.6.0",
34
+ "graphql-shield": "^7.6.5",
33
35
  "jest": "^29.5.0",
34
36
  "tsup": "^6.7.0",
35
37
  "@ttoss/config": "^1.30.0"
@@ -0,0 +1,43 @@
1
+ import { type GraphQLSchema } from 'graphql';
2
+ import {
3
+ type IMiddleware,
4
+ type IMiddlewareGenerator,
5
+ applyMiddleware,
6
+ } from 'graphql-middleware';
7
+ import { type SchemaComposer } from 'graphql-compose';
8
+
9
+ export type BuildSchemaInput<TContext = any> = {
10
+ schemaComposer: SchemaComposer<TContext>;
11
+ middlewares?: (IMiddleware | IMiddlewareGenerator<any, TContext, any>)[];
12
+ };
13
+
14
+ export const buildSchema = ({
15
+ schemaComposer,
16
+ middlewares,
17
+ }: BuildSchemaInput): GraphQLSchema => {
18
+ if (!schemaComposer) {
19
+ throw new Error('No schemaComposer provided');
20
+ }
21
+
22
+ const schema = schemaComposer.buildSchema();
23
+
24
+ if (middlewares) {
25
+ return applyMiddleware(
26
+ schema,
27
+ ...middlewares.map((middleware) => {
28
+ /**
29
+ * https://github.com/dimatill/graphql-middleware/issues/433#issuecomment-1170187160
30
+ */
31
+ if ((middleware as IMiddlewareGenerator<any, any, any>).generate) {
32
+ return (middleware as IMiddlewareGenerator<any, any, any>).generate(
33
+ schema
34
+ );
35
+ }
36
+
37
+ return middleware;
38
+ })
39
+ );
40
+ }
41
+
42
+ return schema;
43
+ };
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { composeWithRelay, toGlobalId, fromGlobalId } from './composeWithRelay';
2
2
  export { default as composeWithConnection } from 'graphql-compose-connection';
3
3
  export * from 'graphql-compose';
4
+ export { buildSchema, type BuildSchemaInput } from './buildSchema';