@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.
- package/README.md +16 -0
- package/dist/common/checks.d.ts +9 -0
- package/dist/common/checks.d.ts.map +1 -0
- package/dist/common/checks.js +21 -0
- package/dist/common/checks.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +19 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/types.d.ts +13 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +15 -0
- package/dist/common/types.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/add-error-codes-enum-plugin.d.ts +27 -0
- package/dist/plugins/add-error-codes-enum-plugin.d.ts.map +1 -0
- package/dist/plugins/add-error-codes-enum-plugin.js +78 -0
- package/dist/plugins/add-error-codes-enum-plugin.js.map +1 -0
- package/dist/plugins/annotate-types-with-permissions-plugin.d.ts +22 -0
- package/dist/plugins/annotate-types-with-permissions-plugin.d.ts.map +1 -0
- package/dist/plugins/annotate-types-with-permissions-plugin.js +145 -0
- package/dist/plugins/annotate-types-with-permissions-plugin.js.map +1 -0
- package/dist/plugins/deprecate-stray-node-id-fields-plugin.d.ts +14 -0
- package/dist/plugins/deprecate-stray-node-id-fields-plugin.d.ts.map +1 -0
- package/dist/plugins/deprecate-stray-node-id-fields-plugin.js +37 -0
- package/dist/plugins/deprecate-stray-node-id-fields-plugin.js.map +1 -0
- package/dist/plugins/generic-bulk-plugin-factory.d.ts +49 -0
- package/dist/plugins/generic-bulk-plugin-factory.d.ts.map +1 -0
- package/dist/plugins/generic-bulk-plugin-factory.js +181 -0
- package/dist/plugins/generic-bulk-plugin-factory.js.map +1 -0
- package/dist/plugins/graphiql-management-mode-plugin-hook.d.ts +13 -0
- package/dist/plugins/graphiql-management-mode-plugin-hook.d.ts.map +1 -0
- package/dist/plugins/graphiql-management-mode-plugin-hook.js +44 -0
- package/dist/plugins/graphiql-management-mode-plugin-hook.js.map +1 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +26 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/omit-from-query-root-plugin.d.ts +17 -0
- package/dist/plugins/omit-from-query-root-plugin.d.ts.map +1 -0
- package/dist/plugins/omit-from-query-root-plugin.js +43 -0
- package/dist/plugins/omit-from-query-root-plugin.js.map +1 -0
- package/dist/plugins/operations-enum-generator-plugin-factory.d.ts +15 -0
- package/dist/plugins/operations-enum-generator-plugin-factory.d.ts.map +1 -0
- package/dist/plugins/operations-enum-generator-plugin-factory.js +108 -0
- package/dist/plugins/operations-enum-generator-plugin-factory.js.map +1 -0
- package/dist/plugins/subscriptions-plugin-factory.d.ts +9 -0
- package/dist/plugins/subscriptions-plugin-factory.d.ts.map +1 -0
- package/dist/plugins/subscriptions-plugin-factory.js +67 -0
- package/dist/plugins/subscriptions-plugin-factory.js.map +1 -0
- package/dist/plugins/validation-directives-plugin.d.ts +6 -0
- package/dist/plugins/validation-directives-plugin.d.ts.map +1 -0
- package/dist/plugins/validation-directives-plugin.js +117 -0
- package/dist/plugins/validation-directives-plugin.js.map +1 -0
- package/dist/postgraphile/enhance-graphql-errors.d.ts +48 -0
- package/dist/postgraphile/enhance-graphql-errors.d.ts.map +1 -0
- package/dist/postgraphile/enhance-graphql-errors.js +67 -0
- package/dist/postgraphile/enhance-graphql-errors.js.map +1 -0
- package/dist/postgraphile/index.d.ts +4 -0
- package/dist/postgraphile/index.d.ts.map +1 -0
- package/dist/postgraphile/index.js +20 -0
- package/dist/postgraphile/index.js.map +1 -0
- package/dist/postgraphile/postgraphile-options-builder.d.ts +273 -0
- package/dist/postgraphile/postgraphile-options-builder.d.ts.map +1 -0
- package/dist/postgraphile/postgraphile-options-builder.js +419 -0
- package/dist/postgraphile/postgraphile-options-builder.js.map +1 -0
- package/dist/postgraphile/websocket-utils.d.ts +11 -0
- package/dist/postgraphile/websocket-utils.d.ts.map +1 -0
- package/dist/postgraphile/websocket-utils.js +17 -0
- package/dist/postgraphile/websocket-utils.js.map +1 -0
- package/package.json +61 -0
- package/src/common/checks.ts +23 -0
- package/src/common/index.ts +2 -0
- package/src/common/types.ts +15 -0
- package/src/index.ts +3 -0
- package/src/plugins/add-error-codes-enum-plugin.ts +102 -0
- package/src/plugins/annotate-types-with-permissions-plugin.spec.ts +158 -0
- package/src/plugins/annotate-types-with-permissions-plugin.ts +205 -0
- package/src/plugins/deprecate-stray-node-id-fields-plugin.ts +41 -0
- package/src/plugins/generic-bulk-plugin-factory.ts +313 -0
- package/src/plugins/graphiql-management-mode-plugin-hook.ts +46 -0
- package/src/plugins/index.ts +9 -0
- package/src/plugins/omit-from-query-root-plugin.ts +69 -0
- package/src/plugins/operations-enum-generator-plugin-factory.ts +130 -0
- package/src/plugins/subscriptions-plugin-factory.ts +114 -0
- package/src/plugins/validation-directives-plugin.ts +141 -0
- package/src/postgraphile/enhance-graphql-errors.spec.ts +241 -0
- package/src/postgraphile/enhance-graphql-errors.ts +138 -0
- package/src/postgraphile/index.ts +3 -0
- package/src/postgraphile/postgraphile-options-builder.spec.ts +744 -0
- package/src/postgraphile/postgraphile-options-builder.ts +510 -0
- 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
|
+
});
|