@makerx/graphql-core 2.2.2 → 2.3.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/User.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"User.js","sources":["../src/User.ts"],"sourcesContent":["import type { JwtPayload } from './context'\nimport { isNotNil } from './utils'\n\nexport class User {\n public readonly token: string\n public readonly claims: JwtPayload\n\n constructor(claims: JwtPayload, accessToken: string) {\n this.claims = claims\n this.token = accessToken\n }\n\n get email(): string | undefined {\n return (\n this.claims.email ??\n (this.claims.emails as string[] | undefined)?.[0] ??\n this.claims.preferred_username ??\n this.claims.unique_name ??\n this.claims.upn\n )\n }\n\n get name(): string | undefined {\n if (this.claims.name) return this.claims.name\n const otherNames = [this.claims.given_name, this.claims.family_name].filter(isNotNil)\n if (otherNames.length > 0) return otherNames.join(' ')\n return undefined\n }\n\n get id(): string {\n return this.firstOrThrow('oid', 'sub')\n }\n\n get scopes(): string[] {\n return this.claims.scp ? this.claims.scp.split(' ') : []\n }\n\n get roles(): string[] {\n return this.claims.roles ?? []\n }\n\n private first(...claims: Array<keyof JwtPayload>): string | undefined {\n for (const key of claims) {\n if (this.claims[key]) return this.claims[key] as string\n }\n return undefined\n }\n\n private firstOrThrow(...claims: Array<keyof JwtPayload>): string {\n const first = this.first(...claims)\n if (!first) throw new Error(`claims do not include any of: ${claims.join(', ')}`)\n return first\n }\n}\n"],"names":["isNotNil"],"mappings":";;;;MAGa,IAAI,CAAA;IAIf,WAAY,CAAA,MAAkB,EAAE,WAAmB,EAAA;AACjD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;AACpB,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW,CAAA;KACzB;AAED,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,QACE,IAAI,CAAC,MAAM,CAAC,KAAK;AAChB,YAAA,IAAI,CAAC,MAAM,CAAC,MAA+B,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,kBAAkB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,EAChB;KACF;AAED,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAA;QAC7C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAACA,cAAQ,CAAC,CAAA;AACrF,QAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACtD,QAAA,OAAO,SAAS,CAAA;KACjB;AAED,IAAA,IAAI,EAAE,GAAA;QACJ,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;KACvC;AAED,IAAA,IAAI,MAAM,GAAA;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;KACzD;AAED,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;KAC/B;IAEO,KAAK,CAAC,GAAG,MAA+B,EAAA;AAC9C,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACxB,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AAAE,gBAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAW,CAAA;SACxD;AACD,QAAA,OAAO,SAAS,CAAA;KACjB;IAEO,YAAY,CAAC,GAAG,MAA+B,EAAA;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAA;AACnC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,8BAAA,EAAiC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAE,CAAA,CAAC,CAAA;AACjF,QAAA,OAAO,KAAK,CAAA;KACb;AACF;;;;"}
1
+ {"version":3,"file":"User.js","sources":["../src/User.ts"],"sourcesContent":["import type { JwtPayload } from './context'\nimport { isNotNil } from './utils'\n\nexport class User {\n public readonly token: string\n public readonly claims: JwtPayload\n\n constructor(claims: JwtPayload, accessToken: string) {\n this.claims = claims\n this.token = accessToken\n }\n\n get email(): string | undefined {\n return (\n this.claims.email ??\n (this.claims.emails as string[] | undefined)?.[0] ??\n this.claims.preferred_username ??\n this.claims.unique_name ??\n this.claims.upn\n )\n }\n\n get name(): string | undefined {\n if (this.claims.name) return this.claims.name\n const otherNames = [this.claims.given_name, this.claims.family_name].filter(isNotNil)\n if (otherNames.length > 0) return otherNames.join(' ')\n return undefined\n }\n\n get id(): string {\n return this.firstOrThrow('oid', 'sub')\n }\n\n get scopes(): string[] {\n return this.claims.scp ? this.claims.scp.split(' ') : []\n }\n\n get roles(): string[] {\n return this.claims.roles ?? []\n }\n\n private first(...claims: Array<keyof JwtPayload>): string | undefined {\n for (const key of claims) {\n if (this.claims[key]) return this.claims[key] as string\n }\n return undefined\n }\n\n private firstOrThrow(...claims: Array<keyof JwtPayload>): string {\n const first = this.first(...claims)\n if (!first) throw new Error(`claims do not include any of: ${claims.join(', ')}`)\n return first\n }\n}\n"],"names":["isNotNil"],"mappings":";;;;MAGa,IAAI,CAAA;IAIf,WAAA,CAAY,MAAkB,EAAE,WAAmB,EAAA;AACjD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW;IAC1B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,QACE,IAAI,CAAC,MAAM,CAAC,KAAK;AAChB,YAAA,IAAI,CAAC,MAAM,CAAC,MAA+B,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,kBAAkB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG;IAEnB;AAEA,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI;QAC7C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAACA,cAAQ,CAAC;AACrF,QAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;AACtD,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,IAAI,EAAE,GAAA;QACJ,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IACxC;AAEA,IAAA,IAAI,MAAM,GAAA;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;IAC1D;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IAChC;IAEQ,KAAK,CAAC,GAAG,MAA+B,EAAA;AAC9C,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACxB,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AAAE,gBAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAW;QACzD;AACA,QAAA,OAAO,SAAS;IAClB;IAEQ,YAAY,CAAC,GAAG,MAA+B,EAAA;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;AACnC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,8BAAA,EAAiC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC;AACjF,QAAA,OAAO,KAAK;IACd;AACD;;;;"}
package/User.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"User.mjs","sources":["../src/User.ts"],"sourcesContent":["import type { JwtPayload } from './context'\nimport { isNotNil } from './utils'\n\nexport class User {\n public readonly token: string\n public readonly claims: JwtPayload\n\n constructor(claims: JwtPayload, accessToken: string) {\n this.claims = claims\n this.token = accessToken\n }\n\n get email(): string | undefined {\n return (\n this.claims.email ??\n (this.claims.emails as string[] | undefined)?.[0] ??\n this.claims.preferred_username ??\n this.claims.unique_name ??\n this.claims.upn\n )\n }\n\n get name(): string | undefined {\n if (this.claims.name) return this.claims.name\n const otherNames = [this.claims.given_name, this.claims.family_name].filter(isNotNil)\n if (otherNames.length > 0) return otherNames.join(' ')\n return undefined\n }\n\n get id(): string {\n return this.firstOrThrow('oid', 'sub')\n }\n\n get scopes(): string[] {\n return this.claims.scp ? this.claims.scp.split(' ') : []\n }\n\n get roles(): string[] {\n return this.claims.roles ?? []\n }\n\n private first(...claims: Array<keyof JwtPayload>): string | undefined {\n for (const key of claims) {\n if (this.claims[key]) return this.claims[key] as string\n }\n return undefined\n }\n\n private firstOrThrow(...claims: Array<keyof JwtPayload>): string {\n const first = this.first(...claims)\n if (!first) throw new Error(`claims do not include any of: ${claims.join(', ')}`)\n return first\n }\n}\n"],"names":[],"mappings":";;MAGa,IAAI,CAAA;IAIf,WAAY,CAAA,MAAkB,EAAE,WAAmB,EAAA;AACjD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;AACpB,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW,CAAA;KACzB;AAED,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,QACE,IAAI,CAAC,MAAM,CAAC,KAAK;AAChB,YAAA,IAAI,CAAC,MAAM,CAAC,MAA+B,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,kBAAkB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,EAChB;KACF;AAED,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAA;QAC7C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACrF,QAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACtD,QAAA,OAAO,SAAS,CAAA;KACjB;AAED,IAAA,IAAI,EAAE,GAAA;QACJ,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;KACvC;AAED,IAAA,IAAI,MAAM,GAAA;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;KACzD;AAED,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;KAC/B;IAEO,KAAK,CAAC,GAAG,MAA+B,EAAA;AAC9C,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACxB,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AAAE,gBAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAW,CAAA;SACxD;AACD,QAAA,OAAO,SAAS,CAAA;KACjB;IAEO,YAAY,CAAC,GAAG,MAA+B,EAAA;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAA;AACnC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,8BAAA,EAAiC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAE,CAAA,CAAC,CAAA;AACjF,QAAA,OAAO,KAAK,CAAA;KACb;AACF;;;;"}
1
+ {"version":3,"file":"User.mjs","sources":["../src/User.ts"],"sourcesContent":["import type { JwtPayload } from './context'\nimport { isNotNil } from './utils'\n\nexport class User {\n public readonly token: string\n public readonly claims: JwtPayload\n\n constructor(claims: JwtPayload, accessToken: string) {\n this.claims = claims\n this.token = accessToken\n }\n\n get email(): string | undefined {\n return (\n this.claims.email ??\n (this.claims.emails as string[] | undefined)?.[0] ??\n this.claims.preferred_username ??\n this.claims.unique_name ??\n this.claims.upn\n )\n }\n\n get name(): string | undefined {\n if (this.claims.name) return this.claims.name\n const otherNames = [this.claims.given_name, this.claims.family_name].filter(isNotNil)\n if (otherNames.length > 0) return otherNames.join(' ')\n return undefined\n }\n\n get id(): string {\n return this.firstOrThrow('oid', 'sub')\n }\n\n get scopes(): string[] {\n return this.claims.scp ? this.claims.scp.split(' ') : []\n }\n\n get roles(): string[] {\n return this.claims.roles ?? []\n }\n\n private first(...claims: Array<keyof JwtPayload>): string | undefined {\n for (const key of claims) {\n if (this.claims[key]) return this.claims[key] as string\n }\n return undefined\n }\n\n private firstOrThrow(...claims: Array<keyof JwtPayload>): string {\n const first = this.first(...claims)\n if (!first) throw new Error(`claims do not include any of: ${claims.join(', ')}`)\n return first\n }\n}\n"],"names":[],"mappings":";;MAGa,IAAI,CAAA;IAIf,WAAA,CAAY,MAAkB,EAAE,WAAmB,EAAA;AACjD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW;IAC1B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,QACE,IAAI,CAAC,MAAM,CAAC,KAAK;AAChB,YAAA,IAAI,CAAC,MAAM,CAAC,MAA+B,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,kBAAkB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG;IAEnB;AAEA,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI;QAC7C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AACrF,QAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;AACtD,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,IAAI,EAAE,GAAA;QACJ,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IACxC;AAEA,IAAA,IAAI,MAAM,GAAA;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;IAC1D;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IAChC;IAEQ,KAAK,CAAC,GAAG,MAA+B,EAAA;AAC9C,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACxB,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AAAE,gBAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAW;QACzD;AACA,QAAA,OAAO,SAAS;IAClB;IAEQ,YAAY,CAAC,GAAG,MAA+B,EAAA;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;AACnC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,8BAAA,EAAiC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC;AACjF,QAAA,OAAO,KAAK;IACd;AACD;;;;"}
package/context.d.ts CHANGED
@@ -19,6 +19,7 @@ export interface BaseRequestInfo extends Record<string, unknown> {
19
19
  correlationId?: string;
20
20
  arrLogId?: string;
21
21
  clientIp?: string;
22
+ userAgent?: string;
22
23
  }
23
24
  export interface LambdaContext {
24
25
  functionName?: string;
@@ -66,5 +67,6 @@ export interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQ
66
67
  requestInfoToLog?: Array<keyof RequestInfo>;
67
68
  augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
68
69
  }
69
- export declare const createContextFactory: <TContext extends AnyGraphqlContext = GraphQLContext<Logger, RequestInfo, User | undefined>>({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }: CreateContextConfig<TContext>) => CreateContext<TContext>;
70
+ export declare const buildBaseRequestInfo: (req: Request) => BaseRequestInfo;
71
+ export declare const createContextFactory: <TContext extends AnyGraphqlContext = GraphQLContext>({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }: CreateContextConfig<TContext>) => CreateContext<TContext>;
70
72
  export declare const defaultCreateUser: CreateUser<User | undefined>;
package/context.js CHANGED
@@ -4,23 +4,25 @@ var crypto = require('crypto');
4
4
  var lodash = require('lodash');
5
5
  var User = require('./User.js');
6
6
 
7
+ const buildBaseRequestInfo = (req) => ({
8
+ requestId: req.headers['x-request-id']?.toString() ?? crypto.randomUUID(),
9
+ protocol: req.protocol,
10
+ host: req.hostname ?? '',
11
+ method: req.method ?? '',
12
+ url: req.originalUrl,
13
+ origin: req.get('Origin') ?? '',
14
+ referer: req.headers.referer?.toString() ?? '',
15
+ arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,
16
+ clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,
17
+ correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,
18
+ userAgent: req.headers['user-agent']?.toString() ?? undefined,
19
+ });
7
20
  const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }) => {
8
21
  // the function that creates the GraphQL context
9
22
  return async (input) => {
10
23
  const { req, claims, context } = input;
11
24
  // build base request info from the request
12
- const baseRequestInfo = {
13
- requestId: req.headers['x-request-id']?.toString() ?? crypto.randomUUID(),
14
- protocol: req.protocol,
15
- host: req.hostname ?? '',
16
- method: req.method ?? '',
17
- url: req.originalUrl,
18
- origin: req.get('Origin') ?? '',
19
- referer: req.headers.referer?.toString() ?? '',
20
- arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,
21
- clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,
22
- correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,
23
- };
25
+ const baseRequestInfo = buildBaseRequestInfo(req);
24
26
  // add lambda info from the context, if present
25
27
  let lambdaRequestInfo;
26
28
  if (context) {
@@ -69,10 +71,11 @@ const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog,
69
71
  const defaultCreateUser = ({ req, claims }) => {
70
72
  if (!claims)
71
73
  return Promise.resolve(undefined);
72
- const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : '';
74
+ const accessToken = req.headers.authorization?.startsWith('Bearer') ? (req.headers.authorization?.substring(7) ?? '') : '';
73
75
  return Promise.resolve(new User.User(claims, accessToken));
74
76
  };
75
77
 
78
+ exports.buildBaseRequestInfo = buildBaseRequestInfo;
76
79
  exports.createContextFactory = createContextFactory;
77
80
  exports.defaultCreateUser = defaultCreateUser;
78
81
  //# sourceMappingURL=context.js.map
package/context.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sources":["../src/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { Request } from 'express'\nimport { pick } from 'lodash'\nimport { User } from './User'\n\nexport interface GraphQLContext<\n TLogger extends Logger = Logger,\n TRequestInfo extends BaseRequestInfo = RequestInfo,\n TUser = User | undefined,\n> {\n logger: TLogger\n requestInfo: TRequestInfo\n user: TUser\n started: number\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyGraphqlContext = GraphQLContext<any, any, any>\n\nexport interface BaseRequestInfo extends Record<string, unknown> {\n requestId: string\n protocol: 'http' | 'https' | 'ws'\n host: string\n method: string\n url: string\n origin: string\n referer?: string\n correlationId?: string\n arrLogId?: string\n clientIp?: string\n}\n\nexport interface LambdaContext {\n functionName?: string\n awsRequestId?: string\n}\nexport type LambdaEvent = never\nexport type LambdaRequestInfo = BaseRequestInfo & LambdaContext\nexport type RequestInfo = BaseRequestInfo | LambdaRequestInfo\n\n// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\nexport interface JwtPayload {\n [key: string]: unknown\n name?: string | undefined\n email?: string | undefined\n given_name?: string | undefined\n family_name?: string | undefined\n preferred_username?: string | undefined\n upn?: string | undefined\n unique_name?: string | undefined\n oid?: string | undefined\n iss?: string | undefined\n sub?: string | undefined\n aud?: string | string[] | undefined\n roles?: string[] | undefined\n scp?: string | undefined\n exp?: number | undefined\n nbf?: number | undefined\n iat?: number | undefined\n jti?: string | undefined\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type InferUserFromContext<TContext extends AnyGraphqlContext> =\n TContext extends GraphQLContext<any, any, infer TUser> ? TUser : never\nexport type CreateUser<T = User | undefined> = (input: Omit<ContextInput, 'createUser'>) => Promise<T> | T\nexport interface ContextInput {\n req: Request\n claims?: JwtPayload\n context?: LambdaContext\n event?: LambdaEvent\n}\nexport type CreateContext<TContext = GraphQLContext> = (input: ContextInput) => Promise<TContext>\nexport type CreateRequestLogger = (requestMetadata: Record<string, unknown>) => Logger\nexport type AugmentRequestInfo = (input: ContextInput) => Record<string, unknown>\n\nexport interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentRequestInfo\n claimsToLog?: string[]\n createUser: CreateUser<InferUserFromContext<TContext>>\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createContextFactory = <TContext extends AnyGraphqlContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser,\n requestInfoToLog,\n augmentContext,\n}: CreateContextConfig<TContext>): CreateContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: ContextInput) => {\n const { req, claims, context } = input\n\n // build base request info from the request\n const baseRequestInfo: BaseRequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: req.protocol as 'http' | 'https',\n host: req.hostname ?? '',\n method: req.method ?? '',\n url: req.originalUrl,\n origin: req.get('Origin') ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n }\n\n // add lambda info from the context, if present\n let lambdaRequestInfo: LambdaRequestInfo | undefined\n if (context) {\n const { awsRequestId, functionName } = context\n lambdaRequestInfo = {\n awsRequestId,\n functionName,\n ...baseRequestInfo,\n }\n }\n\n // augment request info with the supplied function, if present\n let requestInfo: RequestInfo = lambdaRequestInfo ?? baseRequestInfo\n if (augmentRequestInfo)\n requestInfo = {\n ...requestInfo,\n ...augmentRequestInfo(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: createUser ? await createUser(input) : undefined,\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nexport const defaultCreateUser: CreateUser<User | undefined> = ({ req, claims }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : ''\n return Promise.resolve(new User(claims, accessToken))\n}\n"],"names":["randomUUID","pick","User"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sources":["../src/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { Request } from 'express'\nimport { pick } from 'lodash'\nimport { User } from './User'\n\nexport interface GraphQLContext<\n TLogger extends Logger = Logger,\n TRequestInfo extends BaseRequestInfo = RequestInfo,\n TUser = User | undefined,\n> {\n logger: TLogger\n requestInfo: TRequestInfo\n user: TUser\n started: number\n}\n\nexport type AnyGraphqlContext = GraphQLContext<any, any, any>\n\nexport interface BaseRequestInfo extends Record<string, unknown> {\n requestId: string\n protocol: 'http' | 'https' | 'ws'\n host: string\n method: string\n url: string\n origin: string\n referer?: string\n correlationId?: string\n arrLogId?: string\n clientIp?: string\n userAgent?: string\n}\n\nexport interface LambdaContext {\n functionName?: string\n awsRequestId?: string\n}\nexport type LambdaEvent = never\nexport type LambdaRequestInfo = BaseRequestInfo & LambdaContext\nexport type RequestInfo = BaseRequestInfo | LambdaRequestInfo\n\n// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\nexport interface JwtPayload {\n [key: string]: unknown\n name?: string | undefined\n email?: string | undefined\n given_name?: string | undefined\n family_name?: string | undefined\n preferred_username?: string | undefined\n upn?: string | undefined\n unique_name?: string | undefined\n oid?: string | undefined\n iss?: string | undefined\n sub?: string | undefined\n aud?: string | string[] | undefined\n roles?: string[] | undefined\n scp?: string | undefined\n exp?: number | undefined\n nbf?: number | undefined\n iat?: number | undefined\n jti?: string | undefined\n}\n\nexport type InferUserFromContext<TContext extends AnyGraphqlContext> =\n TContext extends GraphQLContext<any, any, infer TUser> ? TUser : never\nexport type CreateUser<T = User | undefined> = (input: Omit<ContextInput, 'createUser'>) => Promise<T> | T\nexport interface ContextInput {\n req: Request\n claims?: JwtPayload\n context?: LambdaContext\n event?: LambdaEvent\n}\nexport type CreateContext<TContext = GraphQLContext> = (input: ContextInput) => Promise<TContext>\nexport type CreateRequestLogger = (requestMetadata: Record<string, unknown>) => Logger\nexport type AugmentRequestInfo = (input: ContextInput) => Record<string, unknown>\n\nexport interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentRequestInfo\n claimsToLog?: string[]\n createUser: CreateUser<InferUserFromContext<TContext>>\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const buildBaseRequestInfo = (req: Request): BaseRequestInfo => ({\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: req.protocol as 'http' | 'https',\n host: req.hostname ?? '',\n method: req.method ?? '',\n url: req.originalUrl,\n origin: req.get('Origin') ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n userAgent: req.headers['user-agent']?.toString() ?? undefined,\n})\n\nexport const createContextFactory = <TContext extends AnyGraphqlContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser,\n requestInfoToLog,\n augmentContext,\n}: CreateContextConfig<TContext>): CreateContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: ContextInput) => {\n const { req, claims, context } = input\n\n // build base request info from the request\n const baseRequestInfo: BaseRequestInfo = buildBaseRequestInfo(req)\n\n // add lambda info from the context, if present\n let lambdaRequestInfo: LambdaRequestInfo | undefined\n if (context) {\n const { awsRequestId, functionName } = context\n lambdaRequestInfo = {\n awsRequestId,\n functionName,\n ...baseRequestInfo,\n }\n }\n\n // augment request info with the supplied function, if present\n let requestInfo: RequestInfo = lambdaRequestInfo ?? baseRequestInfo\n if (augmentRequestInfo)\n requestInfo = {\n ...requestInfo,\n ...augmentRequestInfo(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: createUser ? await createUser(input) : undefined,\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nexport const defaultCreateUser: CreateUser<User | undefined> = ({ req, claims }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = req.headers.authorization?.startsWith('Bearer') ? (req.headers.authorization?.substring(7) ?? '') : ''\n return Promise.resolve(new User(claims, accessToken))\n}\n"],"names":["randomUUID","pick","User"],"mappings":"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"}
package/context.mjs CHANGED
@@ -2,23 +2,25 @@ import { randomUUID } from 'crypto';
2
2
  import { pick } from 'lodash';
3
3
  import { User } from './User.mjs';
4
4
 
5
+ const buildBaseRequestInfo = (req) => ({
6
+ requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),
7
+ protocol: req.protocol,
8
+ host: req.hostname ?? '',
9
+ method: req.method ?? '',
10
+ url: req.originalUrl,
11
+ origin: req.get('Origin') ?? '',
12
+ referer: req.headers.referer?.toString() ?? '',
13
+ arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,
14
+ clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,
15
+ correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,
16
+ userAgent: req.headers['user-agent']?.toString() ?? undefined,
17
+ });
5
18
  const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }) => {
6
19
  // the function that creates the GraphQL context
7
20
  return async (input) => {
8
21
  const { req, claims, context } = input;
9
22
  // build base request info from the request
10
- const baseRequestInfo = {
11
- requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),
12
- protocol: req.protocol,
13
- host: req.hostname ?? '',
14
- method: req.method ?? '',
15
- url: req.originalUrl,
16
- origin: req.get('Origin') ?? '',
17
- referer: req.headers.referer?.toString() ?? '',
18
- arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,
19
- clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,
20
- correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,
21
- };
23
+ const baseRequestInfo = buildBaseRequestInfo(req);
22
24
  // add lambda info from the context, if present
23
25
  let lambdaRequestInfo;
24
26
  if (context) {
@@ -67,9 +69,9 @@ const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog,
67
69
  const defaultCreateUser = ({ req, claims }) => {
68
70
  if (!claims)
69
71
  return Promise.resolve(undefined);
70
- const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : '';
72
+ const accessToken = req.headers.authorization?.startsWith('Bearer') ? (req.headers.authorization?.substring(7) ?? '') : '';
71
73
  return Promise.resolve(new User(claims, accessToken));
72
74
  };
73
75
 
74
- export { createContextFactory, defaultCreateUser };
76
+ export { buildBaseRequestInfo, createContextFactory, defaultCreateUser };
75
77
  //# sourceMappingURL=context.mjs.map
package/context.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"context.mjs","sources":["../src/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { Request } from 'express'\nimport { pick } from 'lodash'\nimport { User } from './User'\n\nexport interface GraphQLContext<\n TLogger extends Logger = Logger,\n TRequestInfo extends BaseRequestInfo = RequestInfo,\n TUser = User | undefined,\n> {\n logger: TLogger\n requestInfo: TRequestInfo\n user: TUser\n started: number\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyGraphqlContext = GraphQLContext<any, any, any>\n\nexport interface BaseRequestInfo extends Record<string, unknown> {\n requestId: string\n protocol: 'http' | 'https' | 'ws'\n host: string\n method: string\n url: string\n origin: string\n referer?: string\n correlationId?: string\n arrLogId?: string\n clientIp?: string\n}\n\nexport interface LambdaContext {\n functionName?: string\n awsRequestId?: string\n}\nexport type LambdaEvent = never\nexport type LambdaRequestInfo = BaseRequestInfo & LambdaContext\nexport type RequestInfo = BaseRequestInfo | LambdaRequestInfo\n\n// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\nexport interface JwtPayload {\n [key: string]: unknown\n name?: string | undefined\n email?: string | undefined\n given_name?: string | undefined\n family_name?: string | undefined\n preferred_username?: string | undefined\n upn?: string | undefined\n unique_name?: string | undefined\n oid?: string | undefined\n iss?: string | undefined\n sub?: string | undefined\n aud?: string | string[] | undefined\n roles?: string[] | undefined\n scp?: string | undefined\n exp?: number | undefined\n nbf?: number | undefined\n iat?: number | undefined\n jti?: string | undefined\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type InferUserFromContext<TContext extends AnyGraphqlContext> =\n TContext extends GraphQLContext<any, any, infer TUser> ? TUser : never\nexport type CreateUser<T = User | undefined> = (input: Omit<ContextInput, 'createUser'>) => Promise<T> | T\nexport interface ContextInput {\n req: Request\n claims?: JwtPayload\n context?: LambdaContext\n event?: LambdaEvent\n}\nexport type CreateContext<TContext = GraphQLContext> = (input: ContextInput) => Promise<TContext>\nexport type CreateRequestLogger = (requestMetadata: Record<string, unknown>) => Logger\nexport type AugmentRequestInfo = (input: ContextInput) => Record<string, unknown>\n\nexport interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentRequestInfo\n claimsToLog?: string[]\n createUser: CreateUser<InferUserFromContext<TContext>>\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createContextFactory = <TContext extends AnyGraphqlContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser,\n requestInfoToLog,\n augmentContext,\n}: CreateContextConfig<TContext>): CreateContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: ContextInput) => {\n const { req, claims, context } = input\n\n // build base request info from the request\n const baseRequestInfo: BaseRequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: req.protocol as 'http' | 'https',\n host: req.hostname ?? '',\n method: req.method ?? '',\n url: req.originalUrl,\n origin: req.get('Origin') ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n }\n\n // add lambda info from the context, if present\n let lambdaRequestInfo: LambdaRequestInfo | undefined\n if (context) {\n const { awsRequestId, functionName } = context\n lambdaRequestInfo = {\n awsRequestId,\n functionName,\n ...baseRequestInfo,\n }\n }\n\n // augment request info with the supplied function, if present\n let requestInfo: RequestInfo = lambdaRequestInfo ?? baseRequestInfo\n if (augmentRequestInfo)\n requestInfo = {\n ...requestInfo,\n ...augmentRequestInfo(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: createUser ? await createUser(input) : undefined,\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nexport const defaultCreateUser: CreateUser<User | undefined> = ({ req, claims }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : ''\n return Promise.resolve(new User(claims, accessToken))\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.mjs","sources":["../src/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { Request } from 'express'\nimport { pick } from 'lodash'\nimport { User } from './User'\n\nexport interface GraphQLContext<\n TLogger extends Logger = Logger,\n TRequestInfo extends BaseRequestInfo = RequestInfo,\n TUser = User | undefined,\n> {\n logger: TLogger\n requestInfo: TRequestInfo\n user: TUser\n started: number\n}\n\nexport type AnyGraphqlContext = GraphQLContext<any, any, any>\n\nexport interface BaseRequestInfo extends Record<string, unknown> {\n requestId: string\n protocol: 'http' | 'https' | 'ws'\n host: string\n method: string\n url: string\n origin: string\n referer?: string\n correlationId?: string\n arrLogId?: string\n clientIp?: string\n userAgent?: string\n}\n\nexport interface LambdaContext {\n functionName?: string\n awsRequestId?: string\n}\nexport type LambdaEvent = never\nexport type LambdaRequestInfo = BaseRequestInfo & LambdaContext\nexport type RequestInfo = BaseRequestInfo | LambdaRequestInfo\n\n// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\nexport interface JwtPayload {\n [key: string]: unknown\n name?: string | undefined\n email?: string | undefined\n given_name?: string | undefined\n family_name?: string | undefined\n preferred_username?: string | undefined\n upn?: string | undefined\n unique_name?: string | undefined\n oid?: string | undefined\n iss?: string | undefined\n sub?: string | undefined\n aud?: string | string[] | undefined\n roles?: string[] | undefined\n scp?: string | undefined\n exp?: number | undefined\n nbf?: number | undefined\n iat?: number | undefined\n jti?: string | undefined\n}\n\nexport type InferUserFromContext<TContext extends AnyGraphqlContext> =\n TContext extends GraphQLContext<any, any, infer TUser> ? TUser : never\nexport type CreateUser<T = User | undefined> = (input: Omit<ContextInput, 'createUser'>) => Promise<T> | T\nexport interface ContextInput {\n req: Request\n claims?: JwtPayload\n context?: LambdaContext\n event?: LambdaEvent\n}\nexport type CreateContext<TContext = GraphQLContext> = (input: ContextInput) => Promise<TContext>\nexport type CreateRequestLogger = (requestMetadata: Record<string, unknown>) => Logger\nexport type AugmentRequestInfo = (input: ContextInput) => Record<string, unknown>\n\nexport interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentRequestInfo\n claimsToLog?: string[]\n createUser: CreateUser<InferUserFromContext<TContext>>\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const buildBaseRequestInfo = (req: Request): BaseRequestInfo => ({\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: req.protocol as 'http' | 'https',\n host: req.hostname ?? '',\n method: req.method ?? '',\n url: req.originalUrl,\n origin: req.get('Origin') ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n userAgent: req.headers['user-agent']?.toString() ?? undefined,\n})\n\nexport const createContextFactory = <TContext extends AnyGraphqlContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser,\n requestInfoToLog,\n augmentContext,\n}: CreateContextConfig<TContext>): CreateContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: ContextInput) => {\n const { req, claims, context } = input\n\n // build base request info from the request\n const baseRequestInfo: BaseRequestInfo = buildBaseRequestInfo(req)\n\n // add lambda info from the context, if present\n let lambdaRequestInfo: LambdaRequestInfo | undefined\n if (context) {\n const { awsRequestId, functionName } = context\n lambdaRequestInfo = {\n awsRequestId,\n functionName,\n ...baseRequestInfo,\n }\n }\n\n // augment request info with the supplied function, if present\n let requestInfo: RequestInfo = lambdaRequestInfo ?? baseRequestInfo\n if (augmentRequestInfo)\n requestInfo = {\n ...requestInfo,\n ...augmentRequestInfo(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: createUser ? await createUser(input) : undefined,\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nexport const defaultCreateUser: CreateUser<User | undefined> = ({ req, claims }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = req.headers.authorization?.startsWith('Bearer') ? (req.headers.authorization?.substring(7) ?? '') : ''\n return Promise.resolve(new User(claims, accessToken))\n}\n"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -9,6 +9,7 @@ var shield = require('./shield.js');
9
9
 
10
10
 
11
11
 
12
+ exports.buildBaseRequestInfo = context.buildBaseRequestInfo;
12
13
  exports.createContextFactory = context.createContextFactory;
13
14
  exports.defaultCreateUser = context.defaultCreateUser;
14
15
  exports.User = User.User;
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
package/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { createContextFactory, defaultCreateUser } from './context.mjs';
1
+ export { buildBaseRequestInfo, createContextFactory, defaultCreateUser } from './context.mjs';
2
2
  export { User } from './User.mjs';
3
3
  export { isIntrospectionQuery, isNil, isNotNil } from './utils.mjs';
4
4
  export { logGraphQLOperation, logSubscriptionOperation } from './logging.mjs';
package/logging.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { Logger } from '@makerx/node-common';
2
2
  import type { ExecutionArgs, GraphQLFormattedError } from 'graphql';
3
3
  import { OperationTypeNode } from 'graphql';
4
4
  import type { ExecutionResult } from 'graphql-ws';
5
+ import type { GraphQLContext } from './context';
5
6
  type LogFunction = Logger['info'];
6
7
  export type LoggerLogFunctions<T extends Logger> = {
7
8
  [Property in keyof T]: LogFunction;
@@ -70,10 +71,11 @@ export interface GraphQLLogOperationInfo<TLogger extends Logger = Logger> extend
70
71
  * Top level and result entries with null or undefined values will be omitted.
71
72
  */
72
73
  export declare const logGraphQLOperation: <TLogger extends Logger = Logger>({ message, started, type, operationName, query, variables, result, logger, logLevel, ...rest }: GraphQLLogOperationInfo<TLogger>) => void;
73
- export declare const logSubscriptionOperation: <TLogger extends Logger = Logger>({ args, result, message, logLevel, }: {
74
+ export declare const logSubscriptionOperation: <TLogger extends Logger = Logger>({ args, result, message, logLevel, resolveLogger, }: {
74
75
  args: ExecutionArgs;
75
- result?: ExecutionResult<Record<string, unknown>, Record<string, unknown>> | undefined;
76
- message?: string | undefined;
77
- logLevel?: keyof TLogger | undefined;
76
+ result?: ExecutionResult;
77
+ message?: string;
78
+ logLevel?: keyof LoggerLogFunctions<TLogger>;
79
+ resolveLogger?: (context: GraphQLContext) => TLogger;
78
80
  }) => void;
79
81
  export {};
package/logging.js CHANGED
@@ -24,8 +24,10 @@ const logGraphQLOperation = ({ message = 'GraphQL operation', started, type, ope
24
24
  ...lodash.omitBy(rest, utils.isNil),
25
25
  }, utils.isNil));
26
26
  };
27
- const logSubscriptionOperation = ({ args, result, message, logLevel, }) => {
28
- const logger = args.contextValue.logger;
27
+ const logSubscriptionOperation = ({ args, result, message, logLevel, resolveLogger, }) => {
28
+ const logger = resolveLogger
29
+ ? resolveLogger(args.contextValue)
30
+ : args.contextValue.logger;
29
31
  if (!logger)
30
32
  return;
31
33
  const { operationName, variableValues, document } = args;
package/logging.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sources":["../src/logging.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { isLocalDev } from '@makerx/node-common'\nimport type { ExecutionArgs, GraphQLFormattedError } from 'graphql'\nimport { OperationTypeNode, print } from 'graphql'\nimport type { ExecutionResult } from 'graphql-ws'\nimport { omitBy } from 'lodash'\nimport type { GraphQLContext } from './context'\nimport { isIntrospectionQuery, isNil } from './utils'\n\ntype LogFunction = Logger['info']\nexport type LoggerLogFunctions<T extends Logger> = {\n [Property in keyof T]: LogFunction\n}\n\n/**\n * Info for logging a GraphQL operation in a consistent format with the option of including any additional data.\n */\nexport interface GraphQLLogOperationInfo<TLogger extends Logger = Logger> extends Record<string, unknown> {\n /**\n * The message to log, defaults to 'GraphQL operation'.\n */\n message?: string\n /**\n * The timestamp when the operation started, if supplied, the duration will be logged.\n */\n started?: number\n /**\n * The type of GraphQL operation.\n */\n type?: OperationTypeNode | null\n /**\n * The name of the GraphQL operation.\n */\n operationName?: string | null\n /**\n * The formatted GraphQL query.\n */\n query?: string | null\n /**\n * The GraphQL variables.\n */\n variables?: Record<string, unknown> | null\n /**\n * The result of the GraphQL operation.\n * Generally, we don't log the data or extensions, just errors.\n */\n result?: {\n data?: Record<string, unknown> | null\n errors?: readonly GraphQLFormattedError[] | null\n extensions?: Record<string, unknown> | null\n hasNext?: boolean\n }\n /**\n * Whether the operation is an introspection query.\n */\n isIntrospectionQuery?: boolean\n /**\n * Whether the operation is part of an incremental response.\n */\n isIncrementalResponse?: boolean\n /**\n * Whether the operation is a subsequent payload of an incremental response.\n */\n isSubsequentPayload?: boolean\n /**\n * The logger to use.\n */\n logger: TLogger\n /**\n * The logger function to use, defaults to 'info'.\n */\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}\n\n/**\n * Logs a GraphQL operation in a consistent format with the option of including any additional data.\n * Top level and result entries with null or undefined values will be omitted.\n */\nexport const logGraphQLOperation = <TLogger extends Logger = Logger>({\n message = 'GraphQL operation',\n started,\n type,\n operationName,\n query,\n variables,\n result,\n logger,\n logLevel = 'info',\n ...rest\n}: GraphQLLogOperationInfo<TLogger>) => {\n const isIntrospection = query && isIntrospectionQuery(query)\n if (isLocalDev && isIntrospection) return\n logger[logLevel as keyof Logger](\n message,\n omitBy(\n {\n type,\n operationName,\n query,\n variables: variables && Object.keys(variables).length > 0 ? variables : undefined,\n duration: started ? Date.now() - started : undefined,\n result: result ? omitBy(result, isNil) : undefined,\n isIntrospectionQuery: isIntrospection || undefined,\n ...omitBy(rest, isNil),\n },\n isNil,\n ),\n )\n}\n\nexport const logSubscriptionOperation = <TLogger extends Logger = Logger>({\n args,\n result,\n message,\n logLevel,\n}: {\n args: ExecutionArgs\n result?: ExecutionResult\n message?: string\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}) => {\n const logger = (args.contextValue as GraphQLContext).logger as TLogger\n if (!logger) return\n\n const { operationName, variableValues, document } = args\n const { data, ...resultWithoutData } = result ?? {}\n\n logGraphQLOperation({\n message,\n type: OperationTypeNode.SUBSCRIPTION,\n operationName,\n query: print(document),\n variables: variableValues,\n result: resultWithoutData,\n logger,\n logLevel,\n })\n}\n"],"names":["isIntrospectionQuery","isLocalDev","omitBy","isNil","OperationTypeNode","print"],"mappings":";;;;;;;AA0EA;;;AAGG;AACI,MAAM,mBAAmB,GAAG,CAAkC,EACnE,OAAO,GAAG,mBAAmB,EAC7B,OAAO,EACP,IAAI,EACJ,aAAa,EACb,KAAK,EACL,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,GAAG,MAAM,EACjB,GAAG,IAAI,EAC0B,KAAI;IACrC,MAAM,eAAe,GAAG,KAAK,IAAIA,0BAAoB,CAAC,KAAK,CAAC,CAAA;IAC5D,IAAIC,qBAAU,IAAI,eAAe;QAAE,OAAM;AACzC,IAAA,MAAM,CAAC,QAAwB,CAAC,CAC9B,OAAO,EACPC,aAAM,CACJ;QACE,IAAI;QACJ,aAAa;QACb,KAAK;QACL,SAAS,EAAE,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,SAAS;AACjF,QAAA,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS;AACpD,QAAA,MAAM,EAAE,MAAM,GAAGA,aAAM,CAAC,MAAM,EAAEC,WAAK,CAAC,GAAG,SAAS;QAClD,oBAAoB,EAAE,eAAe,IAAI,SAAS;AAClD,QAAA,GAAGD,aAAM,CAAC,IAAI,EAAEC,WAAK,CAAC;KACvB,EACDA,WAAK,CACN,CACF,CAAA;AACH,EAAC;AAEM,MAAM,wBAAwB,GAAG,CAAkC,EACxE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,QAAQ,GAMT,KAAI;AACH,IAAA,MAAM,MAAM,GAAI,IAAI,CAAC,YAA+B,CAAC,MAAiB,CAAA;AACtE,IAAA,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;AAEnD,IAAA,mBAAmB,CAAC;QAClB,OAAO;QACP,IAAI,EAAEC,yBAAiB,CAAC,YAAY;QACpC,aAAa;AACb,QAAA,KAAK,EAAEC,aAAK,CAAC,QAAQ,CAAC;AACtB,QAAA,SAAS,EAAE,cAAc;AACzB,QAAA,MAAM,EAAE,iBAAiB;QACzB,MAAM;QACN,QAAQ;AACT,KAAA,CAAC,CAAA;AACJ;;;;;"}
1
+ {"version":3,"file":"logging.js","sources":["../src/logging.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { isLocalDev } from '@makerx/node-common'\nimport type { ExecutionArgs, GraphQLFormattedError } from 'graphql'\nimport { OperationTypeNode, print } from 'graphql'\nimport type { ExecutionResult } from 'graphql-ws'\nimport { omitBy } from 'lodash'\nimport type { GraphQLContext } from './context'\nimport { isIntrospectionQuery, isNil } from './utils'\n\ntype LogFunction = Logger['info']\nexport type LoggerLogFunctions<T extends Logger> = {\n [Property in keyof T]: LogFunction\n}\n\n/**\n * Info for logging a GraphQL operation in a consistent format with the option of including any additional data.\n */\nexport interface GraphQLLogOperationInfo<TLogger extends Logger = Logger> extends Record<string, unknown> {\n /**\n * The message to log, defaults to 'GraphQL operation'.\n */\n message?: string\n /**\n * The timestamp when the operation started, if supplied, the duration will be logged.\n */\n started?: number\n /**\n * The type of GraphQL operation.\n */\n type?: OperationTypeNode | null\n /**\n * The name of the GraphQL operation.\n */\n operationName?: string | null\n /**\n * The formatted GraphQL query.\n */\n query?: string | null\n /**\n * The GraphQL variables.\n */\n variables?: Record<string, unknown> | null\n /**\n * The result of the GraphQL operation.\n * Generally, we don't log the data or extensions, just errors.\n */\n result?: {\n data?: Record<string, unknown> | null\n errors?: readonly GraphQLFormattedError[] | null\n extensions?: Record<string, unknown> | null\n hasNext?: boolean\n }\n /**\n * Whether the operation is an introspection query.\n */\n isIntrospectionQuery?: boolean\n /**\n * Whether the operation is part of an incremental response.\n */\n isIncrementalResponse?: boolean\n /**\n * Whether the operation is a subsequent payload of an incremental response.\n */\n isSubsequentPayload?: boolean\n /**\n * The logger to use.\n */\n logger: TLogger\n /**\n * The logger function to use, defaults to 'info'.\n */\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}\n\n/**\n * Logs a GraphQL operation in a consistent format with the option of including any additional data.\n * Top level and result entries with null or undefined values will be omitted.\n */\nexport const logGraphQLOperation = <TLogger extends Logger = Logger>({\n message = 'GraphQL operation',\n started,\n type,\n operationName,\n query,\n variables,\n result,\n logger,\n logLevel = 'info',\n ...rest\n}: GraphQLLogOperationInfo<TLogger>) => {\n const isIntrospection = query && isIntrospectionQuery(query)\n if (isLocalDev && isIntrospection) return\n logger[logLevel as keyof Logger](\n message,\n omitBy(\n {\n type,\n operationName,\n query,\n variables: variables && Object.keys(variables).length > 0 ? variables : undefined,\n duration: started ? Date.now() - started : undefined,\n result: result ? omitBy(result, isNil) : undefined,\n isIntrospectionQuery: isIntrospection || undefined,\n ...omitBy(rest, isNil),\n },\n isNil,\n ),\n )\n}\n\nexport const logSubscriptionOperation = <TLogger extends Logger = Logger>({\n args,\n result,\n message,\n logLevel,\n resolveLogger,\n}: {\n args: ExecutionArgs\n result?: ExecutionResult\n message?: string\n logLevel?: keyof LoggerLogFunctions<TLogger>\n resolveLogger?: (context: GraphQLContext) => TLogger\n}) => {\n const logger = resolveLogger\n ? resolveLogger(args.contextValue as GraphQLContext)\n : ((args.contextValue as GraphQLContext).logger as TLogger)\n if (!logger) return\n\n const { operationName, variableValues, document } = args\n const { data, ...resultWithoutData } = result ?? {}\n\n logGraphQLOperation({\n message,\n type: OperationTypeNode.SUBSCRIPTION,\n operationName,\n query: print(document),\n variables: variableValues,\n result: resultWithoutData,\n logger,\n logLevel,\n })\n}\n"],"names":["isIntrospectionQuery","isLocalDev","omitBy","isNil","OperationTypeNode","print"],"mappings":";;;;;;;AA0EA;;;AAGG;AACI,MAAM,mBAAmB,GAAG,CAAkC,EACnE,OAAO,GAAG,mBAAmB,EAC7B,OAAO,EACP,IAAI,EACJ,aAAa,EACb,KAAK,EACL,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,GAAG,MAAM,EACjB,GAAG,IAAI,EAC0B,KAAI;IACrC,MAAM,eAAe,GAAG,KAAK,IAAIA,0BAAoB,CAAC,KAAK,CAAC;IAC5D,IAAIC,qBAAU,IAAI,eAAe;QAAE;AACnC,IAAA,MAAM,CAAC,QAAwB,CAAC,CAC9B,OAAO,EACPC,aAAM,CACJ;QACE,IAAI;QACJ,aAAa;QACb,KAAK;QACL,SAAS,EAAE,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,SAAS;AACjF,QAAA,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS;AACpD,QAAA,MAAM,EAAE,MAAM,GAAGA,aAAM,CAAC,MAAM,EAAEC,WAAK,CAAC,GAAG,SAAS;QAClD,oBAAoB,EAAE,eAAe,IAAI,SAAS;AAClD,QAAA,GAAGD,aAAM,CAAC,IAAI,EAAEC,WAAK,CAAC;KACvB,EACDA,WAAK,CACN,CACF;AACH;AAEO,MAAM,wBAAwB,GAAG,CAAkC,EACxE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,QAAQ,EACR,aAAa,GAOd,KAAI;IACH,MAAM,MAAM,GAAG;AACb,UAAE,aAAa,CAAC,IAAI,CAAC,YAA8B;AACnD,UAAI,IAAI,CAAC,YAA+B,CAAC,MAAkB;AAC7D,IAAA,IAAI,CAAC,MAAM;QAAE;IAEb,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,IAAI;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,IAAI,EAAE;AAEnD,IAAA,mBAAmB,CAAC;QAClB,OAAO;QACP,IAAI,EAAEC,yBAAiB,CAAC,YAAY;QACpC,aAAa;AACb,QAAA,KAAK,EAAEC,aAAK,CAAC,QAAQ,CAAC;AACtB,QAAA,SAAS,EAAE,cAAc;AACzB,QAAA,MAAM,EAAE,iBAAiB;QACzB,MAAM;QACN,QAAQ;AACT,KAAA,CAAC;AACJ;;;;;"}
package/logging.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isLocalDev } from '@makerx/node-common';
2
- import { OperationTypeNode, print } from 'graphql';
2
+ import { print, OperationTypeNode } from 'graphql';
3
3
  import { omitBy } from 'lodash';
4
4
  import { isIntrospectionQuery, isNil } from './utils.mjs';
5
5
 
@@ -22,8 +22,10 @@ const logGraphQLOperation = ({ message = 'GraphQL operation', started, type, ope
22
22
  ...omitBy(rest, isNil),
23
23
  }, isNil));
24
24
  };
25
- const logSubscriptionOperation = ({ args, result, message, logLevel, }) => {
26
- const logger = args.contextValue.logger;
25
+ const logSubscriptionOperation = ({ args, result, message, logLevel, resolveLogger, }) => {
26
+ const logger = resolveLogger
27
+ ? resolveLogger(args.contextValue)
28
+ : args.contextValue.logger;
27
29
  if (!logger)
28
30
  return;
29
31
  const { operationName, variableValues, document } = args;
package/logging.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logging.mjs","sources":["../src/logging.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { isLocalDev } from '@makerx/node-common'\nimport type { ExecutionArgs, GraphQLFormattedError } from 'graphql'\nimport { OperationTypeNode, print } from 'graphql'\nimport type { ExecutionResult } from 'graphql-ws'\nimport { omitBy } from 'lodash'\nimport type { GraphQLContext } from './context'\nimport { isIntrospectionQuery, isNil } from './utils'\n\ntype LogFunction = Logger['info']\nexport type LoggerLogFunctions<T extends Logger> = {\n [Property in keyof T]: LogFunction\n}\n\n/**\n * Info for logging a GraphQL operation in a consistent format with the option of including any additional data.\n */\nexport interface GraphQLLogOperationInfo<TLogger extends Logger = Logger> extends Record<string, unknown> {\n /**\n * The message to log, defaults to 'GraphQL operation'.\n */\n message?: string\n /**\n * The timestamp when the operation started, if supplied, the duration will be logged.\n */\n started?: number\n /**\n * The type of GraphQL operation.\n */\n type?: OperationTypeNode | null\n /**\n * The name of the GraphQL operation.\n */\n operationName?: string | null\n /**\n * The formatted GraphQL query.\n */\n query?: string | null\n /**\n * The GraphQL variables.\n */\n variables?: Record<string, unknown> | null\n /**\n * The result of the GraphQL operation.\n * Generally, we don't log the data or extensions, just errors.\n */\n result?: {\n data?: Record<string, unknown> | null\n errors?: readonly GraphQLFormattedError[] | null\n extensions?: Record<string, unknown> | null\n hasNext?: boolean\n }\n /**\n * Whether the operation is an introspection query.\n */\n isIntrospectionQuery?: boolean\n /**\n * Whether the operation is part of an incremental response.\n */\n isIncrementalResponse?: boolean\n /**\n * Whether the operation is a subsequent payload of an incremental response.\n */\n isSubsequentPayload?: boolean\n /**\n * The logger to use.\n */\n logger: TLogger\n /**\n * The logger function to use, defaults to 'info'.\n */\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}\n\n/**\n * Logs a GraphQL operation in a consistent format with the option of including any additional data.\n * Top level and result entries with null or undefined values will be omitted.\n */\nexport const logGraphQLOperation = <TLogger extends Logger = Logger>({\n message = 'GraphQL operation',\n started,\n type,\n operationName,\n query,\n variables,\n result,\n logger,\n logLevel = 'info',\n ...rest\n}: GraphQLLogOperationInfo<TLogger>) => {\n const isIntrospection = query && isIntrospectionQuery(query)\n if (isLocalDev && isIntrospection) return\n logger[logLevel as keyof Logger](\n message,\n omitBy(\n {\n type,\n operationName,\n query,\n variables: variables && Object.keys(variables).length > 0 ? variables : undefined,\n duration: started ? Date.now() - started : undefined,\n result: result ? omitBy(result, isNil) : undefined,\n isIntrospectionQuery: isIntrospection || undefined,\n ...omitBy(rest, isNil),\n },\n isNil,\n ),\n )\n}\n\nexport const logSubscriptionOperation = <TLogger extends Logger = Logger>({\n args,\n result,\n message,\n logLevel,\n}: {\n args: ExecutionArgs\n result?: ExecutionResult\n message?: string\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}) => {\n const logger = (args.contextValue as GraphQLContext).logger as TLogger\n if (!logger) return\n\n const { operationName, variableValues, document } = args\n const { data, ...resultWithoutData } = result ?? {}\n\n logGraphQLOperation({\n message,\n type: OperationTypeNode.SUBSCRIPTION,\n operationName,\n query: print(document),\n variables: variableValues,\n result: resultWithoutData,\n logger,\n logLevel,\n })\n}\n"],"names":[],"mappings":";;;;;AA0EA;;;AAGG;AACI,MAAM,mBAAmB,GAAG,CAAkC,EACnE,OAAO,GAAG,mBAAmB,EAC7B,OAAO,EACP,IAAI,EACJ,aAAa,EACb,KAAK,EACL,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,GAAG,MAAM,EACjB,GAAG,IAAI,EAC0B,KAAI;IACrC,MAAM,eAAe,GAAG,KAAK,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC5D,IAAI,UAAU,IAAI,eAAe;QAAE,OAAM;AACzC,IAAA,MAAM,CAAC,QAAwB,CAAC,CAC9B,OAAO,EACP,MAAM,CACJ;QACE,IAAI;QACJ,aAAa;QACb,KAAK;QACL,SAAS,EAAE,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,SAAS;AACjF,QAAA,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS;AACpD,QAAA,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,SAAS;QAClD,oBAAoB,EAAE,eAAe,IAAI,SAAS;AAClD,QAAA,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;KACvB,EACD,KAAK,CACN,CACF,CAAA;AACH,EAAC;AAEM,MAAM,wBAAwB,GAAG,CAAkC,EACxE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,QAAQ,GAMT,KAAI;AACH,IAAA,MAAM,MAAM,GAAI,IAAI,CAAC,YAA+B,CAAC,MAAiB,CAAA;AACtE,IAAA,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;AAEnD,IAAA,mBAAmB,CAAC;QAClB,OAAO;QACP,IAAI,EAAE,iBAAiB,CAAC,YAAY;QACpC,aAAa;AACb,QAAA,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC;AACtB,QAAA,SAAS,EAAE,cAAc;AACzB,QAAA,MAAM,EAAE,iBAAiB;QACzB,MAAM;QACN,QAAQ;AACT,KAAA,CAAC,CAAA;AACJ;;;;"}
1
+ {"version":3,"file":"logging.mjs","sources":["../src/logging.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { isLocalDev } from '@makerx/node-common'\nimport type { ExecutionArgs, GraphQLFormattedError } from 'graphql'\nimport { OperationTypeNode, print } from 'graphql'\nimport type { ExecutionResult } from 'graphql-ws'\nimport { omitBy } from 'lodash'\nimport type { GraphQLContext } from './context'\nimport { isIntrospectionQuery, isNil } from './utils'\n\ntype LogFunction = Logger['info']\nexport type LoggerLogFunctions<T extends Logger> = {\n [Property in keyof T]: LogFunction\n}\n\n/**\n * Info for logging a GraphQL operation in a consistent format with the option of including any additional data.\n */\nexport interface GraphQLLogOperationInfo<TLogger extends Logger = Logger> extends Record<string, unknown> {\n /**\n * The message to log, defaults to 'GraphQL operation'.\n */\n message?: string\n /**\n * The timestamp when the operation started, if supplied, the duration will be logged.\n */\n started?: number\n /**\n * The type of GraphQL operation.\n */\n type?: OperationTypeNode | null\n /**\n * The name of the GraphQL operation.\n */\n operationName?: string | null\n /**\n * The formatted GraphQL query.\n */\n query?: string | null\n /**\n * The GraphQL variables.\n */\n variables?: Record<string, unknown> | null\n /**\n * The result of the GraphQL operation.\n * Generally, we don't log the data or extensions, just errors.\n */\n result?: {\n data?: Record<string, unknown> | null\n errors?: readonly GraphQLFormattedError[] | null\n extensions?: Record<string, unknown> | null\n hasNext?: boolean\n }\n /**\n * Whether the operation is an introspection query.\n */\n isIntrospectionQuery?: boolean\n /**\n * Whether the operation is part of an incremental response.\n */\n isIncrementalResponse?: boolean\n /**\n * Whether the operation is a subsequent payload of an incremental response.\n */\n isSubsequentPayload?: boolean\n /**\n * The logger to use.\n */\n logger: TLogger\n /**\n * The logger function to use, defaults to 'info'.\n */\n logLevel?: keyof LoggerLogFunctions<TLogger>\n}\n\n/**\n * Logs a GraphQL operation in a consistent format with the option of including any additional data.\n * Top level and result entries with null or undefined values will be omitted.\n */\nexport const logGraphQLOperation = <TLogger extends Logger = Logger>({\n message = 'GraphQL operation',\n started,\n type,\n operationName,\n query,\n variables,\n result,\n logger,\n logLevel = 'info',\n ...rest\n}: GraphQLLogOperationInfo<TLogger>) => {\n const isIntrospection = query && isIntrospectionQuery(query)\n if (isLocalDev && isIntrospection) return\n logger[logLevel as keyof Logger](\n message,\n omitBy(\n {\n type,\n operationName,\n query,\n variables: variables && Object.keys(variables).length > 0 ? variables : undefined,\n duration: started ? Date.now() - started : undefined,\n result: result ? omitBy(result, isNil) : undefined,\n isIntrospectionQuery: isIntrospection || undefined,\n ...omitBy(rest, isNil),\n },\n isNil,\n ),\n )\n}\n\nexport const logSubscriptionOperation = <TLogger extends Logger = Logger>({\n args,\n result,\n message,\n logLevel,\n resolveLogger,\n}: {\n args: ExecutionArgs\n result?: ExecutionResult\n message?: string\n logLevel?: keyof LoggerLogFunctions<TLogger>\n resolveLogger?: (context: GraphQLContext) => TLogger\n}) => {\n const logger = resolveLogger\n ? resolveLogger(args.contextValue as GraphQLContext)\n : ((args.contextValue as GraphQLContext).logger as TLogger)\n if (!logger) return\n\n const { operationName, variableValues, document } = args\n const { data, ...resultWithoutData } = result ?? {}\n\n logGraphQLOperation({\n message,\n type: OperationTypeNode.SUBSCRIPTION,\n operationName,\n query: print(document),\n variables: variableValues,\n result: resultWithoutData,\n logger,\n logLevel,\n })\n}\n"],"names":[],"mappings":";;;;;AA0EA;;;AAGG;AACI,MAAM,mBAAmB,GAAG,CAAkC,EACnE,OAAO,GAAG,mBAAmB,EAC7B,OAAO,EACP,IAAI,EACJ,aAAa,EACb,KAAK,EACL,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,GAAG,MAAM,EACjB,GAAG,IAAI,EAC0B,KAAI;IACrC,MAAM,eAAe,GAAG,KAAK,IAAI,oBAAoB,CAAC,KAAK,CAAC;IAC5D,IAAI,UAAU,IAAI,eAAe;QAAE;AACnC,IAAA,MAAM,CAAC,QAAwB,CAAC,CAC9B,OAAO,EACP,MAAM,CACJ;QACE,IAAI;QACJ,aAAa;QACb,KAAK;QACL,SAAS,EAAE,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,SAAS;AACjF,QAAA,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS;AACpD,QAAA,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,SAAS;QAClD,oBAAoB,EAAE,eAAe,IAAI,SAAS;AAClD,QAAA,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;KACvB,EACD,KAAK,CACN,CACF;AACH;AAEO,MAAM,wBAAwB,GAAG,CAAkC,EACxE,IAAI,EACJ,MAAM,EACN,OAAO,EACP,QAAQ,EACR,aAAa,GAOd,KAAI;IACH,MAAM,MAAM,GAAG;AACb,UAAE,aAAa,CAAC,IAAI,CAAC,YAA8B;AACnD,UAAI,IAAI,CAAC,YAA+B,CAAC,MAAkB;AAC7D,IAAA,IAAI,CAAC,MAAM;QAAE;IAEb,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,IAAI;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,IAAI,EAAE;AAEnD,IAAA,mBAAmB,CAAC;QAClB,OAAO;QACP,IAAI,EAAE,iBAAiB,CAAC,YAAY;QACpC,aAAa;AACb,QAAA,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC;AACtB,QAAA,SAAS,EAAE,cAAc;AACzB,QAAA,MAAM,EAAE,iBAAiB;QACzB,MAAM;QACN,QAAQ;AACT,KAAA,CAAC;AACJ;;;;"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "**"
5
5
  ],
6
6
  "name": "@makerx/graphql-core",
7
- "version": "2.2.2",
7
+ "version": "2.3.0",
8
8
  "private": false,
9
9
  "description": "A set of core GraphQL utilities that MakerX uses to build GraphQL APIs",
10
10
  "author": "MakerX",
@@ -21,7 +21,7 @@
21
21
  "url": "git+https://github.com/MakerXStudio/graphql-core.git"
22
22
  },
23
23
  "dependencies": {
24
- "@makerx/node-common": "^1.4.0"
24
+ "@makerx/node-common": "^1.5.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@apollo/client": "*",
@@ -1 +1 @@
1
- {"version":3,"file":"schema-util.js","sources":["../src/schema-util.ts"],"sourcesContent":["import type { GraphQLSchema } from 'graphql'\nimport { GraphQLScalarType } from 'graphql'\n\n/**\n * It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in\n * this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types\n * provide at least a base level of validation by failing to parse a Symbol instance. The default resolver does not pass this test\n * meaning any scalars that are falling back to the default resolver will fail.\n * @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`\n */\nexport function requireExplicitResolversForScalars(schema: GraphQLSchema, ...scalarsToIgnore: string[]) {\n const testSymbol = Symbol('testSymbol')\n const scalars = Object.values(schema.getTypeMap()).filter((t): t is GraphQLScalarType => t instanceof GraphQLScalarType)\n for (const scalar of scalars) {\n if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name)) continue\n try {\n scalar.parseValue(testSymbol)\n } catch {\n // We expect that a good parser should throw when parsing a random symbol\n continue\n }\n throw new Error(\n `Scalar ${scalar.name} does not appear to have an explicit resolver, or is not performing sufficient validation when parsing input. ` +\n \"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.\",\n )\n }\n}\n"],"names":["GraphQLScalarType"],"mappings":";;;;AAGA;;;;;;AAMG;SACa,kCAAkC,CAAC,MAAqB,EAAE,GAAG,eAAyB,EAAA;AACpG,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAA6B,CAAC,YAAYA,yBAAiB,CAAC,CAAA;AACxH,IAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC5B,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,SAAQ;AACvG,QAAA,IAAI;AACF,YAAA,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;SAC9B;AAAC,QAAA,MAAM;;YAEN,SAAQ;SACT;AACD,QAAA,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,CAAgH,8GAAA,CAAA;AACnI,YAAA,6GAA6G,CAChH,CAAA;KACF;AACH;;;;"}
1
+ {"version":3,"file":"schema-util.js","sources":["../src/schema-util.ts"],"sourcesContent":["import type { GraphQLSchema } from 'graphql'\nimport { GraphQLScalarType } from 'graphql'\n\n/**\n * It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in\n * this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types\n * provide at least a base level of validation by failing to parse a Symbol instance. The default resolver does not pass this test\n * meaning any scalars that are falling back to the default resolver will fail.\n * @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`\n */\nexport function requireExplicitResolversForScalars(schema: GraphQLSchema, ...scalarsToIgnore: string[]) {\n const testSymbol = Symbol('testSymbol')\n const scalars = Object.values(schema.getTypeMap()).filter((t): t is GraphQLScalarType => t instanceof GraphQLScalarType)\n for (const scalar of scalars) {\n if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name)) continue\n try {\n scalar.parseValue(testSymbol)\n } catch {\n // We expect that a good parser should throw when parsing a random symbol\n continue\n }\n throw new Error(\n `Scalar ${scalar.name} does not appear to have an explicit resolver, or is not performing sufficient validation when parsing input. ` +\n \"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.\",\n )\n }\n}\n"],"names":["GraphQLScalarType"],"mappings":";;;;AAGA;;;;;;AAMG;SACa,kCAAkC,CAAC,MAAqB,EAAE,GAAG,eAAyB,EAAA;AACpG,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAA6B,CAAC,YAAYA,yBAAiB,CAAC;AACxH,IAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC5B,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE;AAC/F,QAAA,IAAI;AACF,YAAA,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;QAC/B;AAAE,QAAA,MAAM;;YAEN;QACF;AACA,QAAA,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,CAAA,8GAAA,CAAgH;AACnI,YAAA,6GAA6G,CAChH;IACH;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema-util.mjs","sources":["../src/schema-util.ts"],"sourcesContent":["import type { GraphQLSchema } from 'graphql'\nimport { GraphQLScalarType } from 'graphql'\n\n/**\n * It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in\n * this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types\n * provide at least a base level of validation by failing to parse a Symbol instance. The default resolver does not pass this test\n * meaning any scalars that are falling back to the default resolver will fail.\n * @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`\n */\nexport function requireExplicitResolversForScalars(schema: GraphQLSchema, ...scalarsToIgnore: string[]) {\n const testSymbol = Symbol('testSymbol')\n const scalars = Object.values(schema.getTypeMap()).filter((t): t is GraphQLScalarType => t instanceof GraphQLScalarType)\n for (const scalar of scalars) {\n if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name)) continue\n try {\n scalar.parseValue(testSymbol)\n } catch {\n // We expect that a good parser should throw when parsing a random symbol\n continue\n }\n throw new Error(\n `Scalar ${scalar.name} does not appear to have an explicit resolver, or is not performing sufficient validation when parsing input. ` +\n \"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.\",\n )\n }\n}\n"],"names":[],"mappings":";;AAGA;;;;;;AAMG;SACa,kCAAkC,CAAC,MAAqB,EAAE,GAAG,eAAyB,EAAA;AACpG,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAA6B,CAAC,YAAY,iBAAiB,CAAC,CAAA;AACxH,IAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC5B,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,SAAQ;AACvG,QAAA,IAAI;AACF,YAAA,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;SAC9B;AAAC,QAAA,MAAM;;YAEN,SAAQ;SACT;AACD,QAAA,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,CAAgH,8GAAA,CAAA;AACnI,YAAA,6GAA6G,CAChH,CAAA;KACF;AACH;;;;"}
1
+ {"version":3,"file":"schema-util.mjs","sources":["../src/schema-util.ts"],"sourcesContent":["import type { GraphQLSchema } from 'graphql'\nimport { GraphQLScalarType } from 'graphql'\n\n/**\n * It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in\n * this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types\n * provide at least a base level of validation by failing to parse a Symbol instance. The default resolver does not pass this test\n * meaning any scalars that are falling back to the default resolver will fail.\n * @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`\n */\nexport function requireExplicitResolversForScalars(schema: GraphQLSchema, ...scalarsToIgnore: string[]) {\n const testSymbol = Symbol('testSymbol')\n const scalars = Object.values(schema.getTypeMap()).filter((t): t is GraphQLScalarType => t instanceof GraphQLScalarType)\n for (const scalar of scalars) {\n if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name)) continue\n try {\n scalar.parseValue(testSymbol)\n } catch {\n // We expect that a good parser should throw when parsing a random symbol\n continue\n }\n throw new Error(\n `Scalar ${scalar.name} does not appear to have an explicit resolver, or is not performing sufficient validation when parsing input. ` +\n \"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.\",\n )\n }\n}\n"],"names":[],"mappings":";;AAGA;;;;;;AAMG;SACa,kCAAkC,CAAC,MAAqB,EAAE,GAAG,eAAyB,EAAA;AACpG,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAA6B,CAAC,YAAY,iBAAiB,CAAC;AACxH,IAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC5B,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE;AAC/F,QAAA,IAAI;AACF,YAAA,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;QAC/B;AAAE,QAAA,MAAM;;YAEN;QACF;AACA,QAAA,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,CAAA,8GAAA,CAAgH;AACnI,YAAA,6GAA6G,CAChH;IACH;AACF;;;;"}
package/shield.d.ts CHANGED
@@ -3,7 +3,7 @@ import { allow } from 'graphql-shield';
3
3
  import type { Primitive } from './models';
4
4
  type RuleCombinator = typeof chain | typeof race | typeof or | typeof and;
5
5
  export type ShieldRule = ReturnType<(typeof allow)['getRules']>[number];
6
- export declare const createRule: <TContext, TParent = unknown, TArgs = unknown>(logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error, cache?: 'contextual' | 'strict') => ShieldRule;
6
+ export declare const createRule: <TContext, TParent = unknown, TArgs = unknown>(logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error, cache?: "contextual" | "strict") => ShieldRule;
7
7
  /**
8
8
  * Combines a given rule with all existing defined rules using the provided combinator
9
9
  * @param schema The existing shield schema with rules
package/shield.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"shield.js","sources":["../src/shield.ts"],"sourcesContent":["import type { and, chain, or, race } from 'graphql-shield'\nimport { allow, rule, shield } from 'graphql-shield'\nimport type { IRules } from 'graphql-shield'\nimport type { Primitive } from './models'\n\ntype RuleCombinator = typeof chain | typeof race | typeof or | typeof and\n// For whatever reason, graphql-shield doesn't export this type, but we can extract if from\n// what it does export.\nexport type ShieldRule = ReturnType<(typeof allow)['getRules']>[number]\nexport const createRule = <TContext, TParent = unknown, TArgs = unknown>(\n logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error,\n cache: 'contextual' | 'strict' = 'strict',\n): ShieldRule => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx))\n\n/**\n * Combines a given rule with all existing defined rules using the provided combinator\n * @param schema The existing shield schema with rules\n * @param rule The rule to be combined with existing rules\n * @param combinator The combinator to use. Eg. and | or | chain | race\n *\n * Usage:\n *\n * const updatedSchema = combineRuleWithAll(shieldSchema, rules.accountNotBlocked, chain)\n */\nexport function combineRuleWithAll<T>(schema: ShieldSchema<T>, rule: ShieldRule, combinator: RuleCombinator): ShieldSchema<T> {\n return Object.fromEntries(\n Object.entries(schema).map(([key, value]) => {\n if (value.constructor.name !== 'Object') {\n return [key, combinator(rule, value)]\n }\n return [key, combineRuleWithAll(value, rule, combinator)]\n }),\n ) as ShieldSchema<T>\n}\n\n/**\n * Creates graphql shield middleware making use of generics to type the definition of the rules.\n * @param schema A mapping of schema objects to the shield rules that define the access to that object\n * @param fallbackRule A fallback rule to apply to any object or property which doesn't have a defined rule.\n *\n * Usage:\n * import { Resolvers } from '../generated/types'\n *\n * const shieldSchema = createShieldSchema<Resolvers>({\n * Query: {\n * getThings: allow,\n * dontGetThings: deny,\n * }\n * })\n *\n * let schema = makeExecutableSchema({...})\n *\n * schema = applyMiddleware(schema, shieldSchema)\n */\nexport function createShieldSchema<TRootResolvers>(schema: ShieldSchema<TRootResolvers>, fallbackRule: ShieldRule = allow) {\n return shield(schema as IRules, {\n allowExternalErrors: true,\n fallbackRule: fallbackRule,\n })\n}\n\nexport type ShieldSchema<TResolver> = TResolver extends Primitive\n ? ShieldRule\n : {\n [key in keyof TResolver]?: ShieldSchema<TResolver[key]> | ShieldRule\n } & {\n '*'?: ShieldRule\n }\n"],"names":["rule","allow","shield"],"mappings":";;;;AASa,MAAA,UAAU,GAAG,CACxB,KAA0F,EAC1F,KAAA,GAAiC,QAAQ,KAC1BA,kBAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,EAAC;AAEvF;;;;;;;;;AASG;SACa,kBAAkB,CAAI,MAAuB,EAAE,IAAgB,EAAE,UAA0B,EAAA;IACzG,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;QAC1C,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE;YACvC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;SACtC;AACD,QAAA,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAA;KAC1D,CAAC,CACgB,CAAA;AACtB,CAAC;AAED;;;;;;;;;;;;;;;;;;AAkBG;SACa,kBAAkB,CAAiB,MAAoC,EAAE,eAA2BC,mBAAK,EAAA;IACvH,OAAOC,oBAAM,CAAC,MAAgB,EAAE;AAC9B,QAAA,mBAAmB,EAAE,IAAI;AACzB,QAAA,YAAY,EAAE,YAAY;AAC3B,KAAA,CAAC,CAAA;AACJ;;;;;;"}
1
+ {"version":3,"file":"shield.js","sources":["../src/shield.ts"],"sourcesContent":["import type { and, chain, or, race } from 'graphql-shield'\nimport { allow, rule, shield } from 'graphql-shield'\nimport type { IRules } from 'graphql-shield'\nimport type { Primitive } from './models'\n\ntype RuleCombinator = typeof chain | typeof race | typeof or | typeof and\n// For whatever reason, graphql-shield doesn't export this type, but we can extract if from\n// what it does export.\nexport type ShieldRule = ReturnType<(typeof allow)['getRules']>[number]\nexport const createRule = <TContext, TParent = unknown, TArgs = unknown>(\n logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error,\n cache: 'contextual' | 'strict' = 'strict',\n): ShieldRule => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx))\n\n/**\n * Combines a given rule with all existing defined rules using the provided combinator\n * @param schema The existing shield schema with rules\n * @param rule The rule to be combined with existing rules\n * @param combinator The combinator to use. Eg. and | or | chain | race\n *\n * Usage:\n *\n * const updatedSchema = combineRuleWithAll(shieldSchema, rules.accountNotBlocked, chain)\n */\nexport function combineRuleWithAll<T>(schema: ShieldSchema<T>, rule: ShieldRule, combinator: RuleCombinator): ShieldSchema<T> {\n return Object.fromEntries(\n Object.entries(schema).map(([key, value]) => {\n if (value.constructor.name !== 'Object') {\n return [key, combinator(rule, value)]\n }\n return [key, combineRuleWithAll(value, rule, combinator)]\n }),\n ) as ShieldSchema<T>\n}\n\n/**\n * Creates graphql shield middleware making use of generics to type the definition of the rules.\n * @param schema A mapping of schema objects to the shield rules that define the access to that object\n * @param fallbackRule A fallback rule to apply to any object or property which doesn't have a defined rule.\n *\n * Usage:\n * import { Resolvers } from '../generated/types'\n *\n * const shieldSchema = createShieldSchema<Resolvers>({\n * Query: {\n * getThings: allow,\n * dontGetThings: deny,\n * }\n * })\n *\n * let schema = makeExecutableSchema({...})\n *\n * schema = applyMiddleware(schema, shieldSchema)\n */\nexport function createShieldSchema<TRootResolvers>(schema: ShieldSchema<TRootResolvers>, fallbackRule: ShieldRule = allow) {\n return shield(schema as IRules, {\n allowExternalErrors: true,\n fallbackRule: fallbackRule,\n })\n}\n\nexport type ShieldSchema<TResolver> = TResolver extends Primitive\n ? ShieldRule\n : {\n [key in keyof TResolver]?: ShieldSchema<TResolver[key]> | ShieldRule\n } & {\n '*'?: ShieldRule\n }\n"],"names":["rule","allow","shield"],"mappings":";;;;AASO,MAAM,UAAU,GAAG,CACxB,KAA0F,EAC1F,KAAA,GAAiC,QAAQ,KAC1BA,kBAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC;AAEtF;;;;;;;;;AASG;SACa,kBAAkB,CAAI,MAAuB,EAAE,IAAgB,EAAE,UAA0B,EAAA;IACzG,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;QAC1C,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE;YACvC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC;AACA,QAAA,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC,CACgB;AACtB;AAEA;;;;;;;;;;;;;;;;;;AAkBG;SACa,kBAAkB,CAAiB,MAAoC,EAAE,eAA2BC,mBAAK,EAAA;IACvH,OAAOC,oBAAM,CAAC,MAAgB,EAAE;AAC9B,QAAA,mBAAmB,EAAE,IAAI;AACzB,QAAA,YAAY,EAAE,YAAY;AAC3B,KAAA,CAAC;AACJ;;;;;;"}
package/shield.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { rule, shield, allow } from 'graphql-shield';
1
+ import { rule, allow, shield } from 'graphql-shield';
2
2
 
3
3
  const createRule = (logic, cache = 'strict') => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx));
4
4
  /**
package/shield.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"shield.mjs","sources":["../src/shield.ts"],"sourcesContent":["import type { and, chain, or, race } from 'graphql-shield'\nimport { allow, rule, shield } from 'graphql-shield'\nimport type { IRules } from 'graphql-shield'\nimport type { Primitive } from './models'\n\ntype RuleCombinator = typeof chain | typeof race | typeof or | typeof and\n// For whatever reason, graphql-shield doesn't export this type, but we can extract if from\n// what it does export.\nexport type ShieldRule = ReturnType<(typeof allow)['getRules']>[number]\nexport const createRule = <TContext, TParent = unknown, TArgs = unknown>(\n logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error,\n cache: 'contextual' | 'strict' = 'strict',\n): ShieldRule => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx))\n\n/**\n * Combines a given rule with all existing defined rules using the provided combinator\n * @param schema The existing shield schema with rules\n * @param rule The rule to be combined with existing rules\n * @param combinator The combinator to use. Eg. and | or | chain | race\n *\n * Usage:\n *\n * const updatedSchema = combineRuleWithAll(shieldSchema, rules.accountNotBlocked, chain)\n */\nexport function combineRuleWithAll<T>(schema: ShieldSchema<T>, rule: ShieldRule, combinator: RuleCombinator): ShieldSchema<T> {\n return Object.fromEntries(\n Object.entries(schema).map(([key, value]) => {\n if (value.constructor.name !== 'Object') {\n return [key, combinator(rule, value)]\n }\n return [key, combineRuleWithAll(value, rule, combinator)]\n }),\n ) as ShieldSchema<T>\n}\n\n/**\n * Creates graphql shield middleware making use of generics to type the definition of the rules.\n * @param schema A mapping of schema objects to the shield rules that define the access to that object\n * @param fallbackRule A fallback rule to apply to any object or property which doesn't have a defined rule.\n *\n * Usage:\n * import { Resolvers } from '../generated/types'\n *\n * const shieldSchema = createShieldSchema<Resolvers>({\n * Query: {\n * getThings: allow,\n * dontGetThings: deny,\n * }\n * })\n *\n * let schema = makeExecutableSchema({...})\n *\n * schema = applyMiddleware(schema, shieldSchema)\n */\nexport function createShieldSchema<TRootResolvers>(schema: ShieldSchema<TRootResolvers>, fallbackRule: ShieldRule = allow) {\n return shield(schema as IRules, {\n allowExternalErrors: true,\n fallbackRule: fallbackRule,\n })\n}\n\nexport type ShieldSchema<TResolver> = TResolver extends Primitive\n ? ShieldRule\n : {\n [key in keyof TResolver]?: ShieldSchema<TResolver[key]> | ShieldRule\n } & {\n '*'?: ShieldRule\n }\n"],"names":[],"mappings":";;AASa,MAAA,UAAU,GAAG,CACxB,KAA0F,EAC1F,KAAA,GAAiC,QAAQ,KAC1B,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,EAAC;AAEvF;;;;;;;;;AASG;SACa,kBAAkB,CAAI,MAAuB,EAAE,IAAgB,EAAE,UAA0B,EAAA;IACzG,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;QAC1C,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE;YACvC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;SACtC;AACD,QAAA,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAA;KAC1D,CAAC,CACgB,CAAA;AACtB,CAAC;AAED;;;;;;;;;;;;;;;;;;AAkBG;SACa,kBAAkB,CAAiB,MAAoC,EAAE,eAA2B,KAAK,EAAA;IACvH,OAAO,MAAM,CAAC,MAAgB,EAAE;AAC9B,QAAA,mBAAmB,EAAE,IAAI;AACzB,QAAA,YAAY,EAAE,YAAY;AAC3B,KAAA,CAAC,CAAA;AACJ;;;;"}
1
+ {"version":3,"file":"shield.mjs","sources":["../src/shield.ts"],"sourcesContent":["import type { and, chain, or, race } from 'graphql-shield'\nimport { allow, rule, shield } from 'graphql-shield'\nimport type { IRules } from 'graphql-shield'\nimport type { Primitive } from './models'\n\ntype RuleCombinator = typeof chain | typeof race | typeof or | typeof and\n// For whatever reason, graphql-shield doesn't export this type, but we can extract if from\n// what it does export.\nexport type ShieldRule = ReturnType<(typeof allow)['getRules']>[number]\nexport const createRule = <TContext, TParent = unknown, TArgs = unknown>(\n logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error,\n cache: 'contextual' | 'strict' = 'strict',\n): ShieldRule => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx))\n\n/**\n * Combines a given rule with all existing defined rules using the provided combinator\n * @param schema The existing shield schema with rules\n * @param rule The rule to be combined with existing rules\n * @param combinator The combinator to use. Eg. and | or | chain | race\n *\n * Usage:\n *\n * const updatedSchema = combineRuleWithAll(shieldSchema, rules.accountNotBlocked, chain)\n */\nexport function combineRuleWithAll<T>(schema: ShieldSchema<T>, rule: ShieldRule, combinator: RuleCombinator): ShieldSchema<T> {\n return Object.fromEntries(\n Object.entries(schema).map(([key, value]) => {\n if (value.constructor.name !== 'Object') {\n return [key, combinator(rule, value)]\n }\n return [key, combineRuleWithAll(value, rule, combinator)]\n }),\n ) as ShieldSchema<T>\n}\n\n/**\n * Creates graphql shield middleware making use of generics to type the definition of the rules.\n * @param schema A mapping of schema objects to the shield rules that define the access to that object\n * @param fallbackRule A fallback rule to apply to any object or property which doesn't have a defined rule.\n *\n * Usage:\n * import { Resolvers } from '../generated/types'\n *\n * const shieldSchema = createShieldSchema<Resolvers>({\n * Query: {\n * getThings: allow,\n * dontGetThings: deny,\n * }\n * })\n *\n * let schema = makeExecutableSchema({...})\n *\n * schema = applyMiddleware(schema, shieldSchema)\n */\nexport function createShieldSchema<TRootResolvers>(schema: ShieldSchema<TRootResolvers>, fallbackRule: ShieldRule = allow) {\n return shield(schema as IRules, {\n allowExternalErrors: true,\n fallbackRule: fallbackRule,\n })\n}\n\nexport type ShieldSchema<TResolver> = TResolver extends Primitive\n ? ShieldRule\n : {\n [key in keyof TResolver]?: ShieldSchema<TResolver[key]> | ShieldRule\n } & {\n '*'?: ShieldRule\n }\n"],"names":[],"mappings":";;AASO,MAAM,UAAU,GAAG,CACxB,KAA0F,EAC1F,KAAA,GAAiC,QAAQ,KAC1B,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC;AAEtF;;;;;;;;;AASG;SACa,kBAAkB,CAAI,MAAuB,EAAE,IAAgB,EAAE,UAA0B,EAAA;IACzG,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;QAC1C,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE;YACvC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC;AACA,QAAA,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC,CACgB;AACtB;AAEA;;;;;;;;;;;;;;;;;;AAkBG;SACa,kBAAkB,CAAiB,MAAoC,EAAE,eAA2B,KAAK,EAAA;IACvH,OAAO,MAAM,CAAC,MAAgB,EAAE;AAC9B,QAAA,mBAAmB,EAAE,IAAI;AACzB,QAAA,YAAY,EAAE,YAAY;AAC3B,KAAA,CAAC;AACJ;;;;"}
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { Logger } from '@makerx/node-common';
3
2
  import type { IncomingMessage } from 'http';
4
3
  import { User } from '../User';
@@ -19,4 +18,4 @@ export interface CreateSubscriptionContextConfig<TContext = GraphQLContext> {
19
18
  requestInfoToLog?: Array<keyof RequestInfo>;
20
19
  augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
21
20
  }
22
- export declare const createSubscriptionContextFactory: <TContext extends GraphQLContext<Logger, RequestInfo, User | undefined> = GraphQLContext<Logger, RequestInfo, User | undefined>>({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }: CreateSubscriptionContextConfig<TContext>) => CreateSubscriptionContext<TContext>;
21
+ export declare const createSubscriptionContextFactory: <TContext extends GraphQLContext = GraphQLContext>({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }: CreateSubscriptionContextConfig<TContext>) => CreateSubscriptionContext<TContext>;
@@ -10,7 +10,7 @@ const createSubscriptionContextFactory = ({ requestLogger, augmentRequestInfo, c
10
10
  return async (input) => {
11
11
  const { connectRequest: req, claims } = input;
12
12
  const xForwardedFor = req.headers['x-forwarded-for'];
13
- const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor ?? req.headers.host;
13
+ const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : (xForwardedFor ?? req.headers.host);
14
14
  // build request info from the connect request and socket
15
15
  const requestInfo = {
16
16
  requestId: req.headers['x-request-id']?.toString() ?? crypto.randomUUID(),
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sources":["../../src/subscriptions/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { IncomingMessage } from 'http'\nimport { pick } from 'lodash'\nimport { User } from '../User'\nimport type { CreateRequestLogger, GraphQLContext, JwtPayload, RequestInfo } from '../context'\nimport { extractTokenFromConnectionParams } from './utils'\n\nexport interface SubscriptionContextInput {\n connectRequest: IncomingMessage\n connectionParams?: Readonly<Record<string, unknown>>\n claims?: JwtPayload\n}\n\nexport type CreateSubscriptionUser<T = User | undefined> = (input: SubscriptionContextInput) => Promise<T>\nexport type CreateSubscriptionContext<TContext = GraphQLContext> = (input: SubscriptionContextInput) => Promise<TContext>\nexport type AugmentSubscriptionRequestInfo = (input: SubscriptionContextInput) => Record<string, unknown>\n\nexport interface CreateSubscriptionContextConfig<TContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentSubscriptionRequestInfo\n claimsToLog?: string[]\n createUser?: CreateSubscriptionUser\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createSubscriptionContextFactory = <TContext extends GraphQLContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser = defaultCreateUser,\n requestInfoToLog,\n augmentContext,\n}: CreateSubscriptionContextConfig<TContext>): CreateSubscriptionContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: SubscriptionContextInput) => {\n const { connectRequest: req, claims } = input\n\n const xForwardedFor = req.headers['x-forwarded-for']\n const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor ?? req.headers.host\n\n // build request info from the connect request and socket\n const requestInfo: RequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: 'ws',\n host: host ?? '',\n method: req.method ?? '',\n url: req.url ?? '',\n origin: req.headers['origin'] ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n ...augmentRequestInfo?.(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: await createUser(input),\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nconst defaultCreateUser: CreateSubscriptionUser<User | undefined> = ({ claims, connectionParams }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = extractTokenFromConnectionParams(connectionParams)\n return Promise.resolve(new User(claims, accessToken ?? ''))\n}\n"],"names":["randomUUID","pick","extractTokenFromConnectionParams","User"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sources":["../../src/subscriptions/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { IncomingMessage } from 'http'\nimport { pick } from 'lodash'\nimport { User } from '../User'\nimport type { CreateRequestLogger, GraphQLContext, JwtPayload, RequestInfo } from '../context'\nimport { extractTokenFromConnectionParams } from './utils'\n\nexport interface SubscriptionContextInput {\n connectRequest: IncomingMessage\n connectionParams?: Readonly<Record<string, unknown>>\n claims?: JwtPayload\n}\n\nexport type CreateSubscriptionUser<T = User | undefined> = (input: SubscriptionContextInput) => Promise<T>\nexport type CreateSubscriptionContext<TContext = GraphQLContext> = (input: SubscriptionContextInput) => Promise<TContext>\nexport type AugmentSubscriptionRequestInfo = (input: SubscriptionContextInput) => Record<string, unknown>\n\nexport interface CreateSubscriptionContextConfig<TContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentSubscriptionRequestInfo\n claimsToLog?: string[]\n createUser?: CreateSubscriptionUser\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createSubscriptionContextFactory = <TContext extends GraphQLContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser = defaultCreateUser,\n requestInfoToLog,\n augmentContext,\n}: CreateSubscriptionContextConfig<TContext>): CreateSubscriptionContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: SubscriptionContextInput) => {\n const { connectRequest: req, claims } = input\n\n const xForwardedFor = req.headers['x-forwarded-for']\n const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : (xForwardedFor ?? req.headers.host)\n\n // build request info from the connect request and socket\n const requestInfo: RequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: 'ws',\n host: host ?? '',\n method: req.method ?? '',\n url: req.url ?? '',\n origin: req.headers['origin'] ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n ...augmentRequestInfo?.(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: await createUser(input),\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nconst defaultCreateUser: CreateSubscriptionUser<User | undefined> = ({ claims, connectionParams }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = extractTokenFromConnectionParams(connectionParams)\n return Promise.resolve(new User(claims, accessToken ?? ''))\n}\n"],"names":["randomUUID","pick","extractTokenFromConnectionParams","User"],"mappings":";;;;;;;MA2Ba,gCAAgC,GAAG,CAAmD,EACjG,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,UAAU,GAAG,iBAAiB,EAC9B,gBAAgB,EAChB,cAAc,GAC4B,KAAyC;;AAEnF,IAAA,OAAO,OAAO,KAA+B,KAAI;QAC/C,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK;QAE7C,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;;AAGlG,QAAA,MAAM,WAAW,GAAgB;AAC/B,YAAA,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAIA,iBAAU,EAAE;AAClE,YAAA,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI,IAAI,EAAE;AAChB,YAAA,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;AACxB,YAAA,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,EAAE;YAClB,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;YACnC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC9C,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,SAAS;AAC9D,YAAA,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa;YAChF,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,SAAS;AACvE,YAAA,GAAG,kBAAkB,GAAG,KAAK,CAAC;SAC/B;;AAGD,QAAA,IAAI,MAAc;AAClB,QAAA,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE;;YAEvC,MAAM,qBAAqB,GAA4B,EAAE;;YAEzD,IAAI,gBAAgB,EAAE,MAAM;gBAAE,qBAAqB,CAAC,OAAO,GAAGC,WAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC;;AAEjG,YAAA,IAAI,MAAM,IAAI,WAAW,EAAE,MAAM;gBAAE,qBAAqB,CAAC,IAAI,GAAGA,WAAI,CAAC,MAAM,EAAE,WAAW,CAAC;;AAEzF,YAAA,MAAM,GAAG,aAAa,CAAC,qBAAqB,CAAC;QAC/C;;YAAO,MAAM,GAAG,aAAa;AAE7B,QAAA,MAAM,cAAc,GAAmB;YACrC,WAAW;YACX,MAAM;AACN,YAAA,IAAI,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC;AAC7B,YAAA,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;SACpB;QAED,MAAM,uBAAuB,GAAG;AAC9B,cAAE,EAAE,GAAG,cAAc,EAAE,IAAI,MAAM,cAAc,CAAC,cAA0B,CAAC,CAAC;cAC1E,cAAc;AAElB,QAAA,OAAO,uBAAmC;AAC5C,IAAA,CAAC;AACH;AAEA,MAAM,iBAAiB,GAA6C,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAI;AACnG,IAAA,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;AAC9C,IAAA,MAAM,WAAW,GAAGC,sCAAgC,CAAC,gBAAgB,CAAC;AACtE,IAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAIC,SAAI,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;;;;"}
@@ -8,7 +8,7 @@ const createSubscriptionContextFactory = ({ requestLogger, augmentRequestInfo, c
8
8
  return async (input) => {
9
9
  const { connectRequest: req, claims } = input;
10
10
  const xForwardedFor = req.headers['x-forwarded-for'];
11
- const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor ?? req.headers.host;
11
+ const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : (xForwardedFor ?? req.headers.host);
12
12
  // build request info from the connect request and socket
13
13
  const requestInfo = {
14
14
  requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),
@@ -1 +1 @@
1
- {"version":3,"file":"context.mjs","sources":["../../src/subscriptions/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { IncomingMessage } from 'http'\nimport { pick } from 'lodash'\nimport { User } from '../User'\nimport type { CreateRequestLogger, GraphQLContext, JwtPayload, RequestInfo } from '../context'\nimport { extractTokenFromConnectionParams } from './utils'\n\nexport interface SubscriptionContextInput {\n connectRequest: IncomingMessage\n connectionParams?: Readonly<Record<string, unknown>>\n claims?: JwtPayload\n}\n\nexport type CreateSubscriptionUser<T = User | undefined> = (input: SubscriptionContextInput) => Promise<T>\nexport type CreateSubscriptionContext<TContext = GraphQLContext> = (input: SubscriptionContextInput) => Promise<TContext>\nexport type AugmentSubscriptionRequestInfo = (input: SubscriptionContextInput) => Record<string, unknown>\n\nexport interface CreateSubscriptionContextConfig<TContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentSubscriptionRequestInfo\n claimsToLog?: string[]\n createUser?: CreateSubscriptionUser\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createSubscriptionContextFactory = <TContext extends GraphQLContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser = defaultCreateUser,\n requestInfoToLog,\n augmentContext,\n}: CreateSubscriptionContextConfig<TContext>): CreateSubscriptionContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: SubscriptionContextInput) => {\n const { connectRequest: req, claims } = input\n\n const xForwardedFor = req.headers['x-forwarded-for']\n const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor ?? req.headers.host\n\n // build request info from the connect request and socket\n const requestInfo: RequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: 'ws',\n host: host ?? '',\n method: req.method ?? '',\n url: req.url ?? '',\n origin: req.headers['origin'] ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n ...augmentRequestInfo?.(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: await createUser(input),\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nconst defaultCreateUser: CreateSubscriptionUser<User | undefined> = ({ claims, connectionParams }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = extractTokenFromConnectionParams(connectionParams)\n return Promise.resolve(new User(claims, accessToken ?? ''))\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.mjs","sources":["../../src/subscriptions/context.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport { randomUUID } from 'crypto'\nimport type { IncomingMessage } from 'http'\nimport { pick } from 'lodash'\nimport { User } from '../User'\nimport type { CreateRequestLogger, GraphQLContext, JwtPayload, RequestInfo } from '../context'\nimport { extractTokenFromConnectionParams } from './utils'\n\nexport interface SubscriptionContextInput {\n connectRequest: IncomingMessage\n connectionParams?: Readonly<Record<string, unknown>>\n claims?: JwtPayload\n}\n\nexport type CreateSubscriptionUser<T = User | undefined> = (input: SubscriptionContextInput) => Promise<T>\nexport type CreateSubscriptionContext<TContext = GraphQLContext> = (input: SubscriptionContextInput) => Promise<TContext>\nexport type AugmentSubscriptionRequestInfo = (input: SubscriptionContextInput) => Record<string, unknown>\n\nexport interface CreateSubscriptionContextConfig<TContext = GraphQLContext> {\n requestLogger: CreateRequestLogger | Logger\n augmentRequestInfo?: AugmentSubscriptionRequestInfo\n claimsToLog?: string[]\n createUser?: CreateSubscriptionUser\n requestInfoToLog?: Array<keyof RequestInfo>\n augmentContext?: (context: TContext) => Record<string, unknown> | Promise<Record<string, unknown>>\n}\n\nexport const createSubscriptionContextFactory = <TContext extends GraphQLContext = GraphQLContext>({\n requestLogger,\n augmentRequestInfo,\n claimsToLog,\n createUser = defaultCreateUser,\n requestInfoToLog,\n augmentContext,\n}: CreateSubscriptionContextConfig<TContext>): CreateSubscriptionContext<TContext> => {\n // the function that creates the GraphQL context\n return async (input: SubscriptionContextInput) => {\n const { connectRequest: req, claims } = input\n\n const xForwardedFor = req.headers['x-forwarded-for']\n const host = Array.isArray(xForwardedFor) ? xForwardedFor[0] : (xForwardedFor ?? req.headers.host)\n\n // build request info from the connect request and socket\n const requestInfo: RequestInfo = {\n requestId: req.headers['x-request-id']?.toString() ?? randomUUID(),\n protocol: 'ws',\n host: host ?? '',\n method: req.method ?? '',\n url: req.url ?? '',\n origin: req.headers['origin'] ?? '',\n referer: req.headers.referer?.toString() ?? '',\n arrLogId: req.headers['x-arr-log-id']?.toString() ?? undefined,\n clientIp: req.headers['x-forwarded-for']?.toString() ?? req.socket.remoteAddress,\n correlationId: req.headers['x-correlation-id']?.toString() ?? undefined,\n ...augmentRequestInfo?.(input),\n }\n\n // create request logger\n let logger: Logger\n if (typeof requestLogger === 'function') {\n // build request logger metadata\n const requestLoggerMetadata: Record<string, unknown> = {}\n // add request info to log\n if (requestInfoToLog?.length) requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog)\n // add user claims to log\n if (claims && claimsToLog?.length) requestLoggerMetadata.user = pick(claims, claimsToLog)\n // build the request logger\n logger = requestLogger(requestLoggerMetadata)\n } else logger = requestLogger\n\n const graphqlContext: GraphQLContext = {\n requestInfo,\n logger,\n user: await createUser(input),\n started: Date.now(),\n }\n\n const augmentedGraphQLContext = augmentContext\n ? { ...graphqlContext, ...(await augmentContext(graphqlContext as TContext)) }\n : graphqlContext\n\n return augmentedGraphQLContext as TContext\n }\n}\n\nconst defaultCreateUser: CreateSubscriptionUser<User | undefined> = ({ claims, connectionParams }) => {\n if (!claims) return Promise.resolve(undefined)\n const accessToken = extractTokenFromConnectionParams(connectionParams)\n return Promise.resolve(new User(claims, accessToken ?? ''))\n}\n"],"names":[],"mappings":";;;;;MA2Ba,gCAAgC,GAAG,CAAmD,EACjG,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,UAAU,GAAG,iBAAiB,EAC9B,gBAAgB,EAChB,cAAc,GAC4B,KAAyC;;AAEnF,IAAA,OAAO,OAAO,KAA+B,KAAI;QAC/C,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK;QAE7C,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;;AAGlG,QAAA,MAAM,WAAW,GAAgB;AAC/B,YAAA,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,UAAU,EAAE;AAClE,YAAA,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI,IAAI,EAAE;AAChB,YAAA,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;AACxB,YAAA,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,EAAE;YAClB,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;YACnC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC9C,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,SAAS;AAC9D,YAAA,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa;YAChF,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,SAAS;AACvE,YAAA,GAAG,kBAAkB,GAAG,KAAK,CAAC;SAC/B;;AAGD,QAAA,IAAI,MAAc;AAClB,QAAA,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE;;YAEvC,MAAM,qBAAqB,GAA4B,EAAE;;YAEzD,IAAI,gBAAgB,EAAE,MAAM;gBAAE,qBAAqB,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC;;AAEjG,YAAA,IAAI,MAAM,IAAI,WAAW,EAAE,MAAM;gBAAE,qBAAqB,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC;;AAEzF,YAAA,MAAM,GAAG,aAAa,CAAC,qBAAqB,CAAC;QAC/C;;YAAO,MAAM,GAAG,aAAa;AAE7B,QAAA,MAAM,cAAc,GAAmB;YACrC,WAAW;YACX,MAAM;AACN,YAAA,IAAI,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC;AAC7B,YAAA,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;SACpB;QAED,MAAM,uBAAuB,GAAG;AAC9B,cAAE,EAAE,GAAG,cAAc,EAAE,IAAI,MAAM,cAAc,CAAC,cAA0B,CAAC,CAAC;cAC1E,cAAc;AAElB,QAAA,OAAO,uBAAmC;AAC5C,IAAA,CAAC;AACH;AAEA,MAAM,iBAAiB,GAA6C,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAI;AACnG,IAAA,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;AAC9C,IAAA,MAAM,WAAW,GAAG,gCAAgC,CAAC,gBAAgB,CAAC;AACtE,IAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;;;;"}
@@ -1,10 +1,9 @@
1
- /// <reference types="node" />
2
1
  import type { Logger } from '@makerx/node-common';
3
2
  import type { GraphQLSchema } from 'graphql';
4
3
  import type { Server } from 'http';
5
- import type { JwtPayload } from '../context';
4
+ import type { GraphQLContext, JwtPayload } from '../context';
6
5
  import type { CreateSubscriptionContext } from './context';
7
- export declare function useSubscriptionsServer<TLogger extends Logger = Logger>({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel, path, verifyToken, requireAuth, jwtClaimsToLog, }: {
6
+ export declare function useSubscriptionsServer<TLogger extends Logger = Logger>({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel, path, verifyToken, requireAuth, jwtClaimsToLog, resolveSubscriptionOperationLogger, }: {
8
7
  schema: GraphQLSchema;
9
8
  httpServer: Server;
10
9
  createSubscriptionContext: CreateSubscriptionContext;
@@ -14,4 +13,5 @@ export declare function useSubscriptionsServer<TLogger extends Logger = Logger>(
14
13
  verifyToken?: (host: string, token: string) => Promise<JwtPayload>;
15
14
  requireAuth?: boolean;
16
15
  jwtClaimsToLog?: string[];
16
+ resolveSubscriptionOperationLogger?: (context: GraphQLContext) => TLogger;
17
17
  }): import("graphql-ws").Disposable;
@@ -7,7 +7,7 @@ var ws = require('ws');
7
7
  var logging = require('../logging.js');
8
8
  var utils = require('./utils.js');
9
9
 
10
- function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel = 'info', path = '/graphql', verifyToken, requireAuth, jwtClaimsToLog = ['oid', 'iss'], }) {
10
+ function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel = 'info', path = '/graphql', verifyToken, requireAuth, jwtClaimsToLog = ['oid', 'iss'], resolveSubscriptionOperationLogger, }) {
11
11
  if (requireAuth && !verifyToken)
12
12
  throw new Error('verifyToken must be supplied when requireAuth is true');
13
13
  const wsServer = new ws.WebSocketServer({
@@ -77,10 +77,10 @@ function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext,
77
77
  });
78
78
  },
79
79
  onOperation(_ctx, _message, args) {
80
- logging.logSubscriptionOperation({ args, logLevel: operationLogLevel });
80
+ logging.logSubscriptionOperation({ args, logLevel: operationLogLevel, resolveLogger: resolveSubscriptionOperationLogger });
81
81
  },
82
82
  onNext(_ctx, _message, args, { data, ...result }) {
83
- logging.logSubscriptionOperation({ args, logLevel: operationLogLevel, result });
83
+ logging.logSubscriptionOperation({ args, logLevel: operationLogLevel, result, resolveLogger: resolveSubscriptionOperationLogger });
84
84
  },
85
85
  }, wsServer);
86
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../../src/subscriptions/server.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport type { GraphQLSchema } from 'graphql'\nimport { CloseCode } from 'graphql-ws'\nimport { useServer } from 'graphql-ws/lib/use/ws'\nimport type { Server } from 'http'\nimport { pick } from 'lodash'\nimport { WebSocketServer } from 'ws'\nimport type { JwtPayload } from '../context'\nimport { logSubscriptionOperation } from '../logging'\nimport type { CreateSubscriptionContext } from './context'\nimport { extractTokenFromConnectionParams, getHost } from './utils'\n\nexport function useSubscriptionsServer<TLogger extends Logger = Logger>({\n schema,\n httpServer,\n createSubscriptionContext,\n logger,\n operationLogLevel = 'info',\n path = '/graphql',\n verifyToken,\n requireAuth,\n jwtClaimsToLog = ['oid', 'iss'],\n}: {\n schema: GraphQLSchema\n httpServer: Server\n createSubscriptionContext: CreateSubscriptionContext\n logger: TLogger\n operationLogLevel?: keyof TLogger\n path?: string\n verifyToken?: (host: string, token: string) => Promise<JwtPayload>\n requireAuth?: boolean\n jwtClaimsToLog?: string[]\n}) {\n if (requireAuth && !verifyToken) throw new Error('verifyToken must be supplied when requireAuth is true')\n\n const wsServer = new WebSocketServer({\n server: httpServer,\n path,\n })\n\n return useServer(\n {\n schema,\n onError(_ctx, message, errors) {\n logger.error('GraphQL subscriptions server error', { message, errors })\n },\n onConnect: async (ctx) => {\n const connectionEstablished = 'Subscription connection established'\n if (!verifyToken) {\n logger.info(connectionEstablished)\n return true\n }\n\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n return false\n }\n logger.info(connectionEstablished)\n return true\n }\n\n try {\n const claims = await verifyToken(getHost(ctx.extra.request), token)\n ctx.extra.claims = claims as unknown as undefined\n logger.info(connectionEstablished, {\n claims: pick(claims, jwtClaimsToLog),\n })\n return true\n } catch (error) {\n logger.error('Failed to verify subscription connection auth token', { error })\n return false\n }\n },\n onSubscribe: async (ctx) => {\n if (!verifyToken) return\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n return\n }\n try {\n await verifyToken(getHost(ctx.extra.request), token)\n } catch (error) {\n logger.warn('Subscription connection auth token is no longer valid', { claims: pick(ctx.extra.claims, jwtClaimsToLog), error })\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n },\n onDisconnect({ extra: { claims } }) {\n logger.info('Subscription connection disconnected', { claims: pick(claims, jwtClaimsToLog) })\n },\n context: async (ctx) => {\n return createSubscriptionContext({\n connectRequest: ctx.extra.request,\n connectionParams: ctx.connectionParams,\n claims: ctx.extra.claims as JwtPayload | undefined,\n })\n },\n onOperation(_ctx, _message, args) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel })\n },\n onNext(_ctx, _message, args, { data, ...result }) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, result })\n },\n },\n wsServer,\n )\n}\n"],"names":["WebSocketServer","useServer","extractTokenFromConnectionParams","getHost","pick","CloseCode","logSubscriptionOperation"],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../../src/subscriptions/server.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport type { GraphQLSchema } from 'graphql'\nimport { CloseCode } from 'graphql-ws'\nimport { useServer } from 'graphql-ws/lib/use/ws'\nimport type { Server } from 'http'\nimport { pick } from 'lodash'\nimport { WebSocketServer } from 'ws'\nimport type { GraphQLContext, JwtPayload } from '../context'\nimport { logSubscriptionOperation } from '../logging'\nimport type { CreateSubscriptionContext } from './context'\nimport { extractTokenFromConnectionParams, getHost } from './utils'\n\nexport function useSubscriptionsServer<TLogger extends Logger = Logger>({\n schema,\n httpServer,\n createSubscriptionContext,\n logger,\n operationLogLevel = 'info',\n path = '/graphql',\n verifyToken,\n requireAuth,\n jwtClaimsToLog = ['oid', 'iss'],\n resolveSubscriptionOperationLogger,\n}: {\n schema: GraphQLSchema\n httpServer: Server\n createSubscriptionContext: CreateSubscriptionContext\n logger: TLogger\n operationLogLevel?: keyof TLogger\n path?: string\n verifyToken?: (host: string, token: string) => Promise<JwtPayload>\n requireAuth?: boolean\n jwtClaimsToLog?: string[]\n resolveSubscriptionOperationLogger?: (context: GraphQLContext) => TLogger\n}) {\n if (requireAuth && !verifyToken) throw new Error('verifyToken must be supplied when requireAuth is true')\n\n const wsServer = new WebSocketServer({\n server: httpServer,\n path,\n })\n\n return useServer(\n {\n schema,\n onError(_ctx, message, errors) {\n logger.error('GraphQL subscriptions server error', { message, errors })\n },\n onConnect: async (ctx) => {\n const connectionEstablished = 'Subscription connection established'\n if (!verifyToken) {\n logger.info(connectionEstablished)\n return true\n }\n\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n return false\n }\n logger.info(connectionEstablished)\n return true\n }\n\n try {\n const claims = await verifyToken(getHost(ctx.extra.request), token)\n ctx.extra.claims = claims as unknown as undefined\n logger.info(connectionEstablished, {\n claims: pick(claims, jwtClaimsToLog),\n })\n return true\n } catch (error) {\n logger.error('Failed to verify subscription connection auth token', { error })\n return false\n }\n },\n onSubscribe: async (ctx) => {\n if (!verifyToken) return\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n return\n }\n try {\n await verifyToken(getHost(ctx.extra.request), token)\n } catch (error) {\n logger.warn('Subscription connection auth token is no longer valid', { claims: pick(ctx.extra.claims, jwtClaimsToLog), error })\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n },\n onDisconnect({ extra: { claims } }) {\n logger.info('Subscription connection disconnected', { claims: pick(claims, jwtClaimsToLog) })\n },\n context: async (ctx) => {\n return createSubscriptionContext({\n connectRequest: ctx.extra.request,\n connectionParams: ctx.connectionParams,\n claims: ctx.extra.claims as JwtPayload | undefined,\n })\n },\n onOperation(_ctx, _message, args) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, resolveLogger: resolveSubscriptionOperationLogger })\n },\n onNext(_ctx, _message, args, { data, ...result }) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, result, resolveLogger: resolveSubscriptionOperationLogger })\n },\n },\n wsServer,\n )\n}\n"],"names":["WebSocketServer","useServer","extractTokenFromConnectionParams","getHost","pick","CloseCode","logSubscriptionOperation"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { WebSocketServer } from 'ws';
5
5
  import { logSubscriptionOperation } from '../logging.mjs';
6
6
  import { extractTokenFromConnectionParams, getHost } from './utils.mjs';
7
7
 
8
- function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel = 'info', path = '/graphql', verifyToken, requireAuth, jwtClaimsToLog = ['oid', 'iss'], }) {
8
+ function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext, logger, operationLogLevel = 'info', path = '/graphql', verifyToken, requireAuth, jwtClaimsToLog = ['oid', 'iss'], resolveSubscriptionOperationLogger, }) {
9
9
  if (requireAuth && !verifyToken)
10
10
  throw new Error('verifyToken must be supplied when requireAuth is true');
11
11
  const wsServer = new WebSocketServer({
@@ -75,10 +75,10 @@ function useSubscriptionsServer({ schema, httpServer, createSubscriptionContext,
75
75
  });
76
76
  },
77
77
  onOperation(_ctx, _message, args) {
78
- logSubscriptionOperation({ args, logLevel: operationLogLevel });
78
+ logSubscriptionOperation({ args, logLevel: operationLogLevel, resolveLogger: resolveSubscriptionOperationLogger });
79
79
  },
80
80
  onNext(_ctx, _message, args, { data, ...result }) {
81
- logSubscriptionOperation({ args, logLevel: operationLogLevel, result });
81
+ logSubscriptionOperation({ args, logLevel: operationLogLevel, result, resolveLogger: resolveSubscriptionOperationLogger });
82
82
  },
83
83
  }, wsServer);
84
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","sources":["../../src/subscriptions/server.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport type { GraphQLSchema } from 'graphql'\nimport { CloseCode } from 'graphql-ws'\nimport { useServer } from 'graphql-ws/lib/use/ws'\nimport type { Server } from 'http'\nimport { pick } from 'lodash'\nimport { WebSocketServer } from 'ws'\nimport type { JwtPayload } from '../context'\nimport { logSubscriptionOperation } from '../logging'\nimport type { CreateSubscriptionContext } from './context'\nimport { extractTokenFromConnectionParams, getHost } from './utils'\n\nexport function useSubscriptionsServer<TLogger extends Logger = Logger>({\n schema,\n httpServer,\n createSubscriptionContext,\n logger,\n operationLogLevel = 'info',\n path = '/graphql',\n verifyToken,\n requireAuth,\n jwtClaimsToLog = ['oid', 'iss'],\n}: {\n schema: GraphQLSchema\n httpServer: Server\n createSubscriptionContext: CreateSubscriptionContext\n logger: TLogger\n operationLogLevel?: keyof TLogger\n path?: string\n verifyToken?: (host: string, token: string) => Promise<JwtPayload>\n requireAuth?: boolean\n jwtClaimsToLog?: string[]\n}) {\n if (requireAuth && !verifyToken) throw new Error('verifyToken must be supplied when requireAuth is true')\n\n const wsServer = new WebSocketServer({\n server: httpServer,\n path,\n })\n\n return useServer(\n {\n schema,\n onError(_ctx, message, errors) {\n logger.error('GraphQL subscriptions server error', { message, errors })\n },\n onConnect: async (ctx) => {\n const connectionEstablished = 'Subscription connection established'\n if (!verifyToken) {\n logger.info(connectionEstablished)\n return true\n }\n\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n return false\n }\n logger.info(connectionEstablished)\n return true\n }\n\n try {\n const claims = await verifyToken(getHost(ctx.extra.request), token)\n ctx.extra.claims = claims as unknown as undefined\n logger.info(connectionEstablished, {\n claims: pick(claims, jwtClaimsToLog),\n })\n return true\n } catch (error) {\n logger.error('Failed to verify subscription connection auth token', { error })\n return false\n }\n },\n onSubscribe: async (ctx) => {\n if (!verifyToken) return\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n return\n }\n try {\n await verifyToken(getHost(ctx.extra.request), token)\n } catch (error) {\n logger.warn('Subscription connection auth token is no longer valid', { claims: pick(ctx.extra.claims, jwtClaimsToLog), error })\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n },\n onDisconnect({ extra: { claims } }) {\n logger.info('Subscription connection disconnected', { claims: pick(claims, jwtClaimsToLog) })\n },\n context: async (ctx) => {\n return createSubscriptionContext({\n connectRequest: ctx.extra.request,\n connectionParams: ctx.connectionParams,\n claims: ctx.extra.claims as JwtPayload | undefined,\n })\n },\n onOperation(_ctx, _message, args) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel })\n },\n onNext(_ctx, _message, args, { data, ...result }) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, result })\n },\n },\n wsServer,\n )\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.mjs","sources":["../../src/subscriptions/server.ts"],"sourcesContent":["import type { Logger } from '@makerx/node-common'\nimport type { GraphQLSchema } from 'graphql'\nimport { CloseCode } from 'graphql-ws'\nimport { useServer } from 'graphql-ws/lib/use/ws'\nimport type { Server } from 'http'\nimport { pick } from 'lodash'\nimport { WebSocketServer } from 'ws'\nimport type { GraphQLContext, JwtPayload } from '../context'\nimport { logSubscriptionOperation } from '../logging'\nimport type { CreateSubscriptionContext } from './context'\nimport { extractTokenFromConnectionParams, getHost } from './utils'\n\nexport function useSubscriptionsServer<TLogger extends Logger = Logger>({\n schema,\n httpServer,\n createSubscriptionContext,\n logger,\n operationLogLevel = 'info',\n path = '/graphql',\n verifyToken,\n requireAuth,\n jwtClaimsToLog = ['oid', 'iss'],\n resolveSubscriptionOperationLogger,\n}: {\n schema: GraphQLSchema\n httpServer: Server\n createSubscriptionContext: CreateSubscriptionContext\n logger: TLogger\n operationLogLevel?: keyof TLogger\n path?: string\n verifyToken?: (host: string, token: string) => Promise<JwtPayload>\n requireAuth?: boolean\n jwtClaimsToLog?: string[]\n resolveSubscriptionOperationLogger?: (context: GraphQLContext) => TLogger\n}) {\n if (requireAuth && !verifyToken) throw new Error('verifyToken must be supplied when requireAuth is true')\n\n const wsServer = new WebSocketServer({\n server: httpServer,\n path,\n })\n\n return useServer(\n {\n schema,\n onError(_ctx, message, errors) {\n logger.error('GraphQL subscriptions server error', { message, errors })\n },\n onConnect: async (ctx) => {\n const connectionEstablished = 'Subscription connection established'\n if (!verifyToken) {\n logger.info(connectionEstablished)\n return true\n }\n\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n return false\n }\n logger.info(connectionEstablished)\n return true\n }\n\n try {\n const claims = await verifyToken(getHost(ctx.extra.request), token)\n ctx.extra.claims = claims as unknown as undefined\n logger.info(connectionEstablished, {\n claims: pick(claims, jwtClaimsToLog),\n })\n return true\n } catch (error) {\n logger.error('Failed to verify subscription connection auth token', { error })\n return false\n }\n },\n onSubscribe: async (ctx) => {\n if (!verifyToken) return\n const token = extractTokenFromConnectionParams(ctx.connectionParams)\n if (!token) {\n if (requireAuth) {\n logger.error('No authorization parameter was supplied via websocket connection params')\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n return\n }\n try {\n await verifyToken(getHost(ctx.extra.request), token)\n } catch (error) {\n logger.warn('Subscription connection auth token is no longer valid', { claims: pick(ctx.extra.claims, jwtClaimsToLog), error })\n ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden')\n }\n },\n onDisconnect({ extra: { claims } }) {\n logger.info('Subscription connection disconnected', { claims: pick(claims, jwtClaimsToLog) })\n },\n context: async (ctx) => {\n return createSubscriptionContext({\n connectRequest: ctx.extra.request,\n connectionParams: ctx.connectionParams,\n claims: ctx.extra.claims as JwtPayload | undefined,\n })\n },\n onOperation(_ctx, _message, args) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, resolveLogger: resolveSubscriptionOperationLogger })\n },\n onNext(_ctx, _message, args, { data, ...result }) {\n logSubscriptionOperation({ args, logLevel: operationLogLevel, result, resolveLogger: resolveSubscriptionOperationLogger })\n },\n },\n wsServer,\n )\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { IncomingMessage } from 'http';
3
2
  /**
4
3
  * Extracts a token from a connection parameter named `authorization` or `Authorization`.
@@ -15,7 +15,7 @@ function extractTokenFromConnectionParams(connectionParams) {
15
15
  }
16
16
  function getHost(request) {
17
17
  const proxyHostHeader = request.headers['x-forwarded-host'];
18
- const host = Array.isArray(proxyHostHeader) ? proxyHostHeader[0] ?? undefined : proxyHostHeader ?? request.headers.host ?? undefined;
18
+ const host = Array.isArray(proxyHostHeader) ? (proxyHostHeader[0] ?? undefined) : (proxyHostHeader ?? request.headers.host ?? undefined);
19
19
  return host ?? 'subscriptions';
20
20
  }
21
21
 
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/subscriptions/utils.ts"],"sourcesContent":["import type { IncomingMessage } from 'http'\n\n/**\n * Extracts a token from a connection parameter named `authorization` or `Authorization`.\n * The expected format of the parameter value is: Bearer <token>, consistent with an HTTP Authorization header.\n * Apollo Sandbox sets an `Authorization` connection parameter when you specify an HTTP Authorization header via the UI.\n * @param connectionParams\n * @returns\n */\nexport function extractTokenFromConnectionParams(connectionParams?: Readonly<Record<string, unknown>>) {\n const bearerTokenValue = (connectionParams?.authorization ?? connectionParams?.Authorization) as string | undefined\n if (!bearerTokenValue?.startsWith('Bearer ')) return undefined\n return bearerTokenValue.substring(7)\n}\n\nexport function getHost(request: IncomingMessage) {\n const proxyHostHeader = request.headers['x-forwarded-host']\n const host = Array.isArray(proxyHostHeader) ? proxyHostHeader[0] ?? undefined : proxyHostHeader ?? request.headers.host ?? undefined\n return host ?? 'subscriptions'\n}\n"],"names":[],"mappings":";;AAEA;;;;;;AAMG;AACG,SAAU,gCAAgC,CAAC,gBAAoD,EAAA;IACnG,MAAM,gBAAgB,IAAI,gBAAgB,EAAE,aAAa,IAAI,gBAAgB,EAAE,aAAa,CAAuB,CAAA;AACnH,IAAA,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS,CAAA;AAC9D,IAAA,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AACtC,CAAC;AAEK,SAAU,OAAO,CAAC,OAAwB,EAAA;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,SAAS,GAAG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAA;IACpI,OAAO,IAAI,IAAI,eAAe,CAAA;AAChC;;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/subscriptions/utils.ts"],"sourcesContent":["import type { IncomingMessage } from 'http'\n\n/**\n * Extracts a token from a connection parameter named `authorization` or `Authorization`.\n * The expected format of the parameter value is: Bearer <token>, consistent with an HTTP Authorization header.\n * Apollo Sandbox sets an `Authorization` connection parameter when you specify an HTTP Authorization header via the UI.\n * @param connectionParams\n * @returns\n */\nexport function extractTokenFromConnectionParams(connectionParams?: Readonly<Record<string, unknown>>) {\n const bearerTokenValue = (connectionParams?.authorization ?? connectionParams?.Authorization) as string | undefined\n if (!bearerTokenValue?.startsWith('Bearer ')) return undefined\n return bearerTokenValue.substring(7)\n}\n\nexport function getHost(request: IncomingMessage) {\n const proxyHostHeader = request.headers['x-forwarded-host']\n const host = Array.isArray(proxyHostHeader) ? (proxyHostHeader[0] ?? undefined) : (proxyHostHeader ?? request.headers.host ?? undefined)\n return host ?? 'subscriptions'\n}\n"],"names":[],"mappings":";;AAEA;;;;;;AAMG;AACG,SAAU,gCAAgC,CAAC,gBAAoD,EAAA;IACnG,MAAM,gBAAgB,IAAI,gBAAgB,EAAE,aAAa,IAAI,gBAAgB,EAAE,aAAa,CAAuB;AACnH,IAAA,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AAC9D,IAAA,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;AACtC;AAEM,SAAU,OAAO,CAAC,OAAwB,EAAA;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,IAAI,SAAS,KAAK,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACxI,OAAO,IAAI,IAAI,eAAe;AAChC;;;;;"}
@@ -13,7 +13,7 @@ function extractTokenFromConnectionParams(connectionParams) {
13
13
  }
14
14
  function getHost(request) {
15
15
  const proxyHostHeader = request.headers['x-forwarded-host'];
16
- const host = Array.isArray(proxyHostHeader) ? proxyHostHeader[0] ?? undefined : proxyHostHeader ?? request.headers.host ?? undefined;
16
+ const host = Array.isArray(proxyHostHeader) ? (proxyHostHeader[0] ?? undefined) : (proxyHostHeader ?? request.headers.host ?? undefined);
17
17
  return host ?? 'subscriptions';
18
18
  }
19
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../src/subscriptions/utils.ts"],"sourcesContent":["import type { IncomingMessage } from 'http'\n\n/**\n * Extracts a token from a connection parameter named `authorization` or `Authorization`.\n * The expected format of the parameter value is: Bearer <token>, consistent with an HTTP Authorization header.\n * Apollo Sandbox sets an `Authorization` connection parameter when you specify an HTTP Authorization header via the UI.\n * @param connectionParams\n * @returns\n */\nexport function extractTokenFromConnectionParams(connectionParams?: Readonly<Record<string, unknown>>) {\n const bearerTokenValue = (connectionParams?.authorization ?? connectionParams?.Authorization) as string | undefined\n if (!bearerTokenValue?.startsWith('Bearer ')) return undefined\n return bearerTokenValue.substring(7)\n}\n\nexport function getHost(request: IncomingMessage) {\n const proxyHostHeader = request.headers['x-forwarded-host']\n const host = Array.isArray(proxyHostHeader) ? proxyHostHeader[0] ?? undefined : proxyHostHeader ?? request.headers.host ?? undefined\n return host ?? 'subscriptions'\n}\n"],"names":[],"mappings":"AAEA;;;;;;AAMG;AACG,SAAU,gCAAgC,CAAC,gBAAoD,EAAA;IACnG,MAAM,gBAAgB,IAAI,gBAAgB,EAAE,aAAa,IAAI,gBAAgB,EAAE,aAAa,CAAuB,CAAA;AACnH,IAAA,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS,CAAA;AAC9D,IAAA,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AACtC,CAAC;AAEK,SAAU,OAAO,CAAC,OAAwB,EAAA;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,SAAS,GAAG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAA;IACpI,OAAO,IAAI,IAAI,eAAe,CAAA;AAChC;;;;"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../src/subscriptions/utils.ts"],"sourcesContent":["import type { IncomingMessage } from 'http'\n\n/**\n * Extracts a token from a connection parameter named `authorization` or `Authorization`.\n * The expected format of the parameter value is: Bearer <token>, consistent with an HTTP Authorization header.\n * Apollo Sandbox sets an `Authorization` connection parameter when you specify an HTTP Authorization header via the UI.\n * @param connectionParams\n * @returns\n */\nexport function extractTokenFromConnectionParams(connectionParams?: Readonly<Record<string, unknown>>) {\n const bearerTokenValue = (connectionParams?.authorization ?? connectionParams?.Authorization) as string | undefined\n if (!bearerTokenValue?.startsWith('Bearer ')) return undefined\n return bearerTokenValue.substring(7)\n}\n\nexport function getHost(request: IncomingMessage) {\n const proxyHostHeader = request.headers['x-forwarded-host']\n const host = Array.isArray(proxyHostHeader) ? (proxyHostHeader[0] ?? undefined) : (proxyHostHeader ?? request.headers.host ?? undefined)\n return host ?? 'subscriptions'\n}\n"],"names":[],"mappings":"AAEA;;;;;;AAMG;AACG,SAAU,gCAAgC,CAAC,gBAAoD,EAAA;IACnG,MAAM,gBAAgB,IAAI,gBAAgB,EAAE,aAAa,IAAI,gBAAgB,EAAE,aAAa,CAAuB;AACnH,IAAA,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AAC9D,IAAA,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;AACtC;AAEM,SAAU,OAAO,CAAC,OAAwB,EAAA;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,IAAI,SAAS,KAAK,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACxI,OAAO,IAAI,IAAI,eAAe;AAChC;;;;"}
package/testing.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sources":["../src/testing.ts"],"sourcesContent":["import type { NormalizedCacheObject } from '@apollo/client/core'\nimport { ApolloClient, createHttpLink, from, InMemoryCache } from '@apollo/client/core'\nimport type { ApolloClientOptions } from '@apollo/client/core/ApolloClient'\nimport { setContext } from '@apollo/client/link/context'\nimport type { AccessTokenResponse, ClientCredentialsConfig } from '@makerx/node-common'\nimport { getClientCredentialsToken } from '@makerx/node-common'\n\nexport * from '@apollo/client/core'\n\nconst bearerTokenLink = (accessToken?: string) =>\n setContext((_, { headers }) => {\n if (accessToken)\n return {\n headers: {\n ...headers,\n authorization: `Bearer ${accessToken}`,\n },\n }\n return {\n headers,\n }\n })\n\nconst clientCredentialsLink = (clientCredentialsConfig: ClientCredentialsConfig) => {\n let promise: Promise<AccessTokenResponse> | undefined\n return setContext(async () => {\n if (!promise) promise = getClientCredentialsToken(clientCredentialsConfig)\n let tokenResponse = await promise\n if (tokenResponse.isExpired) {\n promise = getClientCredentialsToken(clientCredentialsConfig)\n tokenResponse = await promise\n }\n return {\n headers: {\n authorization: `Bearer ${tokenResponse.access_token}`,\n },\n }\n })\n}\n\nconst httpLink = (url: string) =>\n createHttpLink({\n uri: url,\n })\n\nexport const createTestClient = (\n url: string,\n accessToken?: string,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([bearerTokenLink(accessToken), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n\nexport const createTestClientWithClientCredentials = (\n url: string,\n clientCredentialsConfig: ClientCredentialsConfig,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([clientCredentialsLink(clientCredentialsConfig), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n"],"names":["setContext","getClientCredentialsToken","createHttpLink","ApolloClient","from","InMemoryCache"],"mappings":";;;;;;AASA,MAAM,eAAe,GAAG,CAAC,WAAoB,KAC3CA,kBAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAI;AAC5B,IAAA,IAAI,WAAW;QACb,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,GAAG,OAAO;gBACV,aAAa,EAAE,CAAU,OAAA,EAAA,WAAW,CAAE,CAAA;AACvC,aAAA;SACF,CAAA;IACH,OAAO;QACL,OAAO;KACR,CAAA;AACH,CAAC,CAAC,CAAA;AAEJ,MAAM,qBAAqB,GAAG,CAAC,uBAAgD,KAAI;AACjF,IAAA,IAAI,OAAiD,CAAA;AACrD,IAAA,OAAOA,kBAAU,CAAC,YAAW;AAC3B,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,GAAGC,oCAAyB,CAAC,uBAAuB,CAAC,CAAA;AAC1E,QAAA,IAAI,aAAa,GAAG,MAAM,OAAO,CAAA;AACjC,QAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,OAAO,GAAGA,oCAAyB,CAAC,uBAAuB,CAAC,CAAA;YAC5D,aAAa,GAAG,MAAM,OAAO,CAAA;SAC9B;QACD,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,aAAa,EAAE,CAAA,OAAA,EAAU,aAAa,CAAC,YAAY,CAAE,CAAA;AACtD,aAAA;SACF,CAAA;AACH,KAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,GAAW,KAC3BC,mBAAc,CAAC;AACb,IAAA,GAAG,EAAE,GAAG;AACT,CAAA,CAAC,CAAA;AAEG,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,WAAoB,EACpB,OAA6D,KAE7D,IAAIC,iBAAY,CAAC;AACf,IAAA,IAAI,EAAEC,SAAI,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,IAAIC,kBAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA,EAAC;AAEG,MAAM,qCAAqC,GAAG,CACnD,GAAW,EACX,uBAAgD,EAChD,OAA6D,KAE7D,IAAIF,iBAAY,CAAC;AACf,IAAA,IAAI,EAAEC,SAAI,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,KAAK,EAAE,IAAIC,kBAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;;;;;;;;;;;"}
1
+ {"version":3,"file":"testing.js","sources":["../src/testing.ts"],"sourcesContent":["import type { NormalizedCacheObject } from '@apollo/client/core'\nimport { ApolloClient, createHttpLink, from, InMemoryCache } from '@apollo/client/core'\nimport type { ApolloClientOptions } from '@apollo/client/core/ApolloClient'\nimport { setContext } from '@apollo/client/link/context'\nimport type { AccessTokenResponse, ClientCredentialsConfig } from '@makerx/node-common'\nimport { getClientCredentialsToken } from '@makerx/node-common'\n\nexport * from '@apollo/client/core'\n\nconst bearerTokenLink = (accessToken?: string) =>\n setContext((_, { headers }) => {\n if (accessToken)\n return {\n headers: {\n ...headers,\n authorization: `Bearer ${accessToken}`,\n },\n }\n return {\n headers,\n }\n })\n\nconst clientCredentialsLink = (clientCredentialsConfig: ClientCredentialsConfig) => {\n let promise: Promise<AccessTokenResponse> | undefined\n return setContext(async () => {\n if (!promise) promise = getClientCredentialsToken(clientCredentialsConfig)\n let tokenResponse = await promise\n if (tokenResponse.isExpired) {\n promise = getClientCredentialsToken(clientCredentialsConfig)\n tokenResponse = await promise\n }\n return {\n headers: {\n authorization: `Bearer ${tokenResponse.access_token}`,\n },\n }\n })\n}\n\nconst httpLink = (url: string) =>\n createHttpLink({\n uri: url,\n })\n\nexport const createTestClient = (\n url: string,\n accessToken?: string,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([bearerTokenLink(accessToken), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n\nexport const createTestClientWithClientCredentials = (\n url: string,\n clientCredentialsConfig: ClientCredentialsConfig,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([clientCredentialsLink(clientCredentialsConfig), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n"],"names":["setContext","getClientCredentialsToken","createHttpLink","ApolloClient","from","InMemoryCache"],"mappings":";;;;;;AASA,MAAM,eAAe,GAAG,CAAC,WAAoB,KAC3CA,kBAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAI;AAC5B,IAAA,IAAI,WAAW;QACb,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,GAAG,OAAO;gBACV,aAAa,EAAE,CAAA,OAAA,EAAU,WAAW,CAAA,CAAE;AACvC,aAAA;SACF;IACH,OAAO;QACL,OAAO;KACR;AACH,CAAC,CAAC;AAEJ,MAAM,qBAAqB,GAAG,CAAC,uBAAgD,KAAI;AACjF,IAAA,IAAI,OAAiD;AACrD,IAAA,OAAOA,kBAAU,CAAC,YAAW;AAC3B,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,GAAGC,oCAAyB,CAAC,uBAAuB,CAAC;AAC1E,QAAA,IAAI,aAAa,GAAG,MAAM,OAAO;AACjC,QAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,OAAO,GAAGA,oCAAyB,CAAC,uBAAuB,CAAC;YAC5D,aAAa,GAAG,MAAM,OAAO;QAC/B;QACA,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,aAAa,EAAE,CAAA,OAAA,EAAU,aAAa,CAAC,YAAY,CAAA,CAAE;AACtD,aAAA;SACF;AACH,IAAA,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,GAAW,KAC3BC,mBAAc,CAAC;AACb,IAAA,GAAG,EAAE,GAAG;AACT,CAAA,CAAC;AAEG,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,WAAoB,EACpB,OAA6D,KAE7D,IAAIC,iBAAY,CAAC;AACf,IAAA,IAAI,EAAEC,SAAI,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,IAAIC,kBAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;AAEI,MAAM,qCAAqC,GAAG,CACnD,GAAW,EACX,uBAAgD,EAChD,OAA6D,KAE7D,IAAIF,iBAAY,CAAC;AACf,IAAA,IAAI,EAAEC,SAAI,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,KAAK,EAAE,IAAIC,kBAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;;;;;;;;;;;"}
package/testing.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { ApolloClient, from, InMemoryCache, createHttpLink } from '@apollo/client/core';
1
+ import { ApolloClient, InMemoryCache, from, createHttpLink } from '@apollo/client/core';
2
2
  export * from '@apollo/client/core';
3
3
  import { setContext } from '@apollo/client/link/context';
4
4
  import { getClientCredentialsToken } from '@makerx/node-common';
package/testing.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"testing.mjs","sources":["../src/testing.ts"],"sourcesContent":["import type { NormalizedCacheObject } from '@apollo/client/core'\nimport { ApolloClient, createHttpLink, from, InMemoryCache } from '@apollo/client/core'\nimport type { ApolloClientOptions } from '@apollo/client/core/ApolloClient'\nimport { setContext } from '@apollo/client/link/context'\nimport type { AccessTokenResponse, ClientCredentialsConfig } from '@makerx/node-common'\nimport { getClientCredentialsToken } from '@makerx/node-common'\n\nexport * from '@apollo/client/core'\n\nconst bearerTokenLink = (accessToken?: string) =>\n setContext((_, { headers }) => {\n if (accessToken)\n return {\n headers: {\n ...headers,\n authorization: `Bearer ${accessToken}`,\n },\n }\n return {\n headers,\n }\n })\n\nconst clientCredentialsLink = (clientCredentialsConfig: ClientCredentialsConfig) => {\n let promise: Promise<AccessTokenResponse> | undefined\n return setContext(async () => {\n if (!promise) promise = getClientCredentialsToken(clientCredentialsConfig)\n let tokenResponse = await promise\n if (tokenResponse.isExpired) {\n promise = getClientCredentialsToken(clientCredentialsConfig)\n tokenResponse = await promise\n }\n return {\n headers: {\n authorization: `Bearer ${tokenResponse.access_token}`,\n },\n }\n })\n}\n\nconst httpLink = (url: string) =>\n createHttpLink({\n uri: url,\n })\n\nexport const createTestClient = (\n url: string,\n accessToken?: string,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([bearerTokenLink(accessToken), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n\nexport const createTestClientWithClientCredentials = (\n url: string,\n clientCredentialsConfig: ClientCredentialsConfig,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([clientCredentialsLink(clientCredentialsConfig), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n"],"names":[],"mappings":";;;;;AASA,MAAM,eAAe,GAAG,CAAC,WAAoB,KAC3C,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAI;AAC5B,IAAA,IAAI,WAAW;QACb,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,GAAG,OAAO;gBACV,aAAa,EAAE,CAAU,OAAA,EAAA,WAAW,CAAE,CAAA;AACvC,aAAA;SACF,CAAA;IACH,OAAO;QACL,OAAO;KACR,CAAA;AACH,CAAC,CAAC,CAAA;AAEJ,MAAM,qBAAqB,GAAG,CAAC,uBAAgD,KAAI;AACjF,IAAA,IAAI,OAAiD,CAAA;AACrD,IAAA,OAAO,UAAU,CAAC,YAAW;AAC3B,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,GAAG,yBAAyB,CAAC,uBAAuB,CAAC,CAAA;AAC1E,QAAA,IAAI,aAAa,GAAG,MAAM,OAAO,CAAA;AACjC,QAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,OAAO,GAAG,yBAAyB,CAAC,uBAAuB,CAAC,CAAA;YAC5D,aAAa,GAAG,MAAM,OAAO,CAAA;SAC9B;QACD,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,aAAa,EAAE,CAAA,OAAA,EAAU,aAAa,CAAC,YAAY,CAAE,CAAA;AACtD,aAAA;SACF,CAAA;AACH,KAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,GAAW,KAC3B,cAAc,CAAC;AACb,IAAA,GAAG,EAAE,GAAG;AACT,CAAA,CAAC,CAAA;AAEG,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,WAAoB,EACpB,OAA6D,KAE7D,IAAI,YAAY,CAAC;AACf,IAAA,IAAI,EAAE,IAAI,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,IAAI,aAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA,EAAC;AAEG,MAAM,qCAAqC,GAAG,CACnD,GAAW,EACX,uBAAgD,EAChD,OAA6D,KAE7D,IAAI,YAAY,CAAC;AACf,IAAA,IAAI,EAAE,IAAI,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,KAAK,EAAE,IAAI,aAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;;;;"}
1
+ {"version":3,"file":"testing.mjs","sources":["../src/testing.ts"],"sourcesContent":["import type { NormalizedCacheObject } from '@apollo/client/core'\nimport { ApolloClient, createHttpLink, from, InMemoryCache } from '@apollo/client/core'\nimport type { ApolloClientOptions } from '@apollo/client/core/ApolloClient'\nimport { setContext } from '@apollo/client/link/context'\nimport type { AccessTokenResponse, ClientCredentialsConfig } from '@makerx/node-common'\nimport { getClientCredentialsToken } from '@makerx/node-common'\n\nexport * from '@apollo/client/core'\n\nconst bearerTokenLink = (accessToken?: string) =>\n setContext((_, { headers }) => {\n if (accessToken)\n return {\n headers: {\n ...headers,\n authorization: `Bearer ${accessToken}`,\n },\n }\n return {\n headers,\n }\n })\n\nconst clientCredentialsLink = (clientCredentialsConfig: ClientCredentialsConfig) => {\n let promise: Promise<AccessTokenResponse> | undefined\n return setContext(async () => {\n if (!promise) promise = getClientCredentialsToken(clientCredentialsConfig)\n let tokenResponse = await promise\n if (tokenResponse.isExpired) {\n promise = getClientCredentialsToken(clientCredentialsConfig)\n tokenResponse = await promise\n }\n return {\n headers: {\n authorization: `Bearer ${tokenResponse.access_token}`,\n },\n }\n })\n}\n\nconst httpLink = (url: string) =>\n createHttpLink({\n uri: url,\n })\n\nexport const createTestClient = (\n url: string,\n accessToken?: string,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([bearerTokenLink(accessToken), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n\nexport const createTestClientWithClientCredentials = (\n url: string,\n clientCredentialsConfig: ClientCredentialsConfig,\n options?: Partial<ApolloClientOptions<NormalizedCacheObject>>,\n): ApolloClient<NormalizedCacheObject> =>\n new ApolloClient({\n link: from([clientCredentialsLink(clientCredentialsConfig), httpLink(url)]),\n cache: new InMemoryCache(),\n defaultOptions: {\n query: {\n errorPolicy: 'all',\n },\n },\n ...options,\n })\n"],"names":[],"mappings":";;;;;AASA,MAAM,eAAe,GAAG,CAAC,WAAoB,KAC3C,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAI;AAC5B,IAAA,IAAI,WAAW;QACb,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,GAAG,OAAO;gBACV,aAAa,EAAE,CAAA,OAAA,EAAU,WAAW,CAAA,CAAE;AACvC,aAAA;SACF;IACH,OAAO;QACL,OAAO;KACR;AACH,CAAC,CAAC;AAEJ,MAAM,qBAAqB,GAAG,CAAC,uBAAgD,KAAI;AACjF,IAAA,IAAI,OAAiD;AACrD,IAAA,OAAO,UAAU,CAAC,YAAW;AAC3B,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,GAAG,yBAAyB,CAAC,uBAAuB,CAAC;AAC1E,QAAA,IAAI,aAAa,GAAG,MAAM,OAAO;AACjC,QAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,OAAO,GAAG,yBAAyB,CAAC,uBAAuB,CAAC;YAC5D,aAAa,GAAG,MAAM,OAAO;QAC/B;QACA,OAAO;AACL,YAAA,OAAO,EAAE;AACP,gBAAA,aAAa,EAAE,CAAA,OAAA,EAAU,aAAa,CAAC,YAAY,CAAA,CAAE;AACtD,aAAA;SACF;AACH,IAAA,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,GAAW,KAC3B,cAAc,CAAC;AACb,IAAA,GAAG,EAAE,GAAG;AACT,CAAA,CAAC;AAEG,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,WAAoB,EACpB,OAA6D,KAE7D,IAAI,YAAY,CAAC;AACf,IAAA,IAAI,EAAE,IAAI,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,IAAI,aAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;AAEI,MAAM,qCAAqC,GAAG,CACnD,GAAW,EACX,uBAAgD,EAChD,OAA6D,KAE7D,IAAI,YAAY,CAAC;AACf,IAAA,IAAI,EAAE,IAAI,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,KAAK,EAAE,IAAI,aAAa,EAAE;AAC1B,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,KAAK;AACnB,SAAA;AACF,KAAA;AACD,IAAA,GAAG,OAAO;AACX,CAAA;;;;"}
package/utils.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export declare const isIntrospectionQuery: (query?: string) => boolean | undefined;
2
2
  export declare const isNil: (value: unknown) => value is null | undefined;
3
- export declare const isNotNil: <T>(value: T) => value is Exclude<T, null | undefined>;
3
+ export declare const isNotNil: <T>(value: T) => value is Exclude<T, undefined | null>;
package/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["export const isIntrospectionQuery = (query?: string) => query?.includes('__schema')\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined\nexport const isNotNil = <T>(value: T): value is Exclude<T, undefined | null> => !isNil(value)\n"],"names":[],"mappings":";;AAAO,MAAM,oBAAoB,GAAG,CAAC,KAAc,KAAK,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAC;AACtE,MAAA,KAAK,GAAG,CAAC,KAAc,KAAgC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,UAAS;AAClG,MAAM,QAAQ,GAAG,CAAI,KAAQ,KAA4C,CAAC,KAAK,CAAC,KAAK;;;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["export const isIntrospectionQuery = (query?: string) => query?.includes('__schema')\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined\nexport const isNotNil = <T>(value: T): value is Exclude<T, undefined | null> => !isNil(value)\n"],"names":[],"mappings":";;AAAO,MAAM,oBAAoB,GAAG,CAAC,KAAc,KAAK,KAAK,EAAE,QAAQ,CAAC,UAAU;AAC3E,MAAM,KAAK,GAAG,CAAC,KAAc,KAAgC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;AACzF,MAAM,QAAQ,GAAG,CAAI,KAAQ,KAA4C,CAAC,KAAK,CAAC,KAAK;;;;;;"}
package/utils.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../src/utils.ts"],"sourcesContent":["export const isIntrospectionQuery = (query?: string) => query?.includes('__schema')\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined\nexport const isNotNil = <T>(value: T): value is Exclude<T, undefined | null> => !isNil(value)\n"],"names":[],"mappings":"AAAO,MAAM,oBAAoB,GAAG,CAAC,KAAc,KAAK,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAC;AACtE,MAAA,KAAK,GAAG,CAAC,KAAc,KAAgC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,UAAS;AAClG,MAAM,QAAQ,GAAG,CAAI,KAAQ,KAA4C,CAAC,KAAK,CAAC,KAAK;;;;"}
1
+ {"version":3,"file":"utils.mjs","sources":["../src/utils.ts"],"sourcesContent":["export const isIntrospectionQuery = (query?: string) => query?.includes('__schema')\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined\nexport const isNotNil = <T>(value: T): value is Exclude<T, undefined | null> => !isNil(value)\n"],"names":[],"mappings":"AAAO,MAAM,oBAAoB,GAAG,CAAC,KAAc,KAAK,KAAK,EAAE,QAAQ,CAAC,UAAU;AAC3E,MAAM,KAAK,GAAG,CAAC,KAAc,KAAgC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;AACzF,MAAM,QAAQ,GAAG,CAAI,KAAQ,KAA4C,CAAC,KAAK,CAAC,KAAK;;;;"}