Skip to content

Commit

Permalink
fix: remove explicit type for GraphQLScalarType (#1920)
Browse files Browse the repository at this point in the history
Removing the explicit type helps with type inference. For example

Before this change `GraphQLDate` is of type `GraphQLScalarType<unknown, unknown>`
After this change `GraphQLDate` is of type `GraphQLScalarType<Date, string>`

The alternative to this is to duplicate the types from the `GraphQLScalarTypeConfig`
By adding the `TInternal` and `TExternal` generics to the explicit type

These types are useful when adding scalars with a code first apporach such as
in @pothos/core where scalar types are defined for the `SchemaBuilder`

Co-authored-by: James Macfie <[email protected]>
  • Loading branch information
Liam-Tait and jamesmacfie authored May 18, 2023
1 parent 12ed1b5 commit 0fb119a
Show file tree
Hide file tree
Showing 63 changed files with 518 additions and 286 deletions.
9 changes: 5 additions & 4 deletions src/scalars/AccountNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const validate = (account: unknown, ast?: ValueNode): string => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}

Expand All @@ -28,7 +28,7 @@ const validate = (account: unknown, ast?: ValueNode): string => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}

Expand All @@ -38,7 +38,8 @@ const validate = (account: unknown, ast?: ValueNode): string => {
export const GraphQLAccountNumberConfig: GraphQLScalarTypeConfig<string, string> = {
name: 'AccountNumber',
description:
'Banking account number is a string of 5 to 17 alphanumeric values for ' + 'representing an generic account number',
'Banking account number is a string of 5 to 17 alphanumeric values for ' +
'representing an generic account number',

serialize(value: unknown) {
return validate(value);
Expand Down Expand Up @@ -67,4 +68,4 @@ export const GraphQLAccountNumberConfig: GraphQLScalarTypeConfig<string, string>
},
};

export const GraphQLAccountNumber: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLAccountNumberConfig);
export const GraphQLAccountNumber = /*#__PURE__*/ new GraphQLScalarType(GraphQLAccountNumberConfig);
4 changes: 1 addition & 3 deletions src/scalars/BigInt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,4 @@ export const GraphQLBigIntConfig: GraphQLScalarTypeConfig<
},
};

