@axinom/mosaic-graphql-common 0.1.0-rc.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.
Files changed (95) hide show
  1. package/README.md +16 -0
  2. package/dist/common/checks.d.ts +9 -0
  3. package/dist/common/checks.d.ts.map +1 -0
  4. package/dist/common/checks.js +21 -0
  5. package/dist/common/checks.js.map +1 -0
  6. package/dist/common/index.d.ts +3 -0
  7. package/dist/common/index.d.ts.map +1 -0
  8. package/dist/common/index.js +19 -0
  9. package/dist/common/index.js.map +1 -0
  10. package/dist/common/types.d.ts +13 -0
  11. package/dist/common/types.d.ts.map +1 -0
  12. package/dist/common/types.js +15 -0
  13. package/dist/common/types.js.map +1 -0
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +20 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/plugins/add-error-codes-enum-plugin.d.ts +27 -0
  19. package/dist/plugins/add-error-codes-enum-plugin.d.ts.map +1 -0
  20. package/dist/plugins/add-error-codes-enum-plugin.js +78 -0
  21. package/dist/plugins/add-error-codes-enum-plugin.js.map +1 -0
  22. package/dist/plugins/annotate-types-with-permissions-plugin.d.ts +22 -0
  23. package/dist/plugins/annotate-types-with-permissions-plugin.d.ts.map +1 -0
  24. package/dist/plugins/annotate-types-with-permissions-plugin.js +145 -0
  25. package/dist/plugins/annotate-types-with-permissions-plugin.js.map +1 -0
  26. package/dist/plugins/deprecate-stray-node-id-fields-plugin.d.ts +14 -0
  27. package/dist/plugins/deprecate-stray-node-id-fields-plugin.d.ts.map +1 -0
  28. package/dist/plugins/deprecate-stray-node-id-fields-plugin.js +37 -0
  29. package/dist/plugins/deprecate-stray-node-id-fields-plugin.js.map +1 -0
  30. package/dist/plugins/generic-bulk-plugin-factory.d.ts +49 -0
  31. package/dist/plugins/generic-bulk-plugin-factory.d.ts.map +1 -0
  32. package/dist/plugins/generic-bulk-plugin-factory.js +181 -0
  33. package/dist/plugins/generic-bulk-plugin-factory.js.map +1 -0
  34. package/dist/plugins/graphiql-management-mode-plugin-hook.d.ts +13 -0
  35. package/dist/plugins/graphiql-management-mode-plugin-hook.d.ts.map +1 -0
  36. package/dist/plugins/graphiql-management-mode-plugin-hook.js +44 -0
  37. package/dist/plugins/graphiql-management-mode-plugin-hook.js.map +1 -0
  38. package/dist/plugins/index.d.ts +10 -0
  39. package/dist/plugins/index.d.ts.map +1 -0
  40. package/dist/plugins/index.js +26 -0
  41. package/dist/plugins/index.js.map +1 -0
  42. package/dist/plugins/omit-from-query-root-plugin.d.ts +17 -0
  43. package/dist/plugins/omit-from-query-root-plugin.d.ts.map +1 -0
  44. package/dist/plugins/omit-from-query-root-plugin.js +43 -0
  45. package/dist/plugins/omit-from-query-root-plugin.js.map +1 -0
  46. package/dist/plugins/operations-enum-generator-plugin-factory.d.ts +15 -0
  47. package/dist/plugins/operations-enum-generator-plugin-factory.d.ts.map +1 -0
  48. package/dist/plugins/operations-enum-generator-plugin-factory.js +108 -0
  49. package/dist/plugins/operations-enum-generator-plugin-factory.js.map +1 -0
  50. package/dist/plugins/subscriptions-plugin-factory.d.ts +9 -0
  51. package/dist/plugins/subscriptions-plugin-factory.d.ts.map +1 -0
  52. package/dist/plugins/subscriptions-plugin-factory.js +67 -0
  53. package/dist/plugins/subscriptions-plugin-factory.js.map +1 -0
  54. package/dist/plugins/validation-directives-plugin.d.ts +6 -0
  55. package/dist/plugins/validation-directives-plugin.d.ts.map +1 -0
  56. package/dist/plugins/validation-directives-plugin.js +117 -0
  57. package/dist/plugins/validation-directives-plugin.js.map +1 -0
  58. package/dist/postgraphile/enhance-graphql-errors.d.ts +48 -0
  59. package/dist/postgraphile/enhance-graphql-errors.d.ts.map +1 -0
  60. package/dist/postgraphile/enhance-graphql-errors.js +67 -0
  61. package/dist/postgraphile/enhance-graphql-errors.js.map +1 -0
  62. package/dist/postgraphile/index.d.ts +4 -0
  63. package/dist/postgraphile/index.d.ts.map +1 -0
  64. package/dist/postgraphile/index.js +20 -0
  65. package/dist/postgraphile/index.js.map +1 -0
  66. package/dist/postgraphile/postgraphile-options-builder.d.ts +273 -0
  67. package/dist/postgraphile/postgraphile-options-builder.d.ts.map +1 -0
  68. package/dist/postgraphile/postgraphile-options-builder.js +419 -0
  69. package/dist/postgraphile/postgraphile-options-builder.js.map +1 -0
  70. package/dist/postgraphile/websocket-utils.d.ts +11 -0
  71. package/dist/postgraphile/websocket-utils.d.ts.map +1 -0
  72. package/dist/postgraphile/websocket-utils.js +17 -0
  73. package/dist/postgraphile/websocket-utils.js.map +1 -0
  74. package/package.json +61 -0
  75. package/src/common/checks.ts +23 -0
  76. package/src/common/index.ts +2 -0
  77. package/src/common/types.ts +15 -0
  78. package/src/index.ts +3 -0
  79. package/src/plugins/add-error-codes-enum-plugin.ts +102 -0
  80. package/src/plugins/annotate-types-with-permissions-plugin.spec.ts +158 -0
  81. package/src/plugins/annotate-types-with-permissions-plugin.ts +205 -0
  82. package/src/plugins/deprecate-stray-node-id-fields-plugin.ts +41 -0
  83. package/src/plugins/generic-bulk-plugin-factory.ts +313 -0
  84. package/src/plugins/graphiql-management-mode-plugin-hook.ts +46 -0
  85. package/src/plugins/index.ts +9 -0
  86. package/src/plugins/omit-from-query-root-plugin.ts +69 -0
  87. package/src/plugins/operations-enum-generator-plugin-factory.ts +130 -0
  88. package/src/plugins/subscriptions-plugin-factory.ts +114 -0
  89. package/src/plugins/validation-directives-plugin.ts +141 -0
  90. package/src/postgraphile/enhance-graphql-errors.spec.ts +241 -0
  91. package/src/postgraphile/enhance-graphql-errors.ts +138 -0
  92. package/src/postgraphile/index.ts +3 -0
  93. package/src/postgraphile/postgraphile-options-builder.spec.ts +744 -0
  94. package/src/postgraphile/postgraphile-options-builder.ts +510 -0
  95. package/src/postgraphile/websocket-utils.ts +19 -0
