postgraphile 4.12.11 → 5.0.0-0.3

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 (134) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE.md +15 -20
  3. package/README.md +20 -171
  4. package/dist/cli-run.d.ts +3 -0
  5. package/dist/cli-run.d.ts.map +1 -0
  6. package/dist/cli-run.js +7 -0
  7. package/dist/cli-run.js.map +1 -0
  8. package/dist/cli.d.ts +21 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +180 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/index.d.ts +14 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +88 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/plugins/PgV4BehaviorPlugin.d.ts +11 -0
  17. package/dist/plugins/PgV4BehaviorPlugin.d.ts.map +1 -0
  18. package/dist/plugins/PgV4BehaviorPlugin.js +73 -0
  19. package/dist/plugins/PgV4BehaviorPlugin.js.map +1 -0
  20. package/dist/plugins/PgV4InflectionPlugin.d.ts +11 -0
  21. package/dist/plugins/PgV4InflectionPlugin.d.ts.map +1 -0
  22. package/dist/plugins/PgV4InflectionPlugin.js +91 -0
  23. package/dist/plugins/PgV4InflectionPlugin.js.map +1 -0
  24. package/dist/plugins/PgV4NoIgnoreIndexes.d.ts +2 -0
  25. package/dist/plugins/PgV4NoIgnoreIndexes.d.ts.map +1 -0
  26. package/dist/plugins/PgV4NoIgnoreIndexes.js +72 -0
  27. package/dist/plugins/PgV4NoIgnoreIndexes.js.map +1 -0
  28. package/dist/plugins/PgV4SmartTagsPlugin.d.ts +11 -0
  29. package/dist/plugins/PgV4SmartTagsPlugin.d.ts.map +1 -0
  30. package/dist/plugins/PgV4SmartTagsPlugin.js +190 -0
  31. package/dist/plugins/PgV4SmartTagsPlugin.js.map +1 -0
  32. package/dist/presets/amber.d.ts +5 -0
  33. package/dist/presets/amber.d.ts.map +1 -0
  34. package/dist/presets/amber.js +38 -0
  35. package/dist/presets/amber.js.map +1 -0
  36. package/dist/presets/v4.d.ts +34 -0
  37. package/dist/presets/v4.d.ts.map +1 -0
  38. package/dist/presets/v4.js +142 -0
  39. package/dist/presets/v4.js.map +1 -0
  40. package/dist/schema.d.ts +34 -0
  41. package/dist/schema.d.ts.map +1 -0
  42. package/dist/schema.js +82 -0
  43. package/dist/schema.js.map +1 -0
  44. package/package.json +77 -154
  45. package/build/assets/favicon.ico.d.ts +0 -3
  46. package/build/assets/favicon.ico.js +0 -6
  47. package/build/assets/graphiql.html.d.ts +0 -2
  48. package/build/assets/graphiql.html.js +0 -6
  49. package/build/index.d.ts +0 -8
  50. package/build/index.js +0 -34
  51. package/build/interfaces.d.ts +0 -162
  52. package/build/interfaces.js +0 -3
  53. package/build/plugins.d.ts +0 -3
  54. package/build/plugins.js +0 -53
  55. package/build/postgraphile/cli.d.ts +0 -3
  56. package/build/postgraphile/cli.js +0 -541
  57. package/build/postgraphile/extendedFormatError.d.ts +0 -9
  58. package/build/postgraphile/extendedFormatError.js +0 -51
  59. package/build/postgraphile/http/createPostGraphileHttpRequestHandler.d.ts +0 -11
  60. package/build/postgraphile/http/createPostGraphileHttpRequestHandler.js +0 -974
  61. package/build/postgraphile/http/frameworks.d.ts +0 -110
  62. package/build/postgraphile/http/frameworks.js +0 -258
  63. package/build/postgraphile/http/liveSubscribe.d.ts +0 -22
  64. package/build/postgraphile/http/liveSubscribe.js +0 -89
  65. package/build/postgraphile/http/mapAsyncIterator.d.ts +0 -15
  66. package/build/postgraphile/http/mapAsyncIterator.js +0 -71
  67. package/build/postgraphile/http/setupServerSentEvents.d.ts +0 -9
  68. package/build/postgraphile/http/setupServerSentEvents.js +0 -51
  69. package/build/postgraphile/http/subscriptions.d.ts +0 -7
  70. package/build/postgraphile/http/subscriptions.js +0 -410
  71. package/build/postgraphile/index.d.ts +0 -5
  72. package/build/postgraphile/index.js +0 -14
  73. package/build/postgraphile/pluginHook.d.ts +0 -104
  74. package/build/postgraphile/pluginHook.js +0 -100
  75. package/build/postgraphile/postgraphile.d.ts +0 -20
  76. package/build/postgraphile/postgraphile.js +0 -332
  77. package/build/postgraphile/postgraphilerc.d.ts +0 -2
  78. package/build/postgraphile/postgraphilerc.js +0 -16
  79. package/build/postgraphile/schema/exportPostGraphileSchema.d.ts +0 -6
  80. package/build/postgraphile/schema/exportPostGraphileSchema.js +0 -45
  81. package/build/postgraphile/shutdownActions.d.ts +0 -41
  82. package/build/postgraphile/shutdownActions.js +0 -87
  83. package/build/postgraphile/withPostGraphileContext.d.ts +0 -55
  84. package/build/postgraphile/withPostGraphileContext.js +0 -457
  85. package/build/postgres/inventory/pgClientFromContext.d.ts +0 -8
  86. package/build/postgres/inventory/pgClientFromContext.js +0 -21
  87. package/build-turbo/assets/favicon.ico.d.ts +0 -3
  88. package/build-turbo/assets/favicon.ico.js +0 -6
  89. package/build-turbo/assets/graphiql.html.d.ts +0 -2
  90. package/build-turbo/assets/graphiql.html.js +0 -6
  91. package/build-turbo/index.d.ts +0 -8
  92. package/build-turbo/index.js +0 -34
  93. package/build-turbo/interfaces.d.ts +0 -162
  94. package/build-turbo/interfaces.js +0 -3
  95. package/build-turbo/plugins.d.ts +0 -3
  96. package/build-turbo/plugins.js +0 -53
  97. package/build-turbo/postgraphile/cli.d.ts +0 -3
  98. package/build-turbo/postgraphile/cli.js +0 -572
  99. package/build-turbo/postgraphile/extendedFormatError.d.ts +0 -9
  100. package/build-turbo/postgraphile/extendedFormatError.js +0 -61
  101. package/build-turbo/postgraphile/http/createPostGraphileHttpRequestHandler.d.ts +0 -11
  102. package/build-turbo/postgraphile/http/createPostGraphileHttpRequestHandler.js +0 -982
  103. package/build-turbo/postgraphile/http/frameworks.d.ts +0 -110
  104. package/build-turbo/postgraphile/http/frameworks.js +0 -258
  105. package/build-turbo/postgraphile/http/liveSubscribe.d.ts +0 -22
  106. package/build-turbo/postgraphile/http/liveSubscribe.js +0 -89
  107. package/build-turbo/postgraphile/http/mapAsyncIterator.d.ts +0 -15
  108. package/build-turbo/postgraphile/http/mapAsyncIterator.js +0 -71
  109. package/build-turbo/postgraphile/http/setupServerSentEvents.d.ts +0 -9
  110. package/build-turbo/postgraphile/http/setupServerSentEvents.js +0 -51
  111. package/build-turbo/postgraphile/http/subscriptions.d.ts +0 -7
  112. package/build-turbo/postgraphile/http/subscriptions.js +0 -409
  113. package/build-turbo/postgraphile/index.d.ts +0 -5
  114. package/build-turbo/postgraphile/index.js +0 -14
  115. package/build-turbo/postgraphile/pluginHook.d.ts +0 -104
  116. package/build-turbo/postgraphile/pluginHook.js +0 -100
  117. package/build-turbo/postgraphile/postgraphile.d.ts +0 -20
  118. package/build-turbo/postgraphile/postgraphile.js +0 -337
  119. package/build-turbo/postgraphile/postgraphilerc.d.ts +0 -2
  120. package/build-turbo/postgraphile/postgraphilerc.js +0 -16
  121. package/build-turbo/postgraphile/schema/exportPostGraphileSchema.d.ts +0 -6
  122. package/build-turbo/postgraphile/schema/exportPostGraphileSchema.js +0 -45
  123. package/build-turbo/postgraphile/shutdownActions.d.ts +0 -41
  124. package/build-turbo/postgraphile/shutdownActions.js +0 -87
  125. package/build-turbo/postgraphile/withPostGraphileContext.d.ts +0 -55
  126. package/build-turbo/postgraphile/withPostGraphileContext.js +0 -466
  127. package/build-turbo/postgres/inventory/pgClientFromContext.d.ts +0 -8
  128. package/build-turbo/postgres/inventory/pgClientFromContext.js +0 -21
  129. package/cli.js +0 -6
  130. package/index.js +0 -5
  131. package/isTurbo.js +0 -11
  132. package/plugins.d.ts +0 -1
  133. package/plugins.js +0 -5
  134. package/sponsors.json +0 -150
