@makerx/graphql-core 2.1.0 → 2.2.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 → User.cjs} +6 -6
- package/User.d.ts +1 -2
- package/User.mjs +47 -0
- package/{context.js → context.cjs} +12 -15
- package/context.d.ts +1 -2
- package/context.mjs +74 -0
- package/index.cjs +29 -0
- package/index.d.ts +0 -1
- package/index.mjs +9 -0
- package/{logging.js → logging.cjs} +18 -21
- package/logging.d.ts +4 -4
- package/logging.mjs +43 -0
- package/models.d.ts +0 -1
- package/package.json +17 -10
- package/{schema-util.js → schema-util.cjs} +6 -6
- package/schema-util.d.ts +1 -2
- package/schema-util.mjs +28 -0
- package/{shield.js → shield.cjs} +10 -10
- package/shield.d.ts +3 -4
- package/shield.mjs +48 -0
- package/subscriptions/{context.js → context.cjs} +14 -14
- package/subscriptions/context.d.ts +1 -2
- package/subscriptions/context.mjs +61 -0
- package/subscriptions/index.d.ts +0 -1
- package/subscriptions/{server.js → server.cjs} +23 -26
- package/subscriptions/server.d.ts +4 -5
- package/subscriptions/server.mjs +86 -0
- package/subscriptions/{utils.js → utils.cjs} +4 -5
- package/subscriptions/utils.d.ts +0 -1
- package/subscriptions/utils.mjs +20 -0
- package/testing.d.ts +6 -6
- package/utils.cjs +9 -0
- package/utils.d.ts +0 -1
- package/utils.mjs +5 -0
- package/User.d.ts.map +0 -1
- package/User.js.map +0 -1
- package/context.d.ts.map +0 -1
- package/context.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js +0 -25
- package/index.js.map +0 -1
- package/logging.d.ts.map +0 -1
- package/logging.js.map +0 -1
- package/models.d.ts.map +0 -1
- package/models.js +0 -3
- package/models.js.map +0 -1
- package/schema-util.d.ts.map +0 -1
- package/schema-util.js.map +0 -1
- package/shield.d.ts.map +0 -1
- package/shield.js.map +0 -1
- package/subscriptions/context.d.ts.map +0 -1
- package/subscriptions/context.js.map +0 -1
- package/subscriptions/index.d.ts.map +0 -1
- package/subscriptions/index.js +0 -22
- package/subscriptions/index.js.map +0 -1
- package/subscriptions/server.d.ts.map +0 -1
- package/subscriptions/server.js.map +0 -1
- package/subscriptions/utils.d.ts.map +0 -1
- package/subscriptions/utils.js.map +0 -1
- package/testing.d.ts.map +0 -1
- package/testing.js +0 -77
- package/testing.js.map +0 -1
- package/utils.d.ts.map +0 -1
- package/utils.js +0 -10
- package/utils.js.map +0 -1
package/{User.js → User.cjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('./utils.cjs');
|
|
4
|
+
|
|
5
5
|
class User {
|
|
6
6
|
constructor(claims, accessToken) {
|
|
7
7
|
this.claims = claims;
|
|
@@ -17,7 +17,7 @@ class User {
|
|
|
17
17
|
get name() {
|
|
18
18
|
if (this.claims.name)
|
|
19
19
|
return this.claims.name;
|
|
20
|
-
const otherNames = [this.claims.given_name, this.claims.family_name].filter(
|
|
20
|
+
const otherNames = [this.claims.given_name, this.claims.family_name].filter(utils.isNotNil);
|
|
21
21
|
if (otherNames.length > 0)
|
|
22
22
|
return otherNames.join(' ');
|
|
23
23
|
return undefined;
|
|
@@ -45,5 +45,5 @@ class User {
|
|
|
45
45
|
return first;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
|
|
48
49
|
exports.User = User;
|
|
49
|
-
//# sourceMappingURL=User.js.map
|
package/User.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JwtPayload } from './context';
|
|
1
|
+
import type { JwtPayload } from './context';
|
|
2
2
|
export declare class User {
|
|
3
3
|
readonly token: string;
|
|
4
4
|
readonly claims: JwtPayload;
|
|
@@ -11,4 +11,3 @@ export declare class User {
|
|
|
11
11
|
private first;
|
|
12
12
|
private firstOrThrow;
|
|
13
13
|
}
|
|
14
|
-
//# sourceMappingURL=User.d.ts.map
|
package/User.mjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isNotNil } from './utils.mjs';
|
|
2
|
+
|
|
3
|
+
class User {
|
|
4
|
+
constructor(claims, accessToken) {
|
|
5
|
+
this.claims = claims;
|
|
6
|
+
this.token = accessToken;
|
|
7
|
+
}
|
|
8
|
+
get email() {
|
|
9
|
+
return (this.claims.email ??
|
|
10
|
+
this.claims.emails?.[0] ??
|
|
11
|
+
this.claims.preferred_username ??
|
|
12
|
+
this.claims.unique_name ??
|
|
13
|
+
this.claims.upn);
|
|
14
|
+
}
|
|
15
|
+
get name() {
|
|
16
|
+
if (this.claims.name)
|
|
17
|
+
return this.claims.name;
|
|
18
|
+
const otherNames = [this.claims.given_name, this.claims.family_name].filter(isNotNil);
|
|
19
|
+
if (otherNames.length > 0)
|
|
20
|
+
return otherNames.join(' ');
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
get id() {
|
|
24
|
+
return this.firstOrThrow('oid', 'sub');
|
|
25
|
+
}
|
|
26
|
+
get scopes() {
|
|
27
|
+
return this.claims.scp ? this.claims.scp.split(' ') : [];
|
|
28
|
+
}
|
|
29
|
+
get roles() {
|
|
30
|
+
return this.claims.roles ?? [];
|
|
31
|
+
}
|
|
32
|
+
first(...claims) {
|
|
33
|
+
for (const key of claims) {
|
|
34
|
+
if (this.claims[key])
|
|
35
|
+
return this.claims[key];
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
firstOrThrow(...claims) {
|
|
40
|
+
const first = this.first(...claims);
|
|
41
|
+
if (!first)
|
|
42
|
+
throw new Error(`claims do not include any of: ${claims.join(', ')}`);
|
|
43
|
+
return first;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { User };
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const crypto_1 = require("crypto");
|
|
8
|
-
const lodash_pick_1 = __importDefault(require("lodash.pick"));
|
|
9
|
-
const User_1 = require("./User");
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var lodash = require('lodash');
|
|
5
|
+
var User = require('./User.cjs');
|
|
6
|
+
|
|
10
7
|
const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }) => {
|
|
11
8
|
// the function that creates the GraphQL context
|
|
12
9
|
return async (input) => {
|
|
13
10
|
const { req, claims, context } = input;
|
|
14
11
|
// build base request info from the request
|
|
15
12
|
const baseRequestInfo = {
|
|
16
|
-
requestId: req.headers['x-request-id']?.toString() ??
|
|
13
|
+
requestId: req.headers['x-request-id']?.toString() ?? crypto.randomUUID(),
|
|
17
14
|
protocol: req.protocol,
|
|
18
15
|
host: req.hostname ?? '',
|
|
19
16
|
method: req.method ?? '',
|
|
@@ -48,10 +45,10 @@ const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog,
|
|
|
48
45
|
const requestLoggerMetadata = {};
|
|
49
46
|
// add request info to log
|
|
50
47
|
if (requestInfoToLog?.length)
|
|
51
|
-
requestLoggerMetadata.request =
|
|
48
|
+
requestLoggerMetadata.request = lodash.pick(requestInfo, requestInfoToLog);
|
|
52
49
|
// add user claims to log
|
|
53
50
|
if (claims && claimsToLog?.length)
|
|
54
|
-
requestLoggerMetadata.user =
|
|
51
|
+
requestLoggerMetadata.user = lodash.pick(claims, claimsToLog);
|
|
55
52
|
// build the request logger
|
|
56
53
|
logger = requestLogger(requestLoggerMetadata);
|
|
57
54
|
}
|
|
@@ -69,12 +66,12 @@ const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog,
|
|
|
69
66
|
return augmentedGraphQLContext;
|
|
70
67
|
};
|
|
71
68
|
};
|
|
72
|
-
exports.createContextFactory = createContextFactory;
|
|
73
69
|
const defaultCreateUser = ({ req, claims }) => {
|
|
74
70
|
if (!claims)
|
|
75
71
|
return Promise.resolve(undefined);
|
|
76
72
|
const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : '';
|
|
77
|
-
return Promise.resolve(new
|
|
73
|
+
return Promise.resolve(new User.User(claims, accessToken));
|
|
78
74
|
};
|
|
75
|
+
|
|
76
|
+
exports.createContextFactory = createContextFactory;
|
|
79
77
|
exports.defaultCreateUser = defaultCreateUser;
|
|
80
|
-
//# sourceMappingURL=context.js.map
|
package/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Logger } from '@makerx/node-common';
|
|
1
|
+
import type { Logger } from '@makerx/node-common';
|
|
2
2
|
import type { Request } from 'express';
|
|
3
3
|
import { User } from './User';
|
|
4
4
|
export interface GraphQLContext<TLogger extends Logger = Logger, TRequestInfo extends BaseRequestInfo = RequestInfo, TUser = User | undefined> {
|
|
@@ -68,4 +68,3 @@ export interface CreateContextConfig<TContext extends AnyGraphqlContext = GraphQ
|
|
|
68
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
70
|
export declare const defaultCreateUser: CreateUser<User | undefined>;
|
|
71
|
-
//# sourceMappingURL=context.d.ts.map
|
package/context.mjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { pick } from 'lodash';
|
|
3
|
+
import { User } from './User.mjs';
|
|
4
|
+
|
|
5
|
+
const createContextFactory = ({ requestLogger, augmentRequestInfo, claimsToLog, createUser, requestInfoToLog, augmentContext, }) => {
|
|
6
|
+
// the function that creates the GraphQL context
|
|
7
|
+
return async (input) => {
|
|
8
|
+
const { req, claims, context } = input;
|
|
9
|
+
// 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
|
+
};
|
|
22
|
+
// add lambda info from the context, if present
|
|
23
|
+
let lambdaRequestInfo;
|
|
24
|
+
if (context) {
|
|
25
|
+
const { awsRequestId, functionName } = context;
|
|
26
|
+
lambdaRequestInfo = {
|
|
27
|
+
awsRequestId,
|
|
28
|
+
functionName,
|
|
29
|
+
...baseRequestInfo,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// augment request info with the supplied function, if present
|
|
33
|
+
let requestInfo = lambdaRequestInfo ?? baseRequestInfo;
|
|
34
|
+
if (augmentRequestInfo)
|
|
35
|
+
requestInfo = {
|
|
36
|
+
...requestInfo,
|
|
37
|
+
...augmentRequestInfo(input),
|
|
38
|
+
};
|
|
39
|
+
// create request logger
|
|
40
|
+
let logger;
|
|
41
|
+
if (typeof requestLogger === 'function') {
|
|
42
|
+
// build request logger metadata
|
|
43
|
+
const requestLoggerMetadata = {};
|
|
44
|
+
// add request info to log
|
|
45
|
+
if (requestInfoToLog?.length)
|
|
46
|
+
requestLoggerMetadata.request = pick(requestInfo, requestInfoToLog);
|
|
47
|
+
// add user claims to log
|
|
48
|
+
if (claims && claimsToLog?.length)
|
|
49
|
+
requestLoggerMetadata.user = pick(claims, claimsToLog);
|
|
50
|
+
// build the request logger
|
|
51
|
+
logger = requestLogger(requestLoggerMetadata);
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
logger = requestLogger;
|
|
55
|
+
const graphqlContext = {
|
|
56
|
+
requestInfo,
|
|
57
|
+
logger,
|
|
58
|
+
user: createUser ? await createUser(input) : undefined,
|
|
59
|
+
started: Date.now(),
|
|
60
|
+
};
|
|
61
|
+
const augmentedGraphQLContext = augmentContext
|
|
62
|
+
? { ...graphqlContext, ...(await augmentContext(graphqlContext)) }
|
|
63
|
+
: graphqlContext;
|
|
64
|
+
return augmentedGraphQLContext;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
const defaultCreateUser = ({ req, claims }) => {
|
|
68
|
+
if (!claims)
|
|
69
|
+
return Promise.resolve(undefined);
|
|
70
|
+
const accessToken = req.headers.authorization?.startsWith('Bearer') ? req.headers.authorization?.substring(7) ?? '' : '';
|
|
71
|
+
return Promise.resolve(new User(claims, accessToken));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export { createContextFactory, defaultCreateUser };
|
package/index.cjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var context = require('./context.cjs');
|
|
4
|
+
var User = require('./User.cjs');
|
|
5
|
+
var utils = require('./utils.cjs');
|
|
6
|
+
var logging = require('./logging.cjs');
|
|
7
|
+
var schemaUtil = require('./schema-util.cjs');
|
|
8
|
+
var shield = require('./shield.cjs');
|
|
9
|
+
var utils$1 = require('./subscriptions/utils.cjs');
|
|
10
|
+
var context$1 = require('./subscriptions/context.cjs');
|
|
11
|
+
var server = require('./subscriptions/server.cjs');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
exports.createContextFactory = context.createContextFactory;
|
|
16
|
+
exports.defaultCreateUser = context.defaultCreateUser;
|
|
17
|
+
exports.User = User.User;
|
|
18
|
+
exports.isIntrospectionQuery = utils.isIntrospectionQuery;
|
|
19
|
+
exports.isNil = utils.isNil;
|
|
20
|
+
exports.isNotNil = utils.isNotNil;
|
|
21
|
+
exports.logGraphQLOperation = logging.logGraphQLOperation;
|
|
22
|
+
exports.logSubscriptionOperation = logging.logSubscriptionOperation;
|
|
23
|
+
exports.requireExplicitResolversForScalars = schemaUtil.requireExplicitResolversForScalars;
|
|
24
|
+
exports.combineRuleWithAll = shield.combineRuleWithAll;
|
|
25
|
+
exports.createRule = shield.createRule;
|
|
26
|
+
exports.createShieldSchema = shield.createShieldSchema;
|
|
27
|
+
exports.extractTokenFromConnectionParams = utils$1.extractTokenFromConnectionParams;
|
|
28
|
+
exports.createSubscriptionContextFactory = context$1.createSubscriptionContextFactory;
|
|
29
|
+
exports.useSubscriptionsServer = server.useSubscriptionsServer;
|
package/index.d.ts
CHANGED
package/index.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { createContextFactory, defaultCreateUser } from './context.mjs';
|
|
2
|
+
export { User } from './User.mjs';
|
|
3
|
+
export { isIntrospectionQuery, isNil, isNotNil } from './utils.mjs';
|
|
4
|
+
export { logGraphQLOperation, logSubscriptionOperation } from './logging.mjs';
|
|
5
|
+
export { requireExplicitResolversForScalars } from './schema-util.mjs';
|
|
6
|
+
export { combineRuleWithAll, createRule, createShieldSchema } from './shield.mjs';
|
|
7
|
+
export { extractTokenFromConnectionParams } from './subscriptions/utils.mjs';
|
|
8
|
+
export { createSubscriptionContextFactory } from './subscriptions/context.mjs';
|
|
9
|
+
export { useSubscriptionsServer } from './subscriptions/server.mjs';
|
|
@@ -1,49 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const graphql_1 = require("graphql");
|
|
9
|
-
const lodash_omitby_1 = __importDefault(require("lodash.omitby"));
|
|
10
|
-
const utils_1 = require("./utils");
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var nodeCommon = require('@makerx/node-common');
|
|
4
|
+
var graphql = require('graphql');
|
|
5
|
+
var lodash = require('lodash');
|
|
6
|
+
var utils = require('./utils.cjs');
|
|
7
|
+
|
|
11
8
|
/**
|
|
12
9
|
* Logs a GraphQL operation in a consistent format with the option of including any additional data.
|
|
13
10
|
* Top level and result entries with null or undefined values will be omitted.
|
|
14
11
|
*/
|
|
15
12
|
const logGraphQLOperation = ({ message = 'GraphQL operation', started, type, operationName, query, variables, result, logger, logLevel = 'info', ...rest }) => {
|
|
16
|
-
const isIntrospection = query &&
|
|
17
|
-
if (
|
|
13
|
+
const isIntrospection = query && utils.isIntrospectionQuery(query);
|
|
14
|
+
if (nodeCommon.isLocalDev && isIntrospection)
|
|
18
15
|
return;
|
|
19
|
-
logger[logLevel](message,
|
|
16
|
+
logger[logLevel](message, lodash.omitBy({
|
|
20
17
|
type,
|
|
21
18
|
operationName,
|
|
22
19
|
query,
|
|
23
20
|
variables: variables && Object.keys(variables).length > 0 ? variables : undefined,
|
|
24
21
|
duration: started ? Date.now() - started : undefined,
|
|
25
|
-
result: result ?
|
|
22
|
+
result: result ? lodash.omitBy(result, utils.isNil) : undefined,
|
|
26
23
|
isIntrospectionQuery: isIntrospection || undefined,
|
|
27
|
-
...
|
|
28
|
-
},
|
|
24
|
+
...lodash.omitBy(rest, utils.isNil),
|
|
25
|
+
}, utils.isNil));
|
|
29
26
|
};
|
|
30
|
-
exports.logGraphQLOperation = logGraphQLOperation;
|
|
31
27
|
const logSubscriptionOperation = ({ args, result, message, logLevel, }) => {
|
|
32
28
|
const logger = args.contextValue.logger;
|
|
33
29
|
if (!logger)
|
|
34
30
|
return;
|
|
35
31
|
const { operationName, variableValues, document } = args;
|
|
36
32
|
const { data, ...resultWithoutData } = result ?? {};
|
|
37
|
-
|
|
33
|
+
logGraphQLOperation({
|
|
38
34
|
message,
|
|
39
|
-
type:
|
|
35
|
+
type: graphql.OperationTypeNode.SUBSCRIPTION,
|
|
40
36
|
operationName,
|
|
41
|
-
query:
|
|
37
|
+
query: graphql.print(document),
|
|
42
38
|
variables: variableValues,
|
|
43
39
|
result: resultWithoutData,
|
|
44
40
|
logger,
|
|
45
41
|
logLevel,
|
|
46
42
|
});
|
|
47
43
|
};
|
|
44
|
+
|
|
45
|
+
exports.logGraphQLOperation = logGraphQLOperation;
|
|
48
46
|
exports.logSubscriptionOperation = logSubscriptionOperation;
|
|
49
|
-
//# sourceMappingURL=logging.js.map
|
package/logging.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Logger } from '@makerx/node-common';
|
|
2
|
-
import { ExecutionArgs, GraphQLFormattedError
|
|
3
|
-
import {
|
|
1
|
+
import type { Logger } from '@makerx/node-common';
|
|
2
|
+
import type { ExecutionArgs, GraphQLFormattedError } from 'graphql';
|
|
3
|
+
import { OperationTypeNode } from 'graphql';
|
|
4
|
+
import type { ExecutionResult } from 'graphql-ws';
|
|
4
5
|
type LogFunction = Logger['info'];
|
|
5
6
|
export type LoggerLogFunctions<T extends Logger> = {
|
|
6
7
|
[Property in keyof T]: LogFunction;
|
|
@@ -76,4 +77,3 @@ export declare const logSubscriptionOperation: <TLogger extends Logger = Logger>
|
|
|
76
77
|
logLevel?: keyof TLogger | undefined;
|
|
77
78
|
}) => void;
|
|
78
79
|
export {};
|
|
79
|
-
//# sourceMappingURL=logging.d.ts.map
|
package/logging.mjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isLocalDev } from '@makerx/node-common';
|
|
2
|
+
import { OperationTypeNode, print } from 'graphql';
|
|
3
|
+
import { omitBy } from 'lodash';
|
|
4
|
+
import { isIntrospectionQuery, isNil } from './utils.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Logs a GraphQL operation in a consistent format with the option of including any additional data.
|
|
8
|
+
* Top level and result entries with null or undefined values will be omitted.
|
|
9
|
+
*/
|
|
10
|
+
const logGraphQLOperation = ({ message = 'GraphQL operation', started, type, operationName, query, variables, result, logger, logLevel = 'info', ...rest }) => {
|
|
11
|
+
const isIntrospection = query && isIntrospectionQuery(query);
|
|
12
|
+
if (isLocalDev && isIntrospection)
|
|
13
|
+
return;
|
|
14
|
+
logger[logLevel](message, omitBy({
|
|
15
|
+
type,
|
|
16
|
+
operationName,
|
|
17
|
+
query,
|
|
18
|
+
variables: variables && Object.keys(variables).length > 0 ? variables : undefined,
|
|
19
|
+
duration: started ? Date.now() - started : undefined,
|
|
20
|
+
result: result ? omitBy(result, isNil) : undefined,
|
|
21
|
+
isIntrospectionQuery: isIntrospection || undefined,
|
|
22
|
+
...omitBy(rest, isNil),
|
|
23
|
+
}, isNil));
|
|
24
|
+
};
|
|
25
|
+
const logSubscriptionOperation = ({ args, result, message, logLevel, }) => {
|
|
26
|
+
const logger = args.contextValue.logger;
|
|
27
|
+
if (!logger)
|
|
28
|
+
return;
|
|
29
|
+
const { operationName, variableValues, document } = args;
|
|
30
|
+
const { data, ...resultWithoutData } = result ?? {};
|
|
31
|
+
logGraphQLOperation({
|
|
32
|
+
message,
|
|
33
|
+
type: OperationTypeNode.SUBSCRIPTION,
|
|
34
|
+
operationName,
|
|
35
|
+
query: print(document),
|
|
36
|
+
variables: variableValues,
|
|
37
|
+
result: resultWithoutData,
|
|
38
|
+
logger,
|
|
39
|
+
logLevel,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { logGraphQLOperation, logSubscriptionOperation };
|
package/models.d.ts
CHANGED
|
@@ -2,4 +2,3 @@ export type Primitive = string | number | symbol | bigint | boolean | null | und
|
|
|
2
2
|
type ScalarPropsInternal<T, TKey extends keyof T, TAdditionalScalars = never> = TKey extends any ? T[TKey] extends Primitive | TAdditionalScalars ? TKey : never : never;
|
|
3
3
|
export type ScalarProps<T, TAdditionalScalars = never> = Pick<T, ScalarPropsInternal<T, keyof T, TAdditionalScalars>>;
|
|
4
4
|
export {};
|
|
5
|
-
//# sourceMappingURL=models.d.ts.map
|
package/package.json
CHANGED
|
@@ -2,13 +2,25 @@
|
|
|
2
2
|
"main": "index.js",
|
|
3
3
|
"types": "index.d.ts",
|
|
4
4
|
"name": "@makerx/graphql-core",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.2.0",
|
|
6
6
|
"private": false,
|
|
7
7
|
"description": "A set of core GraphQL utilities that MakerX uses to build GraphQL APIs",
|
|
8
8
|
"author": "MakerX",
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"module": "index.mjs",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./index.d.ts",
|
|
15
|
+
"module": "./index.mjs",
|
|
16
|
+
"import": "./index.mjs",
|
|
17
|
+
"require": "./index.cjs",
|
|
18
|
+
"default": "./index.mjs"
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
10
22
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
23
|
+
"node": ">=18.0"
|
|
12
24
|
},
|
|
13
25
|
"bugs": {
|
|
14
26
|
"url": "https://github.com/MakerXStudio/graphql-core/issues"
|
|
@@ -19,16 +31,15 @@
|
|
|
19
31
|
"url": "git+https://github.com/MakerXStudio/graphql-core.git"
|
|
20
32
|
},
|
|
21
33
|
"dependencies": {
|
|
22
|
-
"@makerx/node-common": "^1.
|
|
23
|
-
"lodash.omitby": "^4.6.0",
|
|
24
|
-
"lodash.pick": "^4.4.0"
|
|
34
|
+
"@makerx/node-common": "^1.4.0"
|
|
25
35
|
},
|
|
26
36
|
"peerDependencies": {
|
|
27
37
|
"@apollo/client": "*",
|
|
28
38
|
"express": "*",
|
|
39
|
+
"graphql": "*",
|
|
29
40
|
"graphql-shield": "*",
|
|
30
41
|
"graphql-ws": "*",
|
|
31
|
-
"
|
|
42
|
+
"lodash": "*",
|
|
32
43
|
"ws": "*"
|
|
33
44
|
},
|
|
34
45
|
"peerDependenciesMeta": {
|
|
@@ -41,9 +52,5 @@
|
|
|
41
52
|
"ws": {
|
|
42
53
|
"optional": true
|
|
43
54
|
}
|
|
44
|
-
},
|
|
45
|
-
"overrides": {
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
47
|
-
"@typescript-eslint/parser": "^6.0.0"
|
|
48
55
|
}
|
|
49
56
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var graphql = require('graphql');
|
|
4
|
+
|
|
5
5
|
/**
|
|
6
6
|
* It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in
|
|
7
7
|
* this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types
|
|
@@ -11,7 +11,7 @@ const graphql_1 = require("graphql");
|
|
|
11
11
|
*/
|
|
12
12
|
function requireExplicitResolversForScalars(schema, ...scalarsToIgnore) {
|
|
13
13
|
const testSymbol = Symbol('testSymbol');
|
|
14
|
-
const scalars = Object.values(schema.getTypeMap()).filter((t) => t instanceof
|
|
14
|
+
const scalars = Object.values(schema.getTypeMap()).filter((t) => t instanceof graphql.GraphQLScalarType);
|
|
15
15
|
for (const scalar of scalars) {
|
|
16
16
|
if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name))
|
|
17
17
|
continue;
|
|
@@ -26,5 +26,5 @@ function requireExplicitResolversForScalars(schema, ...scalarsToIgnore) {
|
|
|
26
26
|
"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.");
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
|
|
29
30
|
exports.requireExplicitResolversForScalars = requireExplicitResolversForScalars;
|
|
30
|
-
//# sourceMappingURL=schema-util.js.map
|
package/schema-util.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphQLSchema } from 'graphql';
|
|
1
|
+
import type { GraphQLSchema } from 'graphql';
|
|
2
2
|
/**
|
|
3
3
|
* It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in
|
|
4
4
|
* this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types
|
|
@@ -7,4 +7,3 @@ import { GraphQLSchema } from 'graphql';
|
|
|
7
7
|
* @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`
|
|
8
8
|
*/
|
|
9
9
|
export declare function requireExplicitResolversForScalars(schema: GraphQLSchema, ...scalarsToIgnore: string[]): void;
|
|
10
|
-
//# sourceMappingURL=schema-util.d.ts.map
|
package/schema-util.mjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { GraphQLScalarType } from 'graphql';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* It is possible to register a custom scalar with apollo server without defining an explicit resolver (a default resolver is used in
|
|
5
|
+
* this case), but it is rarely desirable. This function, when provided with your built schema, will ensure any registered scalar types
|
|
6
|
+
* provide at least a base level of validation by failing to parse a Symbol instance. The default resolver does not pass this test
|
|
7
|
+
* meaning any scalars that are falling back to the default resolver will fail.
|
|
8
|
+
* @param schema A schema object, the result of calling `makeExecutableSchema` from `@graphql-tools/schema`
|
|
9
|
+
*/
|
|
10
|
+
function requireExplicitResolversForScalars(schema, ...scalarsToIgnore) {
|
|
11
|
+
const testSymbol = Symbol('testSymbol');
|
|
12
|
+
const scalars = Object.values(schema.getTypeMap()).filter((t) => t instanceof GraphQLScalarType);
|
|
13
|
+
for (const scalar of scalars) {
|
|
14
|
+
if (scalar.name === 'Void' || scalar.name === 'JSON' || scalarsToIgnore.includes(scalar.name))
|
|
15
|
+
continue;
|
|
16
|
+
try {
|
|
17
|
+
scalar.parseValue(testSymbol);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// We expect that a good parser should throw when parsing a random symbol
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`Scalar ${scalar.name} does not appear to have an explicit resolver, or is not performing sufficient validation when parsing input. ` +
|
|
24
|
+
"If you're satisfied with this scalar you can ignore it in the call to `requireExplicitResolversForScalars`.");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { requireExplicitResolversForScalars };
|
package/{shield.js → shield.cjs}
RENAMED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const createRule = (logic, cache = 'strict') =>
|
|
6
|
-
exports.createRule = createRule;
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var graphqlShield = require('graphql-shield');
|
|
4
|
+
|
|
5
|
+
const createRule = (logic, cache = 'strict') => graphqlShield.rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx));
|
|
7
6
|
/**
|
|
8
7
|
* Combines a given rule with all existing defined rules using the provided combinator
|
|
9
8
|
* @param schema The existing shield schema with rules
|
|
@@ -22,7 +21,6 @@ function combineRuleWithAll(schema, rule, combinator) {
|
|
|
22
21
|
return [key, combineRuleWithAll(value, rule, combinator)];
|
|
23
22
|
}));
|
|
24
23
|
}
|
|
25
|
-
exports.combineRuleWithAll = combineRuleWithAll;
|
|
26
24
|
/**
|
|
27
25
|
* Creates graphql shield middleware making use of generics to type the definition of the rules.
|
|
28
26
|
* @param schema A mapping of schema objects to the shield rules that define the access to that object
|
|
@@ -42,11 +40,13 @@ exports.combineRuleWithAll = combineRuleWithAll;
|
|
|
42
40
|
*
|
|
43
41
|
* schema = applyMiddleware(schema, shieldSchema)
|
|
44
42
|
*/
|
|
45
|
-
function createShieldSchema(schema, fallbackRule =
|
|
46
|
-
return
|
|
43
|
+
function createShieldSchema(schema, fallbackRule = graphqlShield.allow) {
|
|
44
|
+
return graphqlShield.shield(schema, {
|
|
47
45
|
allowExternalErrors: true,
|
|
48
46
|
fallbackRule: fallbackRule,
|
|
49
47
|
});
|
|
50
48
|
}
|
|
49
|
+
|
|
50
|
+
exports.combineRuleWithAll = combineRuleWithAll;
|
|
51
|
+
exports.createRule = createRule;
|
|
51
52
|
exports.createShieldSchema = createShieldSchema;
|
|
52
|
-
//# sourceMappingURL=shield.js.map
|
package/shield.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { and, chain, or, race } from 'graphql-shield';
|
|
2
|
+
import type { ShieldRule } from 'graphql-shield/typings/types';
|
|
3
|
+
import type { Primitive } from './models';
|
|
4
4
|
type RuleCombinator = typeof chain | typeof race | typeof or | typeof and;
|
|
5
5
|
export declare const createRule: <TContext, TParent = unknown, TArgs = unknown>(logic: (parent: TParent, args: TArgs, ctx: TContext) => boolean | Promise<boolean> | Error, cache?: 'contextual' | 'strict') => import("graphql-shield/typings/rules").Rule;
|
|
6
6
|
/**
|
|
@@ -40,4 +40,3 @@ export type ShieldSchema<TResolver> = TResolver extends Primitive ? ShieldRule :
|
|
|
40
40
|
'*'?: ShieldRule;
|
|
41
41
|
};
|
|
42
42
|
export {};
|
|
43
|
-
//# sourceMappingURL=shield.d.ts.map
|
package/shield.mjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { rule, shield, allow } from 'graphql-shield';
|
|
2
|
+
|
|
3
|
+
const createRule = (logic, cache = 'strict') => rule({ cache })(async (parent, args, ctx) => logic(parent, args, ctx));
|
|
4
|
+
/**
|
|
5
|
+
* Combines a given rule with all existing defined rules using the provided combinator
|
|
6
|
+
* @param schema The existing shield schema with rules
|
|
7
|
+
* @param rule The rule to be combined with existing rules
|
|
8
|
+
* @param combinator The combinator to use. Eg. and | or | chain | race
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
*
|
|
12
|
+
* const updatedSchema = combineRuleWithAll(shieldSchema, rules.accountNotBlocked, chain)
|
|
13
|
+
*/
|
|
14
|
+
function combineRuleWithAll(schema, rule, combinator) {
|
|
15
|
+
return Object.fromEntries(Object.entries(schema).map(([key, value]) => {
|
|
16
|
+
if (value.constructor.name !== 'Object') {
|
|
17
|
+
return [key, combinator(rule, value)];
|
|
18
|
+
}
|
|
19
|
+
return [key, combineRuleWithAll(value, rule, combinator)];
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates graphql shield middleware making use of generics to type the definition of the rules.
|
|
24
|
+
* @param schema A mapping of schema objects to the shield rules that define the access to that object
|
|
25
|
+
* @param fallbackRule A fallback rule to apply to any object or property which doesn't have a defined rule.
|
|
26
|
+
*
|
|
27
|
+
* Usage:
|
|
28
|
+
* import { Resolvers } from '../generated/types'
|
|
29
|
+
*
|
|
30
|
+
* const shieldSchema = createShieldSchema<Resolvers>({
|
|
31
|
+
* Query: {
|
|
32
|
+
* getThings: allow,
|
|
33
|
+
* dontGetThings: deny,
|
|
34
|
+
* }
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* let schema = makeExecutableSchema({...})
|
|
38
|
+
*
|
|
39
|
+
* schema = applyMiddleware(schema, shieldSchema)
|
|
40
|
+
*/
|
|
41
|
+
function createShieldSchema(schema, fallbackRule = allow) {
|
|
42
|
+
return shield(schema, {
|
|
43
|
+
allowExternalErrors: true,
|
|
44
|
+
fallbackRule: fallbackRule,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { combineRuleWithAll, createRule, createShieldSchema };
|