@opensaas/keystone-nextjs-auth 26.0.0 → 27.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @opensaas-keystone/nextjs-auth
2
2
 
3
+ ## 27.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - ec29144: Update dependency @keystone-6/core to v5
8
+
9
+ ### Patch Changes
10
+
11
+ - 0a8ea8e: Update patch dependencies (patch)
12
+
3
13
  ## 26.0.0
4
14
 
5
15
  ### Major Changes
@@ -75,17 +75,14 @@ function getBaseAuthSchema(_ref) {
75
75
  types: [base.object(listKey)],
76
76
  resolveType: (root, context) => {
77
77
  var _context$session;
78
-
79
78
  return (_context$session = context.session) === null || _context$session === void 0 ? void 0 : _context$session.listKey;
80
79
  }
81
80
  }),
82
-
83
81
  resolve(root, args, _ref2) {
84
82
  let {
85
83
  session,
86
84
  db
87
85
  } = _ref2;
88
-
89
86
  if (typeof (session === null || session === void 0 ? void 0 : session.itemId) === 'string' && typeof session.listKey === 'string') {
90
87
  return db[session.listKey].findOne({
91
88
  where: {
@@ -93,10 +90,8 @@ function getBaseAuthSchema(_ref) {
93
90
  }
94
91
  });
95
92
  }
96
-
97
93
  return null;
98
94
  }
99
-
100
95
  })
101
96
  }
102
97
  };
@@ -111,7 +106,6 @@ const getSchemaExtension = _ref => {
111
106
  } = _ref;