@@ -0,0 +1,744 @@
1
+ /* eslint-disable no-console */
2
+ import PgPubsub from '@graphile/pg-pubsub';
3
+ import { Request, Response } from 'express';
4
+ import { MutationPayloadQueryPlugin, NodePlugin } from 'graphile-build';
5
+ import { stub } from 'jest-auto-stub';
6
+ import 'jest-extended';
7
+ import { Pool } from 'pg';
8
+ import { Plugin, PostGraphilePlugin } from 'postgraphile';
9
+ import { Dict } from '../common';
10
+ import {
11
+ AnnotateTypesWithPermissionsPlugin,
12
+ ValidationDirectivesPlugin,
13
+ } from '../plugins';
14
+ import { PostgraphileOptionsBuilder } from './postgraphile-options-builder';
15
+
16
+ const testHookFactory = (): PostGraphilePlugin => {
17
+ return {};
18
+ };
19
+
20
+ describe('RascalConfigBuilder', () => {
21
+ let req: Request & { token: string };
22
+ let res: Response;
23
+ let headers: Dict<string> = {};
24
+ beforeEach(async () => {
25
+ req = stub<Request & { token: string }>({ token: 'test-jwt-token-string' });
26
+ res = stub<Response>({
27
+ setHeader: (key: string, val: string) => (headers[key] = val),
28
+ });
29
+ });
30
+ afterEach(async () => {
31
+ headers = {};
32
+ });
33
+ describe('build', () => {
34
+ it('Builder without any calls -> returns empty object', () => {
35
+ // Arrange
36
+ const builder = new PostgraphileOptionsBuilder();
37
+
38
+ // Act
39
+ const options = builder.build();
40
+
41
+ // Assert
42
+ expect(options).toEqual({});
43
+ });
44
+
45
+ it('Builder with setPgSettings call with sync function -> options adjusted', () => {
46
+ // Arrange
47
+ const builder = new PostgraphileOptionsBuilder();
48
+ const mockFunc = () => {
49
+ return {};
50
+ };
51
+
52
+ // Act
53
+ const options = builder.setPgSettings(mockFunc).build();
54
+
55
+ // Assert
56
+ expect(options).toEqual({
57
+ pgSettings: mockFunc,
58
+ });
59
+ });
60
+
61
+ it('Builder with setPgSettings call with async function -> options adjusted', () => {
62
+ // Arrange
63
+ const builder = new PostgraphileOptionsBuilder();
64
+ const mockFunc = async () => {
65
+ return {};
66
+ };
67
+
68
+ // Act
69
+ const options = builder.setPgSettings(mockFunc).build();
70
+
71
+ // Assert
72
+ expect(options).toEqual({
73
+ pgSettings: mockFunc,
74
+ });
75
+ });
76
+
77
+ it('Builder with setErrorsHandler call -> options adjusted', () => {
78
+ // Arrange
79
+ const builder = new PostgraphileOptionsBuilder();
80
+ const mockFunc = () => {
81
+ return [];
82
+ };
83
+
84
+ // Act
85
+ const options = builder.setErrorsHandler(mockFunc).build();
86
+
87
+ // Assert
88
+ expect(options).toEqual({
89
+ handleErrors: mockFunc,
90
+ });
91
+ });
92
+
93
+ it.each([
94
+ {},
95
+ { enableCors: true },
96
+ { enableCors: true, legacyRelations: 'omit' },
97
+ ])('Builder with setProperties "%p" -> options adjusted', (props) => {
98
+ // Arrange
99
+ const builder = new PostgraphileOptionsBuilder();
100
+
101
+ // Act
102
+ const options = builder.setProperties(props as any).build();
103
+
104
+ // Assert
105
+ expect(options).toEqual(props);
106
+ });
107
+
108
+ it.each([
109
+ {},
110
+ { enableCors: true },
111
+ { enableCors: true, exportGqlSchemaPath: 'schema.graphql' },
112
+ ])(
113
+ 'Builder with setConditionalProperties %p and true condition -> options adjusted',
114
+ (props) => {
115
+ // Arrange
116
+ const builder = new PostgraphileOptionsBuilder();
117
+
118
+ // Act
119
+ const options = builder.setConditionalProperties(true, props).build();
120
+
121
+ // Assert
122
+ expect(options).toEqual(props);
123
+ },
124
+ );
125
+
126
+ it.each([
127
+ {},
128
+ { enableCors: true },
129
+ { enableCors: true, exportGqlSchemaPath: 'schema.graphql' },
130
+ ])(
131
+ 'Builder with setConditionalProperties %p and false condition -> options not adjusted',
132
+ (props) => {
133
+ // Arrange
134
+ const builder = new PostgraphileOptionsBuilder();
135
+
136
+ // Act
137
+ const options = builder.setConditionalProperties(false, props).build();
138
+
139
+ // Assert
140
+ expect(options).toEqual({});
141
+ },
142
+ );
143
+
144
+ it('Builder with multiple setProperties calls in dev setup -> options adjusted using latest values', () => {
145
+ // Arrange
146
+ const builder = new PostgraphileOptionsBuilder();
147
+
148
+ // Act
149
+ const options = builder
150
+ .setProperties({
151
+ enableCors: true,
152
+ legacyRelations: 'omit',
153
+ ownerConnectionString: 'value 1',
154
+ })
155
+ .setProperties({
156
+ enableCors: true,
157
+ legacyRelations: 'only',
158
+ ownerConnectionString: 'value 2',
159
+ })
160
+ .setConditionalProperties(true, {
161
+ dynamicJson: true,
162
+ exportGqlSchemaPath: 'value 1',
163
+ ownerConnectionString: 'value 3',
164
+ })
165
+ .setConditionalProperties(true, {
166
+ dynamicJson: true,
167
+ exportGqlSchemaPath: 'value 2',
168
+ ownerConnectionString: 'value 4',
169
+ })
170
+ .build();
171
+
172
+ // Assert
173
+ expect(options).toEqual({
174
+ enableCors: true,
175
+ dynamicJson: true,
176
+ legacyRelations: 'only',
177
+ exportGqlSchemaPath: 'value 2',
178
+ ownerConnectionString: 'value 4',
179
+ });
180
+ });
181
+
182
+ it('Builder with multiple setProperties calls in non-dev setup -> options adjusted using latest values', () => {
183
+ // Arrange
184
+ const builder = new PostgraphileOptionsBuilder();
185
+
186
+ // Act
187
+ const options = builder
188
+ .setProperties({
189
+ enableCors: true,
190
+ legacyRelations: 'omit',
191
+ ownerConnectionString: 'value 1',
192
+ })
193
+ .setProperties({
194
+ enableCors: true,
195
+ legacyRelations: 'only',
196
+ ownerConnectionString: 'value 2',
197
+ })
198
+ // Ignored, because condition is false
199
+ .setConditionalProperties(false, {
200
+ enableCors: false,
201
+ legacyRelations: 'deprecated',
202
+ ownerConnectionString: 'value X',
203
+ })
204
+ .build();
205
+
206
+ // Assert
207
+ expect(options).toEqual({
208
+ enableCors: true,
209
+ legacyRelations: 'only',
210
+ ownerConnectionString: 'value 2',
211
+ });
212
+ });
213
+
214
+ it('Builder with enableSubscriptions call without middleware -> options adjusted', () => {
215
+ // Arrange
216
+ const builder = new PostgraphileOptionsBuilder();
217
+ const subPlugin: Plugin = () => {
218
+ return;
219
+ };
220
+
221
+ // Act
222
+ const options = builder
223
+ .enableSubscriptions({ plugin: subPlugin })
224
+ .build();
225
+
226
+ // Assert
227
+ expect([...builder['pluginHooks']]).toEqual([PgPubsub]);
228
+ expect(options.pluginHook).toBeTruthy();
229
+ expect(options).toMatchObject({
230
+ appendPlugins: [subPlugin],
231
+ subscriptions: true,
232
+ websocketMiddlewares: [],
233
+ });
234
+ });
235
+
236
+ it('Builder with enableSubscriptions call with middleware -> options adjusted', () => {
237
+ // Arrange
238
+ const builder = new PostgraphileOptionsBuilder();
239
+ const subPlugin: Plugin = () => {
240
+ return;
241
+ };
242
+ const mockMiddleware = () => {
243
+ return;
244
+ };
245
+
246
+ // Act
247
+ const options = builder
248
+ .enableSubscriptions({
249
+ plugin: subPlugin,
250
+ websocketMiddlewares: [mockMiddleware],
251
+ })
252
+ .build();
253
+
254
+ // Assert
255
+ expect([...builder['pluginHooks']]).toEqual([PgPubsub]);
256
+ expect(options.pluginHook).toBeTruthy();
257
+ expect(options).toMatchObject({
258
+ appendPlugins: [subPlugin],
259
+ subscriptions: true,
260
+ websocketMiddlewares: [mockMiddleware],
261
+ });
262
+ });
263
+
264
+ it('Builder with addPlugins calls -> options adjusted', () => {
265
+ // Arrange
266
+ const builder = new PostgraphileOptionsBuilder();
267
+ const plugin1: Plugin = () => {
268
+ return;
269
+ };
270
+ const plugin2: Plugin = () => {
271
+ return;
272
+ };
273
+ const plugin3: Plugin = () => {
274
+ return;
275
+ };
276
+
277
+ // Act
278
+ const options = builder
279
+ .addPlugins(plugin1, plugin2)
280
+ .addPlugins(plugin2, plugin3)
281
+ .build();
282
+
283
+ // Assert
284
+ expect(options).toEqual({
285
+ appendPlugins: [plugin1, plugin2, plugin3],
286
+ });
287
+ });
288
+
289
+ it('Builder with addPlugins and enableSubscriptions calls -> options adjusted', () => {
290
+ // Arrange
291
+ const builder = new PostgraphileOptionsBuilder();
292
+ const plugin1: Plugin = () => {
293
+ return;
294
+ };
295
+ const plugin2: Plugin = () => {
296
+ return;
297
+ };
298
+ const plugin3: Plugin = () => {
299
+ return;
300
+ };
301
+
302
+ // Act
303
+ const options = builder
304
+ .addPlugins(plugin1, plugin2)
305
+ .enableSubscriptions({ plugin: plugin2 })
306
+ .enableSubscriptions({ plugin: plugin3 })
307
+ .build();
308
+
309
+ // Assert
310
+ expect([...builder['pluginHooks']]).toEqual([PgPubsub]);
311
+ expect(options.pluginHook).toBeTruthy();
312
+ expect(options).toMatchObject({
313
+ appendPlugins: [plugin1, plugin2, plugin3],
314
+ subscriptions: true,
315
+ websocketMiddlewares: [],
316
+ });
317
+ });
318
+
319
+ it('Builder with enableSubscriptions and addHookPluginFactory calls -> options adjusted', () => {
320
+ // Arrange
321
+ const builder = new PostgraphileOptionsBuilder();
322
+ const plugin: Plugin = () => {
323
+ return;
324
+ };
325
+
326
+ // Act
327
+ const options = builder
328
+ .enableSubscriptions({ plugin, hookFactory: testHookFactory })
329
+ .addHookPluginFactory(testHookFactory)
330
+ .build();
331
+
332
+ // Assert
333
+ expect([...builder['pluginHooks']]).toEqual([
334
+ PgPubsub,
335
+ testHookFactory(),
336
+ ]);
337
+ expect(options.pluginHook).toBeTruthy();
338
+ expect(options).toMatchObject({
339
+ appendPlugins: [plugin],
340
+ subscriptions: true,
341
+ websocketMiddlewares: [],
342
+ });
343
+ });
344
+
345
+ it('Builder with one setHeader call -> options adjusted', () => {
346
+ // Arrange
347
+ const builder = new PostgraphileOptionsBuilder();
348
+
349
+ // Act
350
+ const options = builder.setHeader('Access-Control-Max-Age', 60).build();
351
+
352
+ // Assert
353
+ expect(Object.keys(options)).toHaveLength(1);
354
+ const pluginHooks = [...builder['pluginHooks']];
355
+ expect(pluginHooks).toHaveLength(1);
356
+ expect(pluginHooks[0]['postgraphile:http:handler']).toBeFunction();
357
+ pluginHooks[0]['postgraphile:http:handler']?.(req, {
358
+ res,
359
+ });
360
+ expect(headers).toEqual({ 'Access-Control-Max-Age': 60 });
361
+ expect(options.pluginHook).toBeFunction();
362
+ });
363
+
364
+ it('Builder with two setHeader call -> options adjusted', () => {
365
+ // Arrange
366
+ const builder = new PostgraphileOptionsBuilder();
367
+
368
+ // Act
369
+ const options = builder
370
+ .setHeader('Access-Control-Max-Age', 60)
371
+ .setHeader('random-header', 'test')
372
+ .build();
373
+
374
+ // Assert
375
+ expect(Object.keys(options)).toHaveLength(1);
376
+ const pluginHooks = [...builder['pluginHooks']];
377
+ expect(pluginHooks).toHaveLength(1);
378
+ expect(pluginHooks[0]['postgraphile:http:handler']).toBeFunction();
379
+ pluginHooks[0]['postgraphile:http:handler']?.(req, {
380
+ res,
381
+ });
382
+ expect(headers).toEqual({
383
+ 'Access-Control-Max-Age': 60,
384
+ 'random-header': 'test',
385
+ });
386
+ expect(options.pluginHook).toBeFunction();
387
+ });
388
+
389
+ it('Builder with skipPlugins calls -> options adjusted', () => {
390
+ // Arrange
391
+ const builder = new PostgraphileOptionsBuilder();
392
+
393
+ // Act
394
+ const options = builder
395
+ .skipPlugins(NodePlugin)
396
+ .skipPlugins(NodePlugin, MutationPayloadQueryPlugin)
397
+ .build();
398
+
399
+ // Assert
400
+ expect(options).toEqual({
401
+ skipPlugins: [NodePlugin, MutationPayloadQueryPlugin],
402
+ });
403
+ });
404
+
405
+ it('Builder with addConditionalPlugins call in production env and true condition -> options are adjusted', () => {
406
+ // Arrange
407
+ const builder = new PostgraphileOptionsBuilder();
408
+ const plugin1: Plugin = () => {
409
+ return;
410
+ };
411
+
412
+ // Act
413
+ const options = builder.addConditionalPlugins(true, plugin1).build();
414
+
415
+ // Assert
416
+ expect(options).toEqual({
417
+ appendPlugins: [plugin1],
418
+ });
419
+ });
420
+
421
+ it('Builder with addConditionalPlugins call in production env and false condition -> options are not adjusted', () => {
422
+ // Arrange
423
+ const builder = new PostgraphileOptionsBuilder();
424
+ const plugin1: Plugin = () => {
425
+ return;
426
+ };
427
+
428
+ // Act
429
+ const options = builder.addConditionalPlugins(false, plugin1).build();
430
+
431
+ // Assert
432
+ expect(options).toEqual({});
433
+ });
434
+
435
+ it('Builder with addGraphileBuildOptions calls -> results are merged on first hierarchy level, overridden on others', () => {
436
+ // Arrange
437
+ const builder = new PostgraphileOptionsBuilder();
438
+
439
+ // Act
440
+ const options = builder
441
+ .addGraphileBuildOptions({
442
+ test1: 'test1',
443
+ test3: 'test3-1',
444
+ test4: { t1: 't1', t2: 't2' },
445
+ })
446
+ .addGraphileBuildOptions({
447
+ test2: 'test2',
448
+ test3: 'test3-2',
449
+ test4: { t1: 't1', t3: 't3' },
450
+ })
451
+ .build();
452
+
453
+ // Assert
454
+ expect(options).toEqual({
455
+ graphileBuildOptions: {
456
+ test1: 'test1',
457
+ test2: 'test2',
458
+ test3: 'test3-2',
459
+ test4: { t1: 't1', t3: 't3' },
460
+ },
461
+ });
462
+ });
463
+
464
+ it('Builder with setAdditionalGraphQLContextFromRequest calls -> latest result is set', async () => {
465
+ // Arrange
466
+ const builder = new PostgraphileOptionsBuilder();
467
+
468
+ // Act
469
+ const options = builder
470
+ .setAdditionalGraphQLContextFromRequest(async () => {
471
+ return { test: 'test1' };
472
+ })
473
+ .setAdditionalGraphQLContextFromRequest(async () => {
474
+ return { test: 'test2' };
475
+ })
476
+ .build();
477
+
478
+ // Assert
479
+ expect(options.additionalGraphQLContextFromRequest).not.toBeFalsy();
480
+ const contextProps = await options.additionalGraphQLContextFromRequest?.(
481
+ req,
482
+ res,
483
+ );
484
+ expect(contextProps).toEqual({ test: 'test2' });
485
+ });
486
+
487
+ it('Builder with setDefaultSettings calls in dev environment -> default settings are set', () => {
488
+ // Arrange
489
+ const builder = new PostgraphileOptionsBuilder();
490
+
491
+ // Act
492
+ const options = builder.setDefaultSettings(true, true).build();
493
+
494
+ // Assert
495
+ expect(options.handleErrors).toBeFunction();
496
+ expect(options).toEqual({
497
+ allowExplain: true,
498
+ disableQueryLog: false,
499
+ dynamicJson: true,
500
+ enableCors: true,
501
+ enhanceGraphiql: true,
502
+ exportGqlSchemaPath: './src/generated/graphql/schema.graphql',
503
+ graphiql: true,
504
+ handleErrors: options.handleErrors,
505
+ ignoreRBAC: false,
506
+ legacyRelations: 'omit',
507
+ setofFunctionsContainNulls: false,
508
+ watchPg: true,
509
+ retryOnInitFail: false,
510
+ skipPlugins: [NodePlugin],
511
+ });
512
+ });
513
+
514
+ it('Builder with setDefaultSettings calls in non-dev environment -> default settings are set', () => {
515
+ // Arrange
516
+ const builder = new PostgraphileOptionsBuilder();
517
+
518
+ // Act
519
+ const options = builder.setDefaultSettings(false, false).build();
520
+
521
+ // Assert
522
+ expect(options.handleErrors).toBeFunction();
523
+ expect(options).toEqual({
524
+ disableQueryLog: true,
525
+ dynamicJson: true,
526
+ enableCors: true,
527
+ handleErrors: options.handleErrors,
528
+ ignoreRBAC: false,
529
+ legacyRelations: 'omit',
530
+ setofFunctionsContainNulls: false,
531
+ enhanceGraphiql: false,
532
+ graphiql: false,
533
+ allowExplain: false,
534
+ retryOnInitFail: true,
535
+ watchPg: false,
536
+ skipPlugins: [NodePlugin],
537
+ });
538
+ });
539
+
540
+ it('Builder with setDefaultSettings calls in dev environment with overrides -> default settings are overridden', () => {
541
+ // Arrange
542
+ const isDev = true;
543
+ const builder = new PostgraphileOptionsBuilder();
544
+ const syncFunc = () => {
545
+ return [];
546
+ };
547
+ const plugin1: Plugin = () => {
548
+ return;
549
+ };
550
+
551
+ // Act
552
+ const options = builder
553
+ .setDefaultSettings(isDev, true)
554
+ .setErrorsHandler(syncFunc)
555
+ .setProperties({ dynamicJson: false, ownerConnectionString: 'test' })
556
+ .setConditionalProperties(isDev, {
557
+ enhanceGraphiql: false,
558
+ graphiqlCredentials: 'omit',
559
+ exportGqlSchemaPath: 'test-path',
560
+ })
561
+ .skipPlugins(plugin1)
562
+ .build();
563
+
564
+ // Assert
565
+ expect(options).toEqual({
566
+ allowExplain: true,
567
+ disableQueryLog: false,
568
+ dynamicJson: false,
569
+ enableCors: true,
570
+ enhanceGraphiql: false,
571
+ exportGqlSchemaPath: 'test-path',
572
+ graphiql: true,
573
+ handleErrors: syncFunc,
574
+ ignoreRBAC: false,
575
+ legacyRelations: 'omit',
576
+ setofFunctionsContainNulls: false,
577
+ watchPg: true,
578
+ ownerConnectionString: 'test',
579
+ graphiqlCredentials: 'omit',
580
+ retryOnInitFail: false,
581
+ skipPlugins: [NodePlugin, plugin1],
582
+ });
583
+ });
584
+
585
+ it.each([true, false])(
586
+ 'Builder with setGraphiql call -> settings are set to %p',
587
+ (graphqlGuiEnabled) => {
588
+ // Arrange
589
+ const builder = new PostgraphileOptionsBuilder();
590
+ // Act
591
+ const options = builder.setGraphiql(graphqlGuiEnabled).build();
592
+
593
+ // Assert
594
+ expect(options).toEqual({
595
+ graphiql: graphqlGuiEnabled,
596
+ enhanceGraphiql: graphqlGuiEnabled,
597
+ allowExplain: graphqlGuiEnabled,
598
+ });
599
+ },
600
+ );
601
+
602
+ it('Builder with most methods called -> options are adjusted', async () => {
603
+ // Arrange
604
+ const isDev = true;
605
+ const builder = new PostgraphileOptionsBuilder();
606
+ const plugin1: Plugin = () => {
607
+ return;
608
+ };
609
+ const plugin2: Plugin = () => {
610
+ return;
611
+ };
612
+ const plugin3: Plugin = () => {
613
+ return;
614
+ };
615
+ const plugin4: Plugin = () => {
616
+ return;
617
+ };
618
+ const plugin5: Plugin = () => {
619
+ return;
620
+ };
621
+ const asyncFunc = async () => {
622
+ return {};
623
+ };
624
+ const syncFunc = () => {
625
+ return [];
626
+ };
627
+ const authFunc = (_req: unknown) => {
628
+ return { subject: {}, authErrorInfo: {} };
629
+ };
630
+ const ownerPool = new Pool();
631
+
632
+ // Act
633
+ const options = builder
634
+ .setPgSettings(asyncFunc)
635
+ .setErrorsHandler(syncFunc)
636
+ .setProperties({
637
+ enableCors: true,
638
+ dynamicJson: true,
639
+ ignoreRBAC: false,
640
+ legacyRelations: 'omit',
641
+ setofFunctionsContainNulls: false,
642
+ disableQueryLog: true,
643
+ })
644
+ .setConditionalProperties(isDev, {
645
+ ownerConnectionString: 'db-connection-string',
646
+ exportGqlSchemaPath: './src/generated/graphql/schema.graphql',
647
+ watchPg: true,
648
+ graphiql: true,
649
+ enhanceGraphiql: true,
650
+ allowExplain: true,
651
+ disableQueryLog: false,
652
+ })
653
+ .enableSubscriptions({
654
+ plugin: plugin1,
655
+ websocketMiddlewares: [],
656
+ hookFactory: testHookFactory,
657
+ })
658
+ .skipPlugins(NodePlugin)
659
+ .addPlugins(ValidationDirectivesPlugin)
660
+ .addConditionalPlugins(isDev, plugin2)
661
+ .addPlugins(plugin3)
662
+ .addPlugins(plugin4, plugin5)
663
+ .addPlugins(AnnotateTypesWithPermissionsPlugin)
664
+ .addGraphileBuildOptions({
665
+ serviceId: 'serviceIdValue',
666
+ permissionDefinition: 'permissionDefinitionValue',
667
+ })
668
+ .addGraphileBuildOptions({
669
+ ownerPool,
670
+ })
671
+ .setAdditionalGraphQLContextFromRequest(async (req) => {
672
+ const extendedRequest = req as Request & { token: string };
673
+ const { subject, authErrorInfo } = authFunc(req);
674
+ return {
675
+ ownerPool,
676
+ jwtToken: extendedRequest.token,
677
+ authErrorInfo,
678
+ subject,
679
+ };
680
+ })
681
+ .build();
682
+
683
+ // Assert
684
+ const {
685
+ additionalGraphQLContextFromRequest,
686
+ appendPlugins,
687
+ skipPlugins,
688
+ ...optionsWithoutContextAndPlugins
689
+ } = options;
690
+
691
+ expect(appendPlugins).toEqual([
692
+ plugin1,
693
+ ValidationDirectivesPlugin,
694
+ plugin2,
695
+ plugin3,
696
+ plugin4,
697
+ plugin5,
698
+ AnnotateTypesWithPermissionsPlugin,
699
+ ]);
700
+
701
+ expect(skipPlugins).toEqual([NodePlugin]);
702
+ expect([...builder['pluginHooks']]).toEqual([
703
+ PgPubsub,
704
+ testHookFactory(),
705
+ ]);
706
+ expect(options.pluginHook).toBeTruthy();
707
+ expect(optionsWithoutContextAndPlugins).toMatchObject({
708
+ pgSettings: asyncFunc,
709
+ handleErrors: syncFunc,
710
+ enableCors: true,
711
+ dynamicJson: true,
712
+ ignoreRBAC: false,
713
+ legacyRelations: 'omit',
714
+ setofFunctionsContainNulls: false,
715
+ disableQueryLog: false,
716
+ ownerConnectionString: 'db-connection-string',
717
+ exportGqlSchemaPath: './src/generated/graphql/schema.graphql',
718
+ watchPg: true,
719
+ graphiql: true,
720
+ enhanceGraphiql: true,
721
+ allowExplain: true,
722
+ subscriptions: true,
723
+ websocketMiddlewares: [],
724
+ graphileBuildOptions: {
725
+ serviceId: 'serviceIdValue',
726
+ permissionDefinition: 'permissionDefinitionValue',
727
+ ownerPool,
728
+ },
729
+ });
730
+
731
+ expect(additionalGraphQLContextFromRequest).not.toBeFalsy();
732
+ const contextProps = await additionalGraphQLContextFromRequest?.(
733
+ req,
734
+ res,
735
+ );
736
+ expect(contextProps).toEqual({
737
+ ownerPool,
738
+ jwtToken: 'test-jwt-token-string',
739
+ authErrorInfo: {},
740
+ subject: {},
741
+ });
742
+ });
743
+ });
744
+ });