export const GraphQLBigInt: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(
GraphQLBigIntConfig,
);
export const GraphQLBigInt = /*#__PURE__*/ new GraphQLScalarType(GraphQLBigIntConfig);
75 changes: 45 additions & 30 deletions src/scalars/Byte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ function hexValidator(value: string) {
// into smaller pieces to avoid this issue.
if (value.length > 8) {
let parsedString = '';
for (let startIndex = 0, endIndex = 8; startIndex < value.length; startIndex += 8, endIndex += 8) {
for (
let startIndex = 0, endIndex = 8;
startIndex < value.length;
startIndex += 8, endIndex += 8
) {
parsedString += parseInt(value.slice(startIndex, endIndex), 16).toString(16);
}
return parsedString === sanitizedValue;
Expand All @@ -35,7 +39,7 @@ function validate(value: Buffer | string | BufferJson, ast?: ValueNode) {
? {
nodes: ast,
}
: undefined
: undefined,
);
}
if (typeof value === 'string') {
Expand All @@ -48,7 +52,7 @@ function validate(value: Buffer | string | BufferJson, ast?: ValueNode) {
? {
nodes: ast,
}
: undefined
: undefined,
);
}
return global.Buffer.from(value, isHex ? 'hex' : 'base64');
Expand All @@ -60,38 +64,49 @@ function validate(value: Buffer | string | BufferJson, ast?: ValueNode) {
function parseObject(ast: ObjectValueNode) {
const key = ast.fields[0].value;
const value = ast.fields[1].value;
if (ast.fields.length === 2 && key.kind === Kind.STRING && key.value === 'Buffer' && value.kind === Kind.LIST) {
return global.Buffer.from(value.values.map((astValue: IntValueNode) => parseInt(astValue.value)));
if (
ast.fields.length === 2 &&
key.kind === Kind.STRING &&
key.value === 'Buffer' &&
value.kind === Kind.LIST
) {
return global.Buffer.from(
value.values.map((astValue: IntValueNode) => parseInt(astValue.value)),
);
}
throw createGraphQLError(`Value is not a JSON representation of Buffer: ${print(ast)}`, {
nodes: [ast],
});
}

export const GraphQLByteConfig: GraphQLScalarTypeConfig<Buffer | string | BufferJson, Buffer> = /*#__PURE__*/ {
name: 'Byte',
description: 'The `Byte` scalar type represents byte value as a Buffer',
serialize: validate,
parseValue: validate,
parseLiteral(ast: ASTNode) {
switch (ast.kind) {
case Kind.STRING:
return validate(ast.value, ast);
case Kind.OBJECT:
return parseObject(ast);
default:
throw createGraphQLError(`Can only parse base64 or hex encoded strings as Byte, but got a: ${ast.kind}`, {
nodes: [ast],
});
}
},
extensions: {
codegenScalarType: 'Buffer | string',
jsonSchema: {
type: 'string',
format: 'byte',
export const GraphQLByteConfig: GraphQLScalarTypeConfig<Buffer | string | BufferJson, Buffer> =
/*#__PURE__*/ {
name: 'Byte',
description: 'The `Byte` scalar type represents byte value as a Buffer',
serialize: validate,
parseValue: validate,
parseLiteral(ast: ASTNode) {
switch (ast.kind) {
case Kind.STRING:
return validate(ast.value, ast);
case Kind.OBJECT:
return parseObject(ast);
default:
throw createGraphQLError(
`Can only parse base64 or hex encoded strings as Byte, but got a: ${ast.kind}`,
{
nodes: [ast],
},
);
}
},
extensions: {
codegenScalarType: 'Buffer | string',
jsonSchema: {
type: 'string',
format: 'byte',
},
},
},
};
};

export const GraphQLByte: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLByteConfig);
export const GraphQLByte = /*#__PURE__*/ new GraphQLScalarType(GraphQLByteConfig);
17 changes: 10 additions & 7 deletions src/scalars/CountryCode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Kind, GraphQLScalarType, ValueNode } from 'graphql';
import { GraphQLScalarType, Kind, ValueNode } from 'graphql';
import { createGraphQLError } from '../error.js';

const COUNTRY_CODE_REGEX =
Expand All @@ -12,7 +12,7 @@ const validate = (value: any, ast?: ValueNode) => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}

Expand All @@ -23,13 +23,13 @@ const validate = (value: any, ast?: ValueNode) => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}
return value;
};

export const GraphQLCountryCode: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType({
export const GraphQLCountryCode = /*#__PURE__*/ new GraphQLScalarType({
name: 'CountryCode',
description: 'A country code as defined by ISO 3166-1 alpha-2',
serialize(value) {
Expand All @@ -42,9 +42,12 @@ export const GraphQLCountryCode: GraphQLScalarType = /*#__PURE__*/ new GraphQLSc

parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw createGraphQLError(`Can only validate strings as country codes but got a: ${ast.kind}`, {
nodes: [ast],
});
throw createGraphQLError(
`Can only validate strings as country codes but got a: ${ast.kind}`,
{
nodes: [ast],
},
);
}
return validate(ast.value, ast);
},
Expand Down
8 changes: 4 additions & 4 deletions src/scalars/Cuid.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Kind, GraphQLScalarType, GraphQLScalarTypeConfig, ValueNode } from 'graphql';
import { GraphQLScalarType, GraphQLScalarTypeConfig, Kind, ValueNode } from 'graphql';
import { createGraphQLError } from '../error.js';

const CUID_REGEX = /^c[^\s-]{8,}$/i;
Expand All @@ -11,7 +11,7 @@ const validate = (value: any, ast?: ValueNode) => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}

Expand All @@ -22,7 +22,7 @@ const validate = (value: any, ast?: ValueNode) => {
? {
nodes: ast,
}
: undefined
: undefined,
);
}