@@ -1,974 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmpty = void 0;
4
- /* eslint-disable @typescript-eslint/no-explicit-any,require-atomic-updates */
5
- const graphql_1 = require("graphql");
6
- const extendedFormatError_1 = require("../extendedFormatError");
7
- const pluginHook_1 = require("../pluginHook");
8
- const setupServerSentEvents_1 = require("./setupServerSentEvents");
9
- const withPostGraphileContext_1 = require("../withPostGraphileContext");
10
- const lru_1 = require("@graphile/lru");
11
- const chalk_1 = require("chalk");
12
- const Debugger = require("debug"); // tslint:disable-line variable-name
13
- const httpError = require("http-errors");
14
- const parseUrl = require("parseurl");
15
- const finalHandler = require("finalhandler");
16
- const bodyParser = require("body-parser");
17
- const crypto = require("crypto");
18
- const isKoaApp = (a, b) => a.req && a.res && typeof b === 'function';
19
- const CACHE_MULTIPLIER = 100000;
20
- const ALLOW_EXPLAIN_PLACEHOLDER = '__SHOULD_ALLOW_EXPLAIN__';
21
- const noop = () => {
22
- /* noop */
23
- };
24
- const { createHash } = crypto;
25
- /**
26
- * The favicon file in `Buffer` format. We can send a `Buffer` directly to the
27
- * client.
28
- *
29
- * @type {Buffer}
30
- */
31
- const favicon_ico_1 = require("../../assets/favicon.ico");
32
- /**
33
- * The GraphiQL HTML file as a string. We need it to be a string, because we
34
- * will use a regular expression to replace some variables.
35
- */
36
- const graphiql_html_1 = require("../../assets/graphiql.html");
37
- const subscriptions_1 = require("./subscriptions");
38
- const frameworks_1 = require("./frameworks");
39
- /**
40
- * When writing JSON to the browser, we need to be careful that it doesn't get
41
- * interpretted as HTML.
42
- */
43
- const JS_ESCAPE_LOOKUP = {
44
- '<': '\\u003c',
45
- '>': '\\u003e',
46
- '/': '\\u002f',
47
- '\u2028': '\\u2028',
48
- '\u2029': '\\u2029',
49
- };
50
- function safeJSONStringify(obj) {
51
- return JSON.stringify(obj).replace(/[<>/\u2028\u2029]/g, chr => JS_ESCAPE_LOOKUP[chr]);
52
- }
53
- /**
54
- * When people webpack us up, e.g. for lambda, if they don't want GraphiQL then
55
- * they can seriously reduce bundle size by omitting the assets.
56
- */
57
- const shouldOmitAssets = process.env.POSTGRAPHILE_OMIT_ASSETS === '1';
58
- // Used by `createPostGraphileHttpRequestHandler`
59
- let lastString;
60
- let lastHash;
61
- const calculateQueryHash = (queryString) => {
62
- if (queryString !== lastString) {
63
- lastString = queryString;
64
- lastHash = createHash('sha1').update(queryString).digest('base64');
65
- }
66
- return lastHash;
67
- };
68
- // Fast way of checking if an object is empty,
69
- // faster than `Object.keys(value).length === 0`.
70
- // NOTE: we don't need a `hasOwnProperty` call here because isEmpty is called
71
- // with an `Object.create(null)` object, so it has no no-own properties.
72
- /* tslint:disable forin */
73
- function isEmpty(value) {
74
- for (const _key in value) {
75
- return false;
76
- }
77
- return true;
78
- }
79
- exports.isEmpty = isEmpty;
80
- /* tslint:enable forin */
81
- const isPostGraphileDevelopmentMode = process.env.POSTGRAPHILE_ENV === 'development';
82
- const debugGraphql = Debugger('postgraphile:graphql');
83
- const debugRequest = Debugger('postgraphile:request');
84
- /**
85
- * We need to be able to share the withPostGraphileContext logic between HTTP
86
- * and websockets
87
- */
88
- function withPostGraphileContextFromReqResGenerator(options) {
89
- const { pgSettings: pgSettingsGenerator, allowExplain: allowExplainGenerator, jwtSecret, jwtPublicKey, additionalGraphQLContextFromRequest, } = options;
90
- return async (req, res, moreOptions, fn) => {
91
- const jwtVerificationSecret = jwtPublicKey || jwtSecret;
92
- const jwtToken = jwtVerificationSecret ? getJwtToken(req) : null;
93
- const additionalContext = typeof additionalGraphQLContextFromRequest === 'function'
94
- ? await additionalGraphQLContextFromRequest(req, res)
95
- : null;
96
- const pgSettings = typeof pgSettingsGenerator === 'function'
97
- ? await pgSettingsGenerator(req)
98
- : pgSettingsGenerator;
99
- const allowExplain = typeof allowExplainGenerator === 'function'
100
- ? await allowExplainGenerator(req)
101
- : allowExplainGenerator;
102
- return withPostGraphileContext_1.default(Object.assign(Object.assign(Object.assign({}, options), { jwtToken,
103
- pgSettings, explain: allowExplain && req.headers['x-postgraphile-explain'] === 'on' }), moreOptions), context => {
104
- const graphqlContext = additionalContext
105
- ? Object.assign(Object.assign({}, additionalContext), context) : context;
106
- return fn(graphqlContext);
107
- });
108
- };
109
- }
110
- /**
111
- * Creates a GraphQL request handler that can support many different `http` frameworks, including:
112
- *
113
- * - Native Node.js `http`.
114
- * - `connect`.
115
- * - `express`.
116
- * - `koa` (2.0).
117
- */
118
- function createPostGraphileHttpRequestHandler(options) {
119
- const MEGABYTE = 1024 * 1024;
120
- const subscriptions = !!options.subscriptions;
121
- const { getGqlSchema, pgPool, pgSettings, pgDefaultRole, shutdownActions, queryCacheMaxSize = 50 * MEGABYTE, extendedErrors, showErrorStack, watchPg, disableQueryLog, enableQueryBatching, websockets = options.subscriptions || options.live ? ['v0', 'v1'] : [], } = options;
122
- const live = !!options.live;
123
- const enhanceGraphiql = options.enhanceGraphiql === false ? false : !!options.enhanceGraphiql || subscriptions || live;
124
- const enableCors = !!options.enableCors || isPostGraphileDevelopmentMode;
125
- const graphiql = options.graphiql === true;
126
- if (options['absoluteRoutes']) {
127
- throw new Error('Sorry - the `absoluteRoutes` setting has been replaced with `externalUrlBase` which solves the issue in a cleaner way. Please update your settings. Thank you for testing a PostGraphile pre-release 🙏');
128
- }
129
- // Using let because we might override it on the first request.
130
- let externalUrlBase = options.externalUrlBase;
131
- if (externalUrlBase && externalUrlBase.endsWith('/')) {
132
- throw new Error('externalUrlBase must not end with a slash (`/`)');
133
- }
134
- // Validate websockets argument
135
- if (
136
- // must be array
137
- !Array.isArray(websockets) ||
138
- // empty array = 'none'
139
- (websockets.length &&
140
- // array can only hold the versions
141
- websockets.some(ver => !['v0', 'v1'].includes(ver)))) {
142
- throw new Error(`Invalid value for \`websockets\` option: '${websockets}'`);
143
- }
144
- const pluginHook = pluginHook_1.pluginHookFromOptions(options);
145
- const origGraphiqlHtml = pluginHook('postgraphile:graphiql:html', graphiql_html_1.default, { options });
146
- if (pgDefaultRole && typeof pgSettings === 'function') {
147
- throw new Error('pgDefaultRole cannot be combined with pgSettings(req) - please remove pgDefaultRole and instead always return a `role` key from pgSettings(req).');
148
- }
149
- if (pgDefaultRole &&
150
- pgSettings &&
151
- typeof pgSettings === 'object' &&
152
- Object.keys(pgSettings)
153
- .map(s => s.toLowerCase())
154
- .includes('role')) {
155
- throw new Error('pgDefaultRole cannot be combined with pgSettings.role - please use one or the other.');
156
- }
157
- if (graphiql && shouldOmitAssets) {
158
- throw new Error('Cannot enable GraphiQL when POSTGRAPHILE_OMIT_ASSETS is set');
159
- }
160
- // Gets the route names for our GraphQL endpoint, and our GraphiQL endpoint.
161
- const graphqlRoute = options.graphqlRoute || '/graphql';
162
- const graphiqlRoute = options.graphiqlRoute || '/graphiql';
163
- // Set the request credential behavior in graphiql.
164
- const graphiqlCredentials = options.graphiqlCredentials || 'same-origin';
165
- const eventStreamRoute = options.eventStreamRoute || `${graphqlRoute.replace(/\/+$/, '')}/stream`;
166
- const externalGraphqlRoute = options.externalGraphqlRoute;
167
- const externalEventStreamRoute = options.externalEventStreamRoute ||
168
- (externalGraphqlRoute && !options.eventStreamRoute
169
- ? `${externalGraphqlRoute.replace(/\/+$/, '')}/stream`
170
- : undefined);
171
- // Throw an error of the GraphQL and GraphiQL routes are the same.
172
- if (graphqlRoute === graphiqlRoute)
173
- throw new Error(`Cannot use the same route, '${graphqlRoute}', for both GraphQL and GraphiQL. Please use different routes.`);
174
- // Formats an error using the default GraphQL `formatError` function, and
175
- // custom formatting using some other options.
176
- const formatError = (error) => {
177
- // Get the appropriate formatted error object, including any extended error
178
- // fields if the user wants them.
179
- const formattedError = extendedErrors && extendedErrors.length
180
- ? extendedFormatError_1.extendedFormatError(error, extendedErrors)
181
- : graphql_1.formatError(error);
182
- // If the user wants to see the error’s stack, let’s add it to the
183
- // formatted error.
184
- if (showErrorStack)
185
- formattedError['stack'] =
186
- error.stack != null && showErrorStack === 'json' ? error.stack.split('\n') : error.stack;
187
- return formattedError;
188
- };
189
- const DEFAULT_HANDLE_ERRORS = (errors) => errors.map(formatError);
190
- const handleErrors = options.handleErrors || DEFAULT_HANDLE_ERRORS;
191
- // Define a list of middlewares that will get run before our request handler.
192
- // Note though that none of these middlewares will intercept a request (i.e.
193
- // not call `next`). Middlewares that handle a request like favicon
194
- // middleware will result in a promise that never resolves, and we don’t
195
- // want that.
196
- const bodyParserMiddlewares = [
197
- // Parse JSON bodies.
198
- bodyParser.json({ limit: options.bodySizeLimit }),
199
- // Parse URL encoded bodies (forms).
200
- bodyParser.urlencoded({ extended: false, limit: options.bodySizeLimit }),
201
- // Parse `application/graphql` content type bodies as text.
202
- bodyParser.text({ type: 'application/graphql', limit: options.bodySizeLimit }),
203
- ];
204
- // We'll turn this into one function now so it can be better JIT optimised
205
- const bodyParserMiddlewaresComposed = bodyParserMiddlewares.reduce((parent, fn) => {
206
- return (req, res, next) => {
207
- parent(req, res, error => {
208
- if (error) {
209
- return next(error);
210
- }
211
- fn(req, res, next);
212
- });
213
- };
214
- }, (_req, _res, next) => next());
215
- // And we really want that function to be await-able
216
- const parseBody = (req, res) => new Promise((resolve, reject) => {
217
- bodyParserMiddlewaresComposed(req,
218
- // Note: middleware here doesn't actually use the response, but we pass
219
- // the underlying value so types match up.
220
- res.getNodeServerResponse(), (error) => {
221
- if (error) {
222
- reject(error);
223
- }
224
- else {
225
- resolve();
226
- }
227
- });
228
- });
229
- // We only need to calculate the graphiql HTML once; but we need to receive the first request to do so.
230
- let graphiqlHtml;
231
- const withPostGraphileContextFromReqRes = withPostGraphileContextFromReqResGenerator(options);
232
- const staticValidationRules = pluginHook('postgraphile:validationRules:static', graphql_1.specifiedRules, {
233
- options,
234
- });
235
- const cacheSize = Math.ceil(queryCacheMaxSize / CACHE_MULTIPLIER);
236
- // Do not create an LRU for cache size < 2 because @graphile/lru will baulk.
237
- const cacheEnabled = cacheSize >= 2;
238
- const queryCache = cacheEnabled ? new lru_1.default({ maxLength: cacheSize }) : null;
239
- let lastGqlSchema;
240
- const parseQuery = (gqlSchema, queryString) => {
241
- if (gqlSchema !== lastGqlSchema) {
242
- if (queryCache) {
243
- queryCache.reset();
244
- }
245
- lastGqlSchema = gqlSchema;
246
- }
247
- // Only cache queries that are less than 100kB, we don't want DOS attacks
248
- // attempting to exhaust our memory.
249
- const canCache = cacheEnabled && queryString.length < 100000;
250
- const hash = canCache ? calculateQueryHash(queryString) : null;
251
- const result = canCache ? queryCache.get(hash) : null;
252
- if (result) {
253
- return result;
254
- }
255
- else {
256
- const source = new graphql_1.Source(queryString, 'GraphQL Http Request');
257
- let queryDocumentAst;
258
- // Catch an errors while parsing so that we can set the `statusCode` to
259
- // 400. Otherwise we don’t need to parse this way.
260
- try {
261
- queryDocumentAst = graphql_1.parse(source);
262
- }
263
- catch (error) {
264
- error.statusCode = 400;
265
- throw error;
266
- }
267
- if (debugRequest.enabled)
268
- debugRequest('GraphQL query is parsed.');
269
- // Validate our GraphQL query using given rules.
270
- const validationErrors = graphql_1.validate(gqlSchema, queryDocumentAst, staticValidationRules);
271
- const cacheResult = {
272
- queryDocumentAst,
273
- validationErrors,
274
- length: queryString.length,
275
- };
276
- if (canCache) {
277
- queryCache.set(hash, cacheResult);
278
- }
279
- return cacheResult;
280
- }
281
- };
282
- let firstRequestHandler = req => {
283
- // Never be called again
284
- firstRequestHandler = null;
285
- let graphqlRouteForWs = graphqlRoute;
286
- const { pathname = '' } = parseUrl(req) || {};
287
- const { pathname: originalPathname = '' } = parseUrl.original(req) || {};
288
- if (originalPathname !== pathname && originalPathname.endsWith(pathname)) {
289
- const base = originalPathname.slice(0, originalPathname.length - pathname.length);
290
- // Our websocket GraphQL route must be at a different place
291
- graphqlRouteForWs = base + graphqlRouteForWs;
292
- if (externalUrlBase == null) {
293
- // User hasn't specified externalUrlBase; let's try and guess it
294
- // We were mounted on a subpath (e.g. `app.use('/path/to', postgraphile(...))`).
295
- // Figure out our externalUrlBase for ourselves.
296
- externalUrlBase = base;
297
- }
298
- }
299
- // Make sure we have a string, at least
300
- externalUrlBase = externalUrlBase || '';
301
- // Takes the original GraphiQL HTML file and replaces the default config object.
302
- graphiqlHtml = origGraphiqlHtml
303
- ? origGraphiqlHtml.replace(/<\/head>/, ` <script>window.POSTGRAPHILE_CONFIG=${safeJSONStringify({
304
- graphqlUrl: externalGraphqlRoute || `${externalUrlBase}${graphqlRoute}`,
305
- streamUrl: watchPg
306
- ? externalEventStreamRoute || `${externalUrlBase}${eventStreamRoute}`
307
- : null,
308
- enhanceGraphiql,
309
- // if 'v1' websockets are included, use the v1 client always
310
- websockets: !websockets.length ? 'none' : websockets.includes('v1') ? 'v1' : 'v0',
311
- allowExplain: typeof options.allowExplain === 'function'
312
- ? ALLOW_EXPLAIN_PLACEHOLDER
313
- : !!options.allowExplain,
314
- credentials: graphiqlCredentials,
315
- })};</script>\n </head>`)
316
- : null;
317
- if (websockets.length) {
318
- const server = req && req.connection && req.connection['server'];
319
- if (!server) {
320
- // tslint:disable-next-line no-console
321
- console.warn("Failed to find server to add websocket listener to, you'll need to call `enhanceHttpServerWithWebSockets` manually");
322
- }
323
- else {
324
- // Relying on this means that a normal request must come in before an
325
- // upgrade attempt. It's better to call it manually.
326
- subscriptions_1.enhanceHttpServerWithWebSockets(server, middleware, {
327
- graphqlRoute: graphqlRouteForWs,
328
- });
329
- }
330
- }
331
- };
332
- /*
333
- * If we're not in watch mode, then avoid the cost of `await`ing the schema
334
- * on every tick by having it available once it was generated.
335
- */
336
- let theOneAndOnlyGraphQLSchema = null;
337
- if (!watchPg) {
338
- getGqlSchema()
339
- .then(schema => {
340
- theOneAndOnlyGraphQLSchema = schema;
341
- })
342
- .catch(noop);
343
- }
344
- function neverReject(middlewareName, middleware) {
345
- return async (res) => {
346
- try {
347
- await middleware(res);
348
- }
349
- catch (e) {
350
- console.error(`An unexpected error occurred whilst processing '${middlewareName}'; this indicates a bug. The connection will be terminated.`);
351
- console.error(e);
352
- try {
353
- // At least terminate the connection
354
- res.statusCode = 500;
355
- res.end();
356
- }
357
- catch (e) {
358
- /*NOOP*/
359
- }
360
- }
361
- };
362
- }
363
- /**
364
- * The actual request handler. It’s an async function so it will return a
365
- * promise when complete. If the function doesn’t handle anything, it calls
366
- * `next` to let the next middleware try and handle it. If the function
367
- * throws an error, it's up to the wrapping middleware (imaginatively named
368
- * `middleware`, below) to handle the error. Frameworks like Koa have
369
- * middlewares reject a promise on error, whereas Express requires you pass
370
- * the error to the `next(err)` function.
371
- */
372
- const requestHandler = async (responseHandler, next) => {
373
- const res = responseHandler;
374
- const incomingReq = res.getNodeServerRequest();
375
- const nodeRes = res.getNodeServerResponse();
376
- // You can use this hook either to modify the incoming request or to tell
377
- // PostGraphile not to handle the request further (return null). NOTE: if
378
- // you return `null` from this hook then you are also responsible for
379
- // calling `next()` (should that be required).
380
- const req = pluginHook('postgraphile:http:handler', incomingReq, {
381
- options,
382
- res: nodeRes,
383
- next,
384
- });
385
- if (req == null) {
386
- return;
387
- }
388
- const { pathname = '' } = parseUrl(req) || {};
389
- // Certain things depend on externalUrlBase, which we guess if the user
390
- // doesn't supply it, so we calculate them on the first request. After
391
- // first request, this function becomes a NOOP
392
- if (firstRequestHandler)
393
- firstRequestHandler(req);
394
- // ======================================================================
395
- // GraphQL Watch Stream
396
- // ======================================================================
397
- if (watchPg) {
398
- // Setup an event stream so we can broadcast events to graphiql, etc.
399
- if (pathname === eventStreamRoute || pathname === '/_postgraphile/stream') {
400
- return eventStreamRouteHandler(res);
401
- }
402
- }
403
- const isGraphqlRoute = pathname === graphqlRoute;
404
- // ========================================================================
405
- // Serve GraphiQL and Related Assets
406
- // ========================================================================
407
- if (!shouldOmitAssets && graphiql && !isGraphqlRoute) {
408
- // ======================================================================
409
- // Favicon
410
- // ======================================================================
411
- // If this is the favicon path and it has not yet been handled, let us
412
- // serve our GraphQL favicon.
413
- if (pathname === '/favicon.ico') {
414
- return faviconRouteHandler(res);
415
- }
416
- // ======================================================================
417
- // GraphiQL HTML
418
- // ======================================================================
419
- // If this is the GraphiQL route, show GraphiQL and stop execution.
420
- if (pathname === graphiqlRoute) {
421
- // If we are developing PostGraphile, instead just redirect.
422
- if (isPostGraphileDevelopmentMode) {
423
- res.statusCode = 302;
424
- res.setHeader('Location', 'http://localhost:5783');
425
- res.end();
426
- return;
427
- }
428
- return graphiqlRouteHandler(res);
429
- }
430
- }
431
- if (isGraphqlRoute) {
432
- return graphqlRouteHandler(res);
433
- }
434
- else {
435
- // This request wasn't for us.
436
- return next();
437
- }
438
- };
439
- const eventStreamRouteHandler = neverReject('eventStreamRouteHandler', async function eventStreamRouteHandler(res) {
440
- try {
441
- // You can use this hook either to modify the incoming request or to tell
442
- // PostGraphile not to handle the request further (return null). NOTE: if
443
- // you return `null` from this hook then you are also responsible for
444
- // terminating the request however your framework handles that (e.g.
445
- // `res.send(...)` or `next()`).
446
- const req = pluginHook('postgraphile:http:eventStreamRouteHandler', res.getNodeServerRequest(), { options, response: res });
447
- if (req == null) {
448
- return;
449
- }
450
- // Add our CORS headers to be good web citizens (there are perf
451
- // implications though so be careful!)
452
- //
453
- // Always enable CORS when developing PostGraphile because GraphiQL will be
454
- // on port 5783.
455
- if (enableCors)
456
- addCORSHeaders(res);
457
- if (req.headers.accept !== 'text/event-stream') {
458
- res.statusCode = 405;
459
- res.end();
460
- return;
461
- }
462
- setupServerSentEvents_1.default(res, options);
463
- }
464
- catch (e) {
465
- console.error('Unexpected error occurred in eventStreamRouteHandler');
466
- console.error(e);
467
- res.statusCode = 500;
468
- res.end();
469
- }
470
- });
471
- const faviconRouteHandler = neverReject('faviconRouteHandler', async function faviconRouteHandler(res) {
472
- // You can use this hook either to modify the incoming request or to tell
473
- // PostGraphile not to handle the request further (return null). NOTE: if
474
- // you return `null` from this hook then you are also responsible for
475
- // terminating the request however your framework handles that (e.g.
476
- // `res.send(...)` or `next()`).
477
- const req = pluginHook('postgraphile:http:faviconRouteHandler', res.getNodeServerRequest(), {
478
- options,
479
- response: res,
480
- });
481
- if (req == null) {
482
- return;
483
- }
484
- // If this is the wrong method, we should let the client know.
485
- if (!(req.method === 'GET' || req.method === 'HEAD')) {
486
- res.statusCode = req.method === 'OPTIONS' ? 200 : 405;
487
- res.setHeader('Allow', 'GET, HEAD, OPTIONS');
488
- res.end();
489
- return;
490
- }
491
- // Otherwise we are good and should pipe the favicon to the browser.
492
- res.statusCode = 200;
493
- res.setHeader('Cache-Control', 'public, max-age=86400');
494
- res.setHeader('Content-Type', 'image/x-icon');
495
- // End early if the method is `HEAD`.
496
- if (req.method === 'HEAD') {
497
- res.end();
498
- return;
499
- }
500
- res.end(favicon_ico_1.default);
501
- });
502
- const graphiqlRouteHandler = neverReject('graphiqlRouteHandler', async function graphiqlRouteHandler(res) {
503
- // You can use this hook either to modify the incoming request or to tell
504
- // PostGraphile not to handle the request further (return null). NOTE: if
505
- // you return `null` from this hook then you are also responsible for
506
- // terminating the request however your framework handles that (e.g.
507
- // `res.send(...)` or `next()`).
508
- const req = pluginHook('postgraphile:http:graphiqlRouteHandler', res.getNodeServerRequest(), {
509
- options,
510
- response: res,
511
- });
512
- if (req == null) {
513
- return;
514
- }
515
- if (firstRequestHandler)
516
- firstRequestHandler(req);
517
- // If using the incorrect method, let the user know.
518
- if (!(req.method === 'GET' || req.method === 'HEAD')) {
519
- res.statusCode = req.method === 'OPTIONS' ? 200 : 405;
520
- res.setHeader('Allow', 'GET, HEAD, OPTIONS');
521
- res.end();
522
- return;
523
- }
524
- res.statusCode = 200;
525
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
526
- res.setHeader('X-Frame-Options', 'SAMEORIGIN');
527
- res.setHeader('Content-Security-Policy', "frame-ancestors 'self'");
528
- // End early if the method is `HEAD`.
529
- if (req.method === 'HEAD') {
530
- res.end();
531
- return;
532
- }
533
- // Actually renders GraphiQL.
534
- if (graphiqlHtml && typeof options.allowExplain === 'function') {
535
- res.end(graphiqlHtml.replace(`"${ALLOW_EXPLAIN_PLACEHOLDER}"`, // Because JSON escaped
536
- JSON.stringify(!!(await options.allowExplain(req)))));
537
- }
538
- else {
539
- res.end(graphiqlHtml);
540
- }
541
- });
542
- const graphqlRouteHandler = neverReject('graphqlRouteHandler', async function graphqlRouteHandler(res) {
543
- // You can use this hook either to modify the incoming request or to tell
544
- // PostGraphile not to handle the request further (return null). NOTE: if
545
- // you return `null` from this hook then you are also responsible for
546
- // terminating the request however your framework handles that (e.g.
547
- // `res.send(...)` or `next()`).
548
- const req = pluginHook('postgraphile:http:graphqlRouteHandler', res.getNodeServerRequest(), {
549
- options,
550
- response: res,
551
- });
552
- if (req == null) {
553
- return;
554
- }
555
- if (firstRequestHandler)
556
- firstRequestHandler(req);
557
- // Add our CORS headers to be good web citizens (there are perf
558
- // implications though so be careful!)
559
- //
560
- // Always enable CORS when developing PostGraphile because GraphiQL will be
561
- // on port 5783.
562
- if (enableCors)
563
- addCORSHeaders(res);
564
- // ========================================================================
565
- // Execute GraphQL Queries
566
- // ========================================================================
567
- // If we didn’t call `next` above, all requests will return 200 by default!
568
- res.statusCode = 200;
569
- if (watchPg) {
570
- // Inform GraphiQL and other clients that they can subscribe to events
571
- // (such as the schema being updated) at the following URL
572
- res.setHeader('X-GraphQL-Event-Stream', externalEventStreamRoute || `${externalUrlBase}${eventStreamRoute}`);
573
- }
574
- // Don’t execute our GraphQL stuffs for `OPTIONS` requests.
575
- if (req.method === 'OPTIONS') {
576
- res.statusCode = 200;
577
- res.end();
578
- return;
579
- }
580
- // The `result` will be used at the very end in our `finally` block.
581
- // Statements inside the `try` will assign to `result` when they get
582
- // a result. We also keep track of `params`.
583
- let paramsList;
584
- let results = [];
585
- const queryTimeStart = !disableQueryLog && process.hrtime();
586
- let pgRole;
587
- if (debugRequest.enabled)
588
- debugRequest('GraphQL query request has begun.');
589
- let returnArray = false;
590
- // This big `try`/`catch`/`finally` block represents the execution of our
591
- // GraphQL query. All errors thrown in this block will be returned to the
592
- // client as GraphQL errors.
593
- try {
594
- // First thing we need to do is get the GraphQL schema for this request.
595
- // It should never really change unless we are in watch mode.
596
- const gqlSchema = theOneAndOnlyGraphQLSchema || (await getGqlSchema());
597
- // Note that we run our middleware after we make sure we are on the
598
- // correct route. This is so that if our middleware modifies the `req` or
599
- // `res` objects, only we downstream will see the modifications.
600
- //
601
- // We also run our middleware inside the `try` so that we get the GraphQL
602
- // error reporting style for syntax errors.
603
- await parseBody(req, res);
604
- // If this is not one of the correct methods, throw an error.
605
- if (req.method !== 'POST') {
606
- res.setHeader('Allow', 'POST, OPTIONS');
607
- throw httpError(405, 'Only `POST` requests are allowed.');
608
- }
609
- // Get the parameters we will use to run a GraphQL request. `params` may
610
- // include:
611
- //
612
- // - `query`: The required GraphQL query string.
613
- // - `variables`: An optional JSON object containing GraphQL variables.
614
- // - `operationName`: The optional name of the GraphQL operation we will
615
- // be executing.
616
- const body = req.body;
617
- paramsList = typeof body === 'string' ? { query: body } : body;
618
- // Validate our paramsList object a bit.
619
- if (paramsList == null)
620
- throw httpError(400, 'Must provide an object parameters, not nullish value.');
621
- if (typeof paramsList !== 'object')
622
- throw httpError(400, `Expected parameter object, not value of type '${typeof paramsList}'.`);
623
- if (Array.isArray(paramsList)) {
624
- if (!enableQueryBatching) {
625
- throw httpError(501, 'Batching queries as an array is currently unsupported. Please provide a single query object.');
626
- }
627
- else {
628
- returnArray = true;
629
- }
630
- }
631
- else {
632
- paramsList = [paramsList];
633
- }
634
- paramsList = pluginHook('postgraphile:httpParamsList', paramsList, {
635
- options,
636
- req,
637
- res,
638
- returnArray,
639
- httpError,
640
- });
641
- results = await Promise.all(paramsList.map(async (params) => {
642
- let queryDocumentAst = null;
643
- let result;
644
- const meta = Object.create(null);
645
- try {
646
- if (!params)
647
- throw httpError(400, 'Invalid query structure.');
648
- const { query, operationName } = params;
649
- let { variables } = params;
650
- if (!query)
651
- throw httpError(400, 'Must provide a query string.');
652
- // If variables is a string, we assume it is a JSON string and that it
653
- // needs to be parsed.
654
- if (typeof variables === 'string') {
655
- // If variables is just an empty string, we should set it to null and
656
- // ignore it.
657
- if (variables === '') {
658
- variables = null;
659
- }
660
- else {
661
- // Otherwise, let us try to parse it as JSON.
662
- try {
663
- variables = JSON.parse(variables);
664
- }
665
- catch (error) {
666
- error.statusCode = 400;
667
- throw error;
668
- }
669
- }
670
- }
671
- // Throw an error if `variables` is not an object.
672
- if (variables != null && typeof variables !== 'object')
673
- throw httpError(400, `Variables must be an object, not '${typeof variables}'.`);
674
- // Throw an error if `operationName` is not a string.
675
- if (operationName != null && typeof operationName !== 'string')
676
- throw httpError(400, `Operation name must be a string, not '${typeof operationName}'.`);
677
- let validationErrors;
678
- ({ queryDocumentAst, validationErrors } = parseQuery(gqlSchema, query));
679
- if (validationErrors.length === 0) {
680
- // You are strongly encouraged to use
681
- // `postgraphile:validationRules:static` if possible - you should
682
- // only use this one if you need access to variables.
683
- const moreValidationRules = pluginHook('postgraphile:validationRules', [], {
684
- options,
685
- req,
686
- res,
687
- variables,
688
- operationName,
689
- meta,
690
- });
691
- if (moreValidationRules.length) {
692
- validationErrors = graphql_1.validate(gqlSchema, queryDocumentAst, moreValidationRules);
693
- }
694
- }
695
- // If we have some validation errors, don’t execute the query. Instead
696
- // send the errors to the client with a `400` code.
697
- if (validationErrors.length > 0) {
698
- result = { errors: validationErrors, statusCode: 400 };
699
- }
700
- else if (!queryDocumentAst) {
701
- throw new Error('Could not process query');
702
- }
703
- else {
704
- if (debugRequest.enabled)
705
- debugRequest('GraphQL query is validated.');
706
- // Lazily log the query. If this debugger isn’t enabled, don’t run it.
707
- if (debugGraphql.enabled)
708
- debugGraphql('%s', graphql_1.print(queryDocumentAst).replace(/\s+/g, ' ').trim());
709
- result = await withPostGraphileContextFromReqRes(req,
710
- // For backwards compatibilty we must pass the actual node request object.
711
- res.getNodeServerResponse(), {
712
- singleStatement: false,
713
- queryDocumentAst,
714
- variables,
715
- operationName,
716
- }, (graphqlContext) => {
717
- pgRole = graphqlContext.pgRole;
718
- const graphqlResult = graphql_1.execute(gqlSchema, queryDocumentAst, null, graphqlContext, variables, operationName);
719
- if (typeof graphqlContext.getExplainResults === 'function') {
720
- return Promise.resolve(graphqlResult).then(async (obj) => (Object.assign(Object.assign({}, obj), {
721
- // Add our explain data
722
- explain: await graphqlContext.getExplainResults() })));
723
- }
724
- else {
725
- return graphqlResult;
726
- }
727
- });
728
- }
729
- }
730
- catch (error) {
731
- result = {
732
- errors: [error],
733
- statusCode: error.status || error.statusCode || 500,
734
- };
735
- // If the status code is 500, let’s log our error.
736
- if (result.statusCode === 500)
737
- // tslint:disable-next-line no-console
738
- console.error(error.stack);
739
- }
740
- finally {
741
- // Format our errors so the client doesn’t get the full thing.
742
- if (result && result.errors) {
743
- result.errors = handleErrors(result.errors, req, res);
744
- }
745
- if (!isEmpty(meta)) {
746
- result.meta = meta;
747
- }
748
- result = pluginHook('postgraphile:http:result', result, {
749
- options,
750
- returnArray,
751
- queryDocumentAst,
752
- req,
753
- pgRole,
754
- });
755
- // Log the query. If this debugger isn’t enabled, don’t run it.
756
- if (!disableQueryLog && queryDocumentAst) {
757
- // To appease TypeScript
758
- const definitelyQueryDocumentAst = queryDocumentAst;
759
- // We must reference this before it's deleted!
760
- const resultStatusCode = result.statusCode;
761
- const timeDiff = queryTimeStart && process.hrtime(queryTimeStart);
762
- setImmediate(() => {
763
- const prettyQuery = graphql_1.print(definitelyQueryDocumentAst)
764
- .replace(/\s+/g, ' ')
765
- .trim();
766
- const errorCount = (result.errors || []).length;
767
- const ms = timeDiff[0] * 1e3 + timeDiff[1] * 1e-6;
768
- let message;
769
- if (resultStatusCode === 401) {
770
- // Users requested that JWT errors were raised differently:
771
- //
772
- // https://github.com/graphile/postgraphile/issues/560
773
- message = chalk_1.default.red(`401 authentication error`);
774
- }
775
- else if (resultStatusCode === 403) {
776
- message = chalk_1.default.red(`403 forbidden error`);
777
- }
778
- else {
779
- message = chalk_1.default[errorCount === 0 ? 'green' : 'red'](`${errorCount} error(s)`);
780
- }
781
- // tslint:disable-next-line no-console
782
- console.log(`${message} ${pgRole != null ? `as ${chalk_1.default.magenta(pgRole)} ` : ''}in ${chalk_1.default.grey(`${ms.toFixed(2)}ms`)} :: ${prettyQuery}`);
783
- });
784
- }
785
- if (debugRequest.enabled)
786
- debugRequest('GraphQL query has been executed.');
787
- }
788
- return result;
789
- }));
790
- }
791
- catch (error) {
792
- // Set our status code and send the client our results!
793
- if (res.statusCode === 200)
794
- res.statusCode = error.status || error.statusCode || 500;
795
- // Overwrite entire response
796
- returnArray = false;
797
- results = [{ errors: handleErrors([error], req, res) }];
798
- // If the status code is 500, let’s log our error.
799
- if (res.statusCode === 500) {
800
- // tslint:disable-next-line no-console
801
- console.error(error.stack);
802
- }
803
- }
804
- finally {
805
- // Finally, we send the client the results.
806
- if (!returnArray) {
807
- if (res.statusCode === 200 && results[0].statusCode) {
808
- res.statusCode = results[0].statusCode;
809
- }
810
- results[0].statusCode = undefined;
811
- }
812
- res.setHeader('Content-Type', 'application/json; charset=utf-8');
813
- const { statusCode, result } = pluginHook('postgraphile:http:end', {
814
- statusCode: res.statusCode,
815
- result: returnArray ? results : results[0],
816
- }, {
817
- options,
818
- returnArray,
819
- req,
820
- // For backwards compatibility, the underlying response object.
821
- res: res.getNodeServerResponse(),
822
- });
823
- if (statusCode) {
824
- res.statusCode = statusCode;
825
- }
826
- res.end(JSON.stringify(result));
827
- if (debugRequest.enabled) {
828
- debugRequest('GraphQL ' + (returnArray ? 'queries' : 'query') + ' request finished.');
829
- }
830
- }
831
- });
832
- /**
833
- * A polymorphic request handler that should detect what `http` framework is
834
- * being used and specifically handle that framework.
835
- *
836
- * Supported frameworks include:
837
- *
838
- * - Native Node.js `http`.
839
- * - `connect`.
840
- * - `express`.
841
- * - `koa` (2.0).
842
- */
843
- const middleware = (a, b, c) => {
844
- // If are arguments look like the arguments to koa middleware, this is
845
- // `koa` middleware.
846
- if (isKoaApp(a, b)) {
847
- // Set the correct `koa` variable names…
848
- const ctx = a;
849
- const next = b;
850
- const responseHandler = new frameworks_1.PostGraphileResponseKoa(ctx, next);
851
- // Execute our request handler. If an error is thrown, we don’t call
852
- // `next` with an error. Instead we return the promise and let `koa`
853
- // handle the error.
854
- return requestHandler(responseHandler, next);
855
- }
856
- else {
857
- // Set the correct `connect` style variable names. If there was no `next`
858
- // defined (likely the case if the client is using `http`) we use the
859
- // final handler.
860
- const req = a;
861
- const res = b;
862
- const next = c || finalHandler(req, res);
863
- const responseHandler = new frameworks_1.PostGraphileResponseNode(req, res, next);
864
- // Execute our request handler. If the request errored out, call `next` with the error.
865
- requestHandler(responseHandler, next).catch(next);
866
- // No return value.
867
- }
868
- };
869
- middleware.getGraphQLSchema = getGqlSchema;
870
- middleware.formatError = formatError;
871
- middleware.pgPool = pgPool;
872
- middleware.withPostGraphileContextFromReqRes = withPostGraphileContextFromReqRes;
873
- middleware.handleErrors = handleErrors;
874
- middleware.options = options;
875
- middleware.graphqlRoute = graphqlRoute;
876
- middleware.graphqlRouteHandler = graphqlRouteHandler;
877
- middleware.graphiqlRoute = graphiqlRoute;
878
- middleware.graphiqlRouteHandler = graphiql ? graphiqlRouteHandler : null;
879
- middleware.faviconRouteHandler = graphiql ? faviconRouteHandler : null;
880
- middleware.eventStreamRoute = eventStreamRoute;
881
- middleware.eventStreamRouteHandler = watchPg ? eventStreamRouteHandler : null;
882
- middleware.shutdownActions = shutdownActions;
883
- // Experimental
884
- middleware.release = () => shutdownActions.invokeAll();
885
- const hookedMiddleware = pluginHook('postgraphile:middleware', middleware, {
886
- options,
887
- // Experimental
888
- shutdownActions,
889
- });
890
- // Sanity check:
891
- if (!hookedMiddleware.getGraphQLSchema) {
892
- throw new Error("Hook for 'postgraphile:middleware' has not copied over the helpers; e.g. missing `Object.assign(newMiddleware, oldMiddleware)`");
893
- }
894
- return hookedMiddleware;
895
- }
896
- exports.default = createPostGraphileHttpRequestHandler;
897
- /**
898
- * Adds CORS to a request. See [this][1] flowchart for an explanation of how
899
- * CORS works. Note that these headers are set for all requests, CORS
900
- * algorithms normally run a preflight request using the `OPTIONS` method to
901
- * get these headers.
902
- *
903
- * Note though, that enabling CORS will incur extra costs when it comes to the
904
- * preflight requests. It is much better if you choose to use a proxy and
905
- * bypass CORS altogether.
906
- *
907
- * [1]: http://www.html5rocks.com/static/images/cors_server_flowchart.png
908
- */
909
- function addCORSHeaders(res) {
910
- res.setHeader('Access-Control-Allow-Origin', '*');
911
- res.setHeader('Access-Control-Allow-Methods', 'HEAD, GET, POST');
912
- res.setHeader('Access-Control-Allow-Headers', [
913
- 'Origin',
914
- 'X-Requested-With',
915
- // Used by `express-graphql` to determine whether to expose the GraphiQL
916
- // interface (`text/html`) or not.
917
- 'Accept',
918
- // Used by PostGraphile for auth purposes.
919
- 'Authorization',
920
- // Used by GraphQL Playground and other Apollo-enabled servers
921
- 'X-Apollo-Tracing',
922
- // The `Content-*` headers are used when making requests with a body,
923
- // like in a POST request.
924
- 'Content-Type',
925
- 'Content-Length',
926
- // For our 'Explain' feature
927
- 'X-PostGraphile-Explain',
928
- ].join(', '));
929
- res.setHeader('Access-Control-Expose-Headers', ['X-GraphQL-Event-Stream'].join(', '));
930
- }
931
- function createBadAuthorizationHeaderError() {
932
- return httpError(400, 'Authorization header is not of the correct bearer scheme format.');
933
- }
934
- /**
935
- * Parses the `Bearer` auth scheme token out of the `Authorization` header as
936
- * defined by [RFC7235][1].
937
- *
938
- * ```
939
- * Authorization = credentials
940
- * credentials = auth-scheme [ 1*SP ( token68 / #auth-param ) ]
941
- * token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" )*"="
942
- * ```
943
- *
944
- * [1]: https://tools.ietf.org/html/rfc7235
945
- *
946
- * @private
947
- */
948
- const authorizationBearerRex = /^\s*bearer\s+([a-z0-9\-._~+/]+=*)\s*$/i;
949
- /**
950
- * Gets the JWT token from the Http request’s headers. Specifically the
951
- * `Authorization` header in the `Bearer` format. Will throw an error if the
952
- * header is in the incorrect format, but will not throw an error if the header
953
- * does not exist.
954
- *
955
- * @private
956
- * @param {IncomingMessage} request
957
- * @returns {string | null}
958
- */
959
- function getJwtToken(request) {
960
- const { authorization } = request.headers;
961
- if (Array.isArray(authorization))
962
- throw createBadAuthorizationHeaderError();
963
- // If there was no authorization header, just return null.
964
- if (authorization == null)
965
- return null;
966
- const match = authorizationBearerRex.exec(authorization);
967
- // If we did not match the authorization header with our expected format,
968
- // throw a 400 error.
969
- if (!match)
970
- throw createBadAuthorizationHeaderError();
971
- // Return the token from our match.
972
- return match[1];
973
- }
974
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlUG9zdEdyYXBoaWxlSHR0cFJlcXVlc3RIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Bvc3RncmFwaGlsZS9odHRwL2NyZWF0ZVBvc3RHcmFwaGlsZUh0dHBSZXF1ZXN0SGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4RUFBOEU7QUFDOUUscUNBV2lCO0FBQ2pCLGdFQUE2RDtBQUU3RCw4Q0FBc0Q7QUFFdEQsbUVBQTREO0FBQzVELHdFQUFpRTtBQUNqRSx1Q0FBZ0M7QUFFaEMsaUNBQTBCO0FBQzFCLGtDQUFtQyxDQUFDLG9DQUFvQztBQUN4RSx5Q0FBMEM7QUFDMUMscUNBQXNDO0FBQ3RDLDZDQUE4QztBQUM5QywwQ0FBMkM7QUFDM0MsaUNBQWtDO0FBRWxDLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFVBQVUsQ0FBQztBQUUvRSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUVoQyxNQUFNLHlCQUF5QixHQUFHLDBCQUEwQixDQUFDO0FBQzdELE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRTtJQUNoQixVQUFVO0FBQ1osQ0FBQyxDQUFDO0FBRUYsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sQ0FBQztBQUU5Qjs7Ozs7R0FLRztBQUNILDBEQUErQztBQUUvQzs7O0dBR0c7QUFDSCw4REFBMEQ7QUFDMUQsbURBQWtFO0FBQ2xFLDZDQU1zQjtBQUV0Qjs7O0dBR0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLEdBQUcsRUFBRSxTQUFTO0lBQ2QsR0FBRyxFQUFFLFNBQVM7SUFDZCxHQUFHLEVBQUUsU0FBUztJQUNkLFFBQVEsRUFBRSxTQUFTO0lBQ25CLFFBQVEsRUFBRSxTQUFTO0NBQ3BCLENBQUM7QUFDRixT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