@ttoss/graphql-api 0.4.2 → 0.4.4
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 +166 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -142,6 +142,14 @@ This packages provides the method `composeWithConnection` to create a connection
|
|
|
142
142
|
```typescript
|
|
143
143
|
import { composeWithConnection } from '@ttoss/appsync-api';
|
|
144
144
|
|
|
145
|
+
AuthorTC.addResolver({
|
|
146
|
+
name: 'findMany',
|
|
147
|
+
type: AuthorTC,
|
|
148
|
+
resolve: async ({ args }) => {
|
|
149
|
+
// find many
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
145
153
|
composeWithConnection(AuthorTC, {
|
|
146
154
|
findManyResolver: AuthorTC.getResolver('findMany'),
|
|
147
155
|
countResolver: AuthorTC.getResolver('count'),
|
|
@@ -160,10 +168,167 @@ composeWithConnection(AuthorTC, {
|
|
|
160
168
|
rawQuery.id.$gt = cursorData.id;
|
|
161
169
|
},
|
|
162
170
|
},
|
|
171
|
+
DESC: {
|
|
172
|
+
value: {
|
|
173
|
+
scanIndexForward: false,
|
|
174
|
+
},
|
|
175
|
+
cursorFields: ['id'],
|
|
176
|
+
beforeCursorQuery: (rawQuery, cursorData, resolveParams) => {
|
|
177
|
+
if (!rawQuery.id) rawQuery.id = {};
|
|
178
|
+
rawQuery.id.$gt = cursorData.id;
|
|
179
|
+
},
|
|
180
|
+
afterCursorQuery: (rawQuery, cursorData, resolveParams) => {
|
|
181
|
+
if (!rawQuery.id) rawQuery.id = {};
|
|
182
|
+
rawQuery.id.$lt = cursorData.id;
|
|
183
|
+
},
|
|
184
|
+
},
|
|
163
185
|
},
|
|
164
186
|
});
|
|
187
|
+
|
|
188
|
+
schemaComposer.Query.addFields({
|
|
189
|
+
authors: Authors.getResolver('connection'),
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
When you `composeWithConnection` a type, it will add the resolver `connection` to the type, so you can add to `Query` or any other type:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
schemaComposer.Query.addFields({
|
|
197
|
+
authors: Authors.getResolver('connection'),
|
|
198
|
+
});
|
|
165
199
|
```
|
|
166
200
|
|
|
201
|
+
The resolver `connection` has the following arguments based on the [Relay Connection Specification](https://facebook.github.io/relay/graphql/connections.htm):
|
|
202
|
+
|
|
203
|
+
- `first`: the number of nodes to return.
|
|
204
|
+
- `after`: the cursor to start the query.
|
|
205
|
+
- `last`: the number of nodes to return.
|
|
206
|
+
- `before`: the cursor to start the query.
|
|
207
|
+
- `sort`: the sort option to use. It's the keys of the `sort` object. In our example, it's `ASC` and `DESC`.
|
|
208
|
+
- `filter`: the filter to use. It'll exist if you add the `filter` to `findManyResolver` for example, the implementation below will add the `filter` argument with the `name` and `book` fields:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
AuthorTC.addResolver({
|
|
212
|
+
name: 'findMany',
|
|
213
|
+
type: AuthorTC,
|
|
214
|
+
args: {
|
|
215
|
+
filter: {
|
|
216
|
+
name: 'String',
|
|
217
|
+
book: 'String',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
resolve: async ({ args }) => {
|
|
221
|
+
// find many
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
To configure `composeWithConnection`, you need to provide the following options:
|
|
227
|
+
|
|
228
|
+
#### `findManyResolver`
|
|
229
|
+
|
|
230
|
+
The resolver that will be used to find the nodes. It receives the following arguments:
|
|
231
|
+
|
|
232
|
+
- `args`: the `args` object from the resolver. Example:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
AuthorTC.addResolver({
|
|
236
|
+
name: 'findMany',
|
|
237
|
+
type: AuthorTC,
|
|
238
|
+
args: {
|
|
239
|
+
filter: {
|
|
240
|
+
name: 'String',
|
|
241
|
+
book: 'String',
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
resolve: async ({
|
|
245
|
+
args,
|
|
246
|
+
}: {
|
|
247
|
+
args: {
|
|
248
|
+
first?: number;
|
|
249
|
+
after?: string;
|
|
250
|
+
last?: number;
|
|
251
|
+
before?: string;
|
|
252
|
+
/**
|
|
253
|
+
* The `filter` argument, if provided on the query.
|
|
254
|
+
*/
|
|
255
|
+
filter: {
|
|
256
|
+
name: string;
|
|
257
|
+
book: string;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* The `sort` argument, if provided on the query as
|
|
261
|
+
* they keys of the `sort` object. In our example
|
|
262
|
+
* above, it's `ASC` and `DESC`. `scanIndexForward`
|
|
263
|
+
* is the value of the `value` property on the sort
|
|
264
|
+
* object. In our example above, it's `true` for
|
|
265
|
+
* `ASC` and `false` for `DESC`.
|
|
266
|
+
*/
|
|
267
|
+
sort: {
|
|
268
|
+
scanIndexForward: boolean;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
}) => {
|
|
272
|
+
//
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
- `rawQuery`: an object created by `beforeCursorQuery` or `afterCursorQuery` methods from [sort](#sort) option.
|
|
278
|
+
|
|
279
|
+
#### `countResolver`
|
|
280
|
+
|
|
281
|
+
#### `sort`
|
|
282
|
+
|
|
283
|
+
It's an object that defines the sort options. Each key is the sort name and the value is an object with the following properties:
|
|
284
|
+
|
|
285
|
+
- `value`: and object that the resolver will receive as the `sort` argument.
|
|
286
|
+
- `cursorFields`: an array of fields that will be used to create the cursor.
|
|
287
|
+
- `beforeCursorQuery` and `afterCursorQuery`: methods that will be used to create the `rawQuery` object for the `findManyResolver`. They receive the following arguments:
|
|
288
|
+
|
|
289
|
+
- `rawQuery`: the `rawQuery` object that will be used to find the nodes.
|
|
290
|
+
- `cursorData`: the data from the cursor define on `cursorFields`. For example, if you define `cursorFields` as `['id', 'name']`, the `cursorData` will an object with the `id` and `name` properties.
|
|
291
|
+
- `resolveParams`: the `resolveParams` object from the resolver. You can access `args`, `context` and `info` and other GraphQL properties from this object.
|
|
292
|
+
|
|
293
|
+
Example:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
composeWithConnection(AuthorTC, {
|
|
297
|
+
// ...
|
|
298
|
+
sort: {
|
|
299
|
+
ASC: {
|
|
300
|
+
// ...
|
|
301
|
+
cursorFields: ['id', 'name'],
|
|
302
|
+
// Called when `before` cursor is provided.
|
|
303
|
+
beforeCursorQuery: (rawQuery, cursorData, resolveParams) => {
|
|
304
|
+
if (!rawQuery.id) rawQuery.id = {};
|
|
305
|
+
rawQuery.id.$lt = cursorData.id;
|
|
306
|
+
rawQuery.name.$lt = cursorData.name;
|
|
307
|
+
},
|
|
308
|
+
// Called when `after` cursor is provided.
|
|
309
|
+
afterCursorQuery: (rawQuery, cursorData, resolveParams) => {
|
|
310
|
+
if (!rawQuery.id) rawQuery.id = {};
|
|
311
|
+
rawQuery.id.$gt = cursorData.id;
|
|
312
|
+
rawQuery.name.$gt = cursorData.name;
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
In the example above, the `findManyResolver` will receive the following `rawQuery` object when `before` cursor is provided:
|
|
320
|
+
|
|
321
|
+
```json
|
|
322
|
+
{
|
|
323
|
+
"id": {
|
|
324
|
+
"$lt": "id-from-cursor"
|
|
325
|
+
},
|
|
326
|
+
"name": {
|
|
327
|
+
"$lt": "name-from-cursor"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
167
332
|
### Middlewares
|
|
168
333
|
|
|
169
334
|
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:
|
|
@@ -210,7 +375,7 @@ This package re-exports the all methods from [GraphQL Shield](https://the-guild.
|
|
|
210
375
|
import { allow, deny, shield } from '@ttoss/graphql-api/shield';
|
|
211
376
|
```
|
|
212
377
|
|
|
213
|
-
## Building Schema
|
|
378
|
+
## Building Schema and Types
|
|
214
379
|
|
|
215
380
|
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`. It build the schema using the `schemaComposer` from `src/schemaComposer.ts` file and save the schema in `schema/schema.graphql` file and TypeScript types in `schema/types.ts` file.
|
|
216
381
|
|
package/dist/index.d.mts
CHANGED
|
@@ -27,4 +27,4 @@ type BuildSchemaInput<TContext = any> = {
|
|
|
27
27
|
};
|
|
28
28
|
declare const buildSchema: ({ schemaComposer, middlewares, }: BuildSchemaInput) => GraphQLSchema;
|
|
29
29
|
|
|
30
|
-
export { BuildSchemaInput, buildSchema, composeWithRelay, fromGlobalId, toGlobalId };
|
|
30
|
+
export { type BuildSchemaInput, buildSchema, composeWithRelay, fromGlobalId, toGlobalId };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,4 +27,4 @@ type BuildSchemaInput<TContext = any> = {
|
|
|
27
27
|
};
|
|
28
28
|
declare const buildSchema: ({ schemaComposer, middlewares, }: BuildSchemaInput) => GraphQLSchema;
|
|
29
29
|
|
|
30
|
-
export { BuildSchemaInput, buildSchema, composeWithRelay, fromGlobalId, toGlobalId };
|
|
30
|
+
export { type BuildSchemaInput, buildSchema, composeWithRelay, fromGlobalId, toGlobalId };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/graphql-api",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "A library for building GraphQL APIs using ttoss ecosystem.",
|
|
5
5
|
"author": "ttoss",
|
|
6
6
|
"contributors": [
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
"graphql": "^16.6.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/yargs": "^17.0.
|
|
50
|
+
"@types/yargs": "^17.0.32",
|
|
51
51
|
"graphql": "^16.8.1",
|
|
52
|
-
"jest": "^29.
|
|
53
|
-
"tsup": "^
|
|
54
|
-
"@ttoss/config": "^1.
|
|
52
|
+
"jest": "^29.7.0",
|
|
53
|
+
"tsup": "^8.0.1",
|
|
54
|
+
"@ttoss/config": "^1.31.1"
|
|
55
55
|
},
|
|
56
56
|
"keywords": [
|
|
57
57
|
"api",
|