Expand Down Expand Up @@ -63,4 +63,4 @@ export const GraphQLCuidConfig = /*#__PURE__*/ {
},
} as GraphQLScalarTypeConfig<string, string>;

export const GraphQLCuid: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLCuidConfig);
export const GraphQLCuid = /*#__PURE__*/ new GraphQLScalarType(GraphQLCuidConfig);
13 changes: 9 additions & 4 deletions src/scalars/Currency.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Kind, GraphQLScalarType, GraphQLScalarTypeConfig, ASTNode } from 'graphql';
import { ASTNode, GraphQLScalarType, GraphQLScalarTypeConfig, Kind } from 'graphql';
import { createGraphQLError } from '../error.js';

const CURRENCY_REGEX =
Expand All @@ -10,7 +10,10 @@ const validate = (value: any, ast?: ASTNode) => {
}

if (!CURRENCY_REGEX.test(value)) {
throw createGraphQLError(`Value is not a valid currency value: ${value}`, ast ? { nodes: ast } : undefined);
throw createGraphQLError(
`Value is not a valid currency value: ${value}`,
ast ? { nodes: ast } : undefined,
);
}

return value;
Expand All @@ -33,7 +36,9 @@ export const GraphQLCurrencyConfig = /*#__PURE__*/ {

parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw createGraphQLError(`Can only validate strings as a currency but got a: ${ast.kind}`, { nodes: ast });
throw createGraphQLError(`Can only validate strings as a currency but got a: ${ast.kind}`, {
nodes: ast,
});
}

return validate(ast.value, ast);
Expand All @@ -51,4 +56,4 @@ export const GraphQLCurrencyConfig = /*#__PURE__*/ {
},
} as GraphQLScalarTypeConfig<string, string>;

export const GraphQLCurrency: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLCurrencyConfig);
export const GraphQLCurrency = /*#__PURE__*/ new GraphQLScalarType(GraphQLCurrencyConfig);
13 changes: 9 additions & 4 deletions src/scalars/DID.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GraphQLScalarType, Kind, GraphQLScalarTypeConfig, ASTNode } from 'graphql';
import { ASTNode, GraphQLScalarType, GraphQLScalarTypeConfig, Kind } from 'graphql';
import { createGraphQLError } from '../error.js';

// See: https://www.w3.org/TR/2021/PR-did-core-20210803/#did-syntax
Expand All @@ -11,7 +11,10 @@ const validate = (value: any, ast?: ASTNode) => {
}

if (!DID_REGEX.test(value)) {
throw createGraphQLError(`Value is not a valid DID: ${value}`, ast ? { nodes: ast } : undefined);
throw createGraphQLError(
`Value is not a valid DID: ${value}`,
ast ? { nodes: ast } : undefined,
);
}

return value;
Expand All @@ -31,7 +34,9 @@ export const GraphQLDIDConfig = {

parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw createGraphQLError(`Can only validate strings as DID but got a: ${ast.kind}`, { nodes: ast });
throw createGraphQLError(`Can only validate strings as DID but got a: ${ast.kind}`, {
nodes: ast,
});
}

return validate(ast.value, ast);
Expand All @@ -49,4 +54,4 @@ export const GraphQLDIDConfig = {
},
} as GraphQLScalarTypeConfig<string, string>;

export const GraphQLDID: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLDIDConfig);
export const GraphQLDID = /*#__PURE__*/ new GraphQLScalarType(GraphQLDIDConfig);
4 changes: 1 addition & 3 deletions src/scalars/EmailAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,4 @@ export const GraphQLEmailAddressConfig = /*#__PURE__*/ {
},
} as GraphQLScalarTypeConfig<string, string>;

export const GraphQLEmailAddress: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(
GraphQLEmailAddressConfig,
);
export const GraphQLEmailAddress = /*#__PURE__*/ new GraphQLScalarType(GraphQLEmailAddressConfig);
2 changes: 1 addition & 1 deletion src/scalars/GUID.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export const GraphQLGUIDConfig = /*#__PURE__*/ Object.assign({}, GraphQLUUIDConf
name: 'GUID',
});

export const GraphQLGUID: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLGUIDConfig);
export const GraphQLGUID = /*#__PURE__*/ new GraphQLScalarType(GraphQLGUIDConfig);
19 changes: 13 additions & 6 deletions src/scalars/HSL.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { Kind, GraphQLScalarType, GraphQLScalarTypeConfig, ASTNode } from 'graphql';
import { ASTNode, GraphQLScalarType, GraphQLScalarTypeConfig, Kind } from 'graphql';
import { createGraphQLError } from '../error.js';

const HSL_REGEX = /^hsl\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*\)$/;
const HSL_REGEX =
/^hsl\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*\)$/;

const validate = (value: any, ast?: ASTNode) => {
if (typeof value !== 'string') {
throw createGraphQLError(`Value is not string: ${value}`, ast ? { nodes: ast } : undefined);
}

if (!HSL_REGEX.test(value)) {
throw createGraphQLError(`Value is not a valid HSL color: ${value}`, ast ? { nodes: ast } : undefined);
throw createGraphQLError(
`Value is not a valid HSL color: ${value}`,
ast ? { nodes: ast } : undefined,
);
}

return value;
};

const specifiedByURL = 'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()_and_hsla()';
const specifiedByURL =
'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()_and_hsla()';

export const GraphQLHSLConfig: GraphQLScalarTypeConfig<string, string> = /*#__PURE__*/ {
name: `HSL`,
Expand All @@ -32,7 +37,9 @@ export const GraphQLHSLConfig: GraphQLScalarTypeConfig<string, string> = /*#__PU

parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw createGraphQLError(`Can only validate strings as HSL colors but got a: ${ast.kind}`, { nodes: ast });
throw createGraphQLError(`Can only validate strings as HSL colors but got a: ${ast.kind}`, {
nodes: ast,
});
}

return validate(ast.value, ast);
Expand All @@ -50,4 +57,4 @@ export const GraphQLHSLConfig: GraphQLScalarTypeConfig<string, string> = /*#__PU
},
} as GraphQLScalarTypeConfig<string, string>;

export const GraphQLHSL: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLHSLConfig);
export const GraphQLHSL = /*#__PURE__*/ new GraphQLScalarType(GraphQLHSLConfig);
13 changes: 9 additions & 4 deletions src/scalars/HSLA.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Kind, GraphQLScalarType, ASTNode } from 'graphql';
import { ASTNode, GraphQLScalarType, Kind } from 'graphql';
import { createGraphQLError } from '../error.js';

const HSLA_REGEX =
Expand All @@ -10,13 +10,16 @@ const validate = (value: any, ast?: ASTNode) => {
}

if (!HSLA_REGEX.test(value)) {
throw createGraphQLError(`Value is not a valid HSLA color: ${value}`, ast ? { nodes: ast } : undefined);
throw createGraphQLError(
`Value is not a valid HSLA color: ${value}`,
ast ? { nodes: ast } : undefined,
);
}

return value;
};

export const GraphQLHSLA: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType({
export const GraphQLHSLA = /*#__PURE__*/ new GraphQLScalarType({
name: `HSLA`,

description: `A field whose value is a CSS HSLA color: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()_and_hsla().`,
Expand All @@ -31,7 +34,9 @@ export const GraphQLHSLA: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarTyp

parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw createGraphQLError(`Can only validate strings as HSLA colors but got a: ${ast.kind}`, { nodes: ast });
throw createGraphQLError(`Can only validate strings as HSLA colors but got a: ${ast.kind}`, {
nodes: ast,
});
}

return validate(ast.value, ast);
Expand Down
Loading

0 comments on commit 0fb119a

Please sign in to comment.