112
107
  return core.graphql.extend(base => {
113
108
  var _context;
114
-
115
109
  const baseSchema = getBaseAuthSchema({
116
110
  listKey,
117
111
  base
@@ -161,6 +155,7 @@ const authTemplate = _ref => {
161
155
  };
162
156
 
163
157
  const _excluded = ["get", "end"];
158
+
164
159
  /**
165
160
  * createAuth function
166
161
  *
@@ -184,6 +179,7 @@ function createAuth(_ref) {
184
179
  // part of the createAuth API (in which case its use cases need to be documented and tested)
185
180
  // or whether always being true is what we want, in which case we can refactor our code
186
181
  // to match this. -TL
182
+
187
183
  const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
188
184
  /**
189
185
  * pageMiddleware
@@ -195,29 +191,25 @@ function createAuth(_ref) {
195
191
  * - to the init page when initFirstItem is configured, and there are no user in the database
196
192
  * - to the signin page when no valid session is present
197
193
  */
198
-
199
194
  const authMiddleware = async _ref2 => {
200
195
  let {
201
196
  context,
202
- isValidSession
197
+ wasAccessAllowed
203
198
  } = _ref2;
204
199
  const {
205
200
  req,
206
201
  session
207
202
  } = context;
208
203
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
209
-
210
- if (isValidSession) {
204
+ if (wasAccessAllowed) {
211
205
  if (customPath !== '' && pathname === '/') {
212
206
  return {
213
207
  kind: 'redirect',
214
208
  to: `${customPath}`
215
209
  };
216
210
  }
217
-
218
211
  return;
219
212
  }
220
-
221
213
  if (!session && !_includesInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`)) {
222
214
  return {
223
215
  kind: 'redirect',
@@ -225,6 +217,7 @@ function createAuth(_ref) {
225
217
  };
226
218
  }
227
219
  };
220
+
228
221
  /**
229
222
  * authGetAdditionalFiles
230
223
  *
@@ -233,8 +226,6 @@ function createAuth(_ref) {
233
226
  *
234
227
  * The signin page is always included, and the init page is included when initFirstItem is set
235
228
  */
236
-
237
-
238
229
  const authGetAdditionalFiles = () => {
239
230
  const filesToWrite = [{
240
231
  mode: 'write',
@@ -255,84 +246,75 @@ function createAuth(_ref) {
255
246
  }];
256
247
  return filesToWrite;
257
248
  };
249
+
258
250
  /**
259
251
  * publicAuthPages
260
252
  *
261
253
  * Must be added to the ui.publicPages config
262
254
  */
263
-
264
-
265
- const authPublicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`]; // TODO: Add Provider Types
255
+ const authPublicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`];
256
+ // TODO: Add Provider Types
266
257
  // @ts-ignore
267
-
268
258
  function addPages(provider) {
269
259
  const name = provider.id;
270
260
  authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
271
261
  authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
272
262
  }
273
-
274
263
  _mapInstanceProperty__default["default"](providers).call(providers, addPages);
264
+
275
265
  /**
276
266
  * extendGraphqlSchema
277
267
  *
278
268
  * Must be added to the extendGraphqlSchema config. Can be composed.
279
269
  */
280
-
281
-
282
270
  const extendGraphqlSchema = getSchemaExtension({
283
271
  identityField,
284
272
  listKey
285
273
  });
274
+
286
275
  /**
287
276
  * validateConfig
288
277
  *
289
278
  * Validates the provided auth config; optional step when integrating auth
290
279
  */
291
-
292
280
  const validateConfig = keystoneConfig => {
293
281
  const listConfig = keystoneConfig.lists[listKey];
294
-
295
282
  if (listConfig === undefined) {
296
283
  const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
297
284
  throw new Error(msg);
298
- } // TODO: Check if providers
285
+ }
286
+
287
+ // TODO: Check if providers
299
288
  // TODO: Check other required commands/data
289
+
300
290
  // TODO: Check for String-like typing for identityField? How?
301
291
  // TODO: Validate that the identifyField is unique.
302
292
  // TODO: If this field isn't required, what happens if I try to log in as `null`?
303
-
304
-
305
293
  const identityFieldConfig = listConfig.fields[identityField];
306
-
307
294
  if (identityFieldConfig === undefined) {
308
295
  const identityFieldName = _JSON$stringify__default["default"](identityField);
309
-
310
296
  const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
311
297
  throw new Error(msg);
312
298
  }
313
299
  };
300
+
314
301
  /**
315
302
  * withItemData
316
303
  *
317
304
  * Automatically injects a session.data value with the authenticated item
318
305
  */
319
-
320
306
  /* TODO:
321
307
  - [ ] We could support additional where input to validate item sessions (e.g an isEnabled boolean)
322
308
  */
323
-
324
-
325
309
  const withItemData = _sessionStrategy => {
326
310
  const {
327
- get,
328
- end
329
- } = _sessionStrategy,
330
- sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
331
-
311
+ get,
312
+ end
313
+ } = _sessionStrategy,
314
+ sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
332
315
  return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
333
316
  get: async _ref3 => {
334
317
  var _req$headers, _req$headers$authoriz;
335
-
336
318
  let {
337
319
  context
338
320
  } = _ref3;
@@ -342,13 +324,10 @@ function createAuth(_ref) {
342
324
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
343
325
  let nextSession;
344
326
  if (!req) return;
345
-
346
327
  if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
347
328
  return;
348
329
  }
349
-
350
330
  const sudoContext = context.sudo();
351
-
352
331
  if (((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : (_req$headers$authoriz = _req$headers.authorization) === null || _req$headers$authoriz === void 0 ? void 0 : _req$headers$authoriz.split(' ')[0]) === 'Bearer') {
353
332
  nextSession = await jwt.getToken({
354
333
  req: req,
@@ -359,11 +338,9 @@ function createAuth(_ref) {
359
338
  req
360
339
  });
361
340
  }
362
-
363
341
  if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
364
342
  return;
365
343
  }
366
-
367
344
  const reqWithUser = req;
368
345
  reqWithUser.user = {
369
346
  istKey: nextSession.listKey,
@@ -405,7 +382,6 @@ function createAuth(_ref) {
405
382
  }
406
383
  });
407
384
  };
408
-
409
385
  function defaultIsAccessAllowed(_ref5) {
410
386
  let {
411
387
  session
@@ -422,16 +398,12 @@ function createAuth(_ref) {
422
398
  * It validates the auth config against the provided keystone config, and preserves existing
423
399
  * config by composing existing extendGraphqlSchema functions and ui config.
424
400
  */
425
-
426
-
427
401
  const withAuth = keystoneConfig => {
428
402
  var _ui;
429
-
430
403
  validateConfig(keystoneConfig);
431
404
  let {
432
405
  ui
433
406
  } = keystoneConfig;
434
-
435
407
  if (!((_ui = ui) !== null && _ui !== void 0 && _ui.isDisabled)) {
436
408
  const {
437
409
  getAdditionalFiles = [],
@@ -443,13 +415,10 @@ function createAuth(_ref) {
443
415
  publicPages: [...publicPages, ...authPublicPages],
444
416
  isAccessAllowed: async context => {
445
417
  var _context$req;
446
-
447
418
  const pathname = url__default["default"].parse((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url).pathname;
448
-
449
419
  if (_startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/_next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/__next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`) || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || pages !== null && pages !== void 0 && pages.error && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || pages !== null && pages !== void 0 && pages.signOut && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
450
420
  return true;
451
421
  }
452
-
453
422
  return await isAccessAllowed(context);
454
423
  },
455
424
  getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
@@ -460,7 +429,6 @@ function createAuth(_ref) {
460
429
  }
461
430
  });
462
431
  }
463
-
464
432
  if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
465
433
  const session = withItemData(keystoneConfig.session);
466
434
  const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
@@ -475,16 +443,15 @@ function createAuth(_ref) {
475
443
  extendGraphqlSchema: existingExtendGraphQLSchema ? schema => existingExtendGraphQLSchema(extendGraphqlSchema(schema)) : extendGraphqlSchema
476
444
  });
477
445
  };
478
-
479
446
  return {
480
- withAuth // In the future we may want to return the following so that developers can
447
+ withAuth
448
+ // In the future we may want to return the following so that developers can
481
449
  // roll their own. This is pending a review of the use cases this might be
482
450
  // appropriate for, along with documentation and testing.
483
451
  // ui: { enableSessionItem: true, pageMiddleware, getAdditionalFiles, publicPages },
484
452
  // fields,
485
453
  // extendGraphqlSchema,
486
454
  // validateConfig,
487
-
488
455
  };
489
456
  }
490
457
 
@@ -75,17 +75,14 @@ function getBaseAuthSchema(_ref) {
75
75
  types: [base.object(listKey)],
76
76
  resolveType: (root, context) => {
77
77
  var _context$session;
78
-
79
78
  return (_context$session = context.session) === null || _context$session === void 0 ? void 0 : _context$session.listKey;
80
79
  }
81
80
  }),
82
-
83
81
  resolve(root, args, _ref2) {
84
82
  let {
85
83
  session,
86
84
  db
87
85
  } = _ref2;
88
-
89
86
  if (typeof (session === null || session === void 0 ? void 0 : session.itemId) === 'string' && typeof session.listKey === 'string') {
90
87
  return db[session.listKey].findOne({
91
88
  where: {
@@ -93,10 +90,8 @@ function getBaseAuthSchema(_ref) {
93
90
  }
94
91
  });
95
92
  }
96
-
97
93
  return null;
98
94
  }
99
-
100
95
  })
101
96
  }
102
97
  };
@@ -111,7 +106,6 @@ const getSchemaExtension = _ref => {
111
106
  } = _ref;
112
107
  return core.graphql.extend(base => {
113
108
  var _context;
114
-
115
109
  const baseSchema = getBaseAuthSchema({
116
110
  listKey,
117
111
  base
@@ -161,6 +155,7 @@ const authTemplate = _ref => {
161
155
  };
162
156
 
163
157
  const _excluded = ["get", "end"];
158
+
164
159
  /**
165
160
  * createAuth function
166
161
  *
@@ -184,6 +179,7 @@ function createAuth(_ref) {
184
179
  // part of the createAuth API (in which case its use cases need to be documented and tested)
185
180
  // or whether always being true is what we want, in which case we can refactor our code
186
181
  // to match this. -TL
182
+
187
183
  const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
188
184
  /**
189
185
  * pageMiddleware
@@ -195,29 +191,25 @@ function createAuth(_ref) {
195
191
  * - to the init page when initFirstItem is configured, and there are no user in the database
196
192
  * - to the signin page when no valid session is present
197
193
  */
198
-
199
194
  const authMiddleware = async _ref2 => {
200
195
  let {
201
196
  context,
202
- isValidSession
197
+ wasAccessAllowed
203
198
  } = _ref2;
204
199
  const {
205
200
  req,
206
201
  session
207
202
  } = context;
208
203
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
209
-
210
- if (isValidSession) {
204
+ if (wasAccessAllowed) {
211
205
  if (customPath !== '' && pathname === '/') {
212
206
  return {
213
207
  kind: 'redirect',
214
208
  to: `${customPath}`
215
209
  };
216
210
  }
217
-
218
211
  return;
219
212
  }
220
-
221
213
  if (!session && !_includesInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`)) {
222
214
  return {
223
215
  kind: 'redirect',
@@ -225,6 +217,7 @@ function createAuth(_ref) {
225
217
  };
226
218
  }
227
219
  };
220
+
228
221
  /**
229
222
  * authGetAdditionalFiles
230
223
  *
@@ -233,8 +226,6 @@ function createAuth(_ref) {
233
226
  *
234
227
  * The signin page is always included, and the init page is included when initFirstItem is set
235
228
  */
236
-
237
-
238
229
  const authGetAdditionalFiles = () => {
239
230
  const filesToWrite = [{
240
231
  mode: 'write',
@@ -255,84 +246,75 @@ function createAuth(_ref) {
255
246
  }];
256
247
  return filesToWrite;
257
248
  };
249
+
258
250
  /**
259
251
  * publicAuthPages
260
252
  *
261
253
  * Must be added to the ui.publicPages config
262
254
  */
263
-
264
-
265
- const authPublicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`]; // TODO: Add Provider Types
255
+ const authPublicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`];
256
+ // TODO: Add Provider Types
266
257
  // @ts-ignore
267
-
268
258
  function addPages(provider) {
269
259
  const name = provider.id;
270
260
  authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
271
261
  authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
272
262
  }
273
-
274
263
  _mapInstanceProperty__default["default"](providers).call(providers, addPages);
264
+
275
265
  /**
276
266
  * extendGraphqlSchema
277
267
  *
278
268
  * Must be added to the extendGraphqlSchema config. Can be composed.
279
269
  */
280
-
281
-
282
270
  const extendGraphqlSchema = getSchemaExtension({
283
271
  identityField,
284
272
  listKey
285
273
  });
274
+
286
275
  /**
287
276
  * validateConfig
288
277
  *
289
278
  * Validates the provided auth config; optional step when integrating auth
290
279
  */
291
-
292
280
  const validateConfig = keystoneConfig => {
293
281
  const listConfig = keystoneConfig.lists[listKey];
294
-
295
282
  if (listConfig === undefined) {
296
283
  const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
297
284
  throw new Error(msg);
298
- } // TODO: Check if providers
285
+ }
286
+
287
+ // TODO: Check if providers
299
288
  // TODO: Check other required commands/data
289
+
300
290
  // TODO: Check for String-like typing for identityField? How?
301
291
  // TODO: Validate that the identifyField is unique.
302
292
  // TODO: If this field isn't required, what happens if I try to log in as `null`?
303
-
304
-
305
293
  const identityFieldConfig = listConfig.fields[identityField];
306
-
307
294
  if (identityFieldConfig === undefined) {
308
295
  const identityFieldName = _JSON$stringify__default["default"](identityField);
309
-
310
296
  const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
311
297
  throw new Error(msg);
312
298
  }
313
299
  };
300
+
314
301
  /**
315
302
  * withItemData
316
303
  *
317
304
  * Automatically injects a session.data value with the authenticated item
318
305
  */
319
-
320
306
  /* TODO:
321
307
  - [ ] We could support additional where input to validate item sessions (e.g an isEnabled boolean)
322
308
  */
323
-
324
-
325
309
  const withItemData = _sessionStrategy => {
326
310
  const {
327
- get,
328
- end
329
- } = _sessionStrategy,
330
- sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
331
-
311
+ get,
312
+ end
313
+ } = _sessionStrategy,
314
+ sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
332
315
  return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
333
316
  get: async _ref3 => {
334
317
  var _req$headers, _req$headers$authoriz;
335
-
336
318
  let {
337
319
  context
338
320
  } = _ref3;
@@ -342,13 +324,10 @@ function createAuth(_ref) {
342
324
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
343
325
  let nextSession;
344
326
  if (!req) return;
345
-
346
327
  if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
347
328
  return;
348
329
  }
349
-
350
330
  const sudoContext = context.sudo();
351
-
352
331
  if (((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : (_req$headers$authoriz = _req$headers.authorization) === null || _req$headers$authoriz === void 0 ? void 0 : _req$headers$authoriz.split(' ')[0]) === 'Bearer') {
353
332
  nextSession = await jwt.getToken({
354
333
  req: req,
@@ -359,11 +338,9 @@ function createAuth(_ref) {
359
338
  req
360
339
  });
361
340
  }
362
-
363
341
  if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
364
342
  return;
365
343
  }
366
-
367
344
  const reqWithUser = req;
368
345
  reqWithUser.user = {
369
346
  istKey: nextSession.listKey,
@@ -405,7 +382,6 @@ function createAuth(_ref) {
405
382
  }
406
383
  });
407
384
  };
408
-
409
385
  function defaultIsAccessAllowed(_ref5) {
410
386
  let {
411
387
  session
@@ -422,16 +398,12 @@ function createAuth(_ref) {
422
398
  * It validates the auth config against the provided keystone config, and preserves existing
423
399
  * config by composing existing extendGraphqlSchema functions and ui config.
424
400
  */
425
-
426
-
427
401
  const withAuth = keystoneConfig => {
428
402
  var _ui;
429
-
430
403
  validateConfig(keystoneConfig);
431
404
  let {
432
405
  ui
433
406
  } = keystoneConfig;
434
-
435
407
  if (!((_ui = ui) !== null && _ui !== void 0 && _ui.isDisabled)) {
436
408
  const {
437
409
  getAdditionalFiles = [],
@@ -443,13 +415,10 @@ function createAuth(_ref) {
443
415
  publicPages: [...publicPages, ...authPublicPages],
444
416
  isAccessAllowed: async context => {
445
417
  var _context$req;
446
-
447
418
  const pathname = url__default["default"].parse((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url).pathname;
448
-
449
419
  if (_startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/_next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/__next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`) || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || pages !== null && pages !== void 0 && pages.error && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || pages !== null && pages !== void 0 && pages.signOut && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
450
420
  return true;
451
421
  }
452
-
453
422
  return await isAccessAllowed(context);
454
423
  },
455
424
  getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
@@ -460,7 +429,6 @@ function createAuth(_ref) {
460
429
  }
461
430
  });
462
431
  }
463
-
464
432
  if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
465
433
  const session = withItemData(keystoneConfig.session);
466
434
  const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
@@ -475,16 +443,15 @@ function createAuth(_ref) {
475
443
  extendGraphqlSchema: existingExtendGraphQLSchema ? schema => existingExtendGraphQLSchema(extendGraphqlSchema(schema)) : extendGraphqlSchema
476
444
  });
477
445
  };
478
-
479
446
  return {
480
- withAuth // In the future we may want to return the following so that developers can
447
+ withAuth
448
+ // In the future we may want to return the following so that developers can
481
449
  // roll their own. This is pending a review of the use cases this might be
482
450
  // appropriate for, along with documentation and testing.
483
451
  // ui: { enableSessionItem: true, pageMiddleware, getAdditionalFiles, publicPages },
484
452
  // fields,
485
453
  // extendGraphqlSchema,
486
454
  // validateConfig,
487
-
488
455
  };
489
456
  }
490
457