Created
December 13, 2025 06:44
-
-
Save whoisYeshua/36ed2734435a8b43b6d56b30cbbe550b to your computer and use it in GitHub Desktop.
GraphQL custom scalars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "schema": "https://apollo-whoisyeshua-test.onrender.com", | |
| "documents": "**/*.{graphql,gql}" | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { readFileSync } from 'node:fs' | |
| import { resolve } from 'node:path' | |
| import { ApolloServer } from '@apollo/server' | |
| import { startStandaloneServer } from '@apollo/server/standalone' | |
| import { addMocksToSchema } from '@graphql-tools/mock' | |
| import { makeExecutableSchema } from '@graphql-tools/schema' | |
| import { bigintScalar } from './scalars/bigintScalar.js' | |
| import { dateScalar } from './scalars/dateScalar.js' | |
| const typeDefsPath = resolve('./schema.gql') | |
| const typeDefs = readFileSync(typeDefsPath).toString('utf-8') | |
| const resolvers = { | |
| Bigint: bigintScalar, | |
| Date: dateScalar, | |
| Query: { | |
| test: () => 'test2', | |
| age: () => Number.MAX_SAFE_INTEGER - 1, | |
| date: () => new Date(), | |
| }, | |
| } | |
| const mocks = { | |
| Int: () => 6, | |
| Float: () => 22.1, | |
| String: () => 'Hello', | |
| Date: () => new Date('2011', '11', '11'), | |
| Bigint: () => 3_000_000_000, | |
| } | |
| const server = new ApolloServer({ | |
| schema: addMocksToSchema({ | |
| schema: makeExecutableSchema({ typeDefs, resolvers }), | |
| preserveResolvers: true, | |
| mocks, | |
| }), | |
| introspection: true, | |
| }) | |
| const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }) | |
| console.log(`🚀 Server listening at: ${url}`) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "apollo-test", | |
| "type": "module", | |
| "scripts": { | |
| "build": "echo \"No build step currently\"", | |
| "start": "node index.js", | |
| "dev": "nodemon index.js", | |
| "test": "echo \"Error: no test specified\" && exit 1" | |
| }, | |
| "dependencies": { | |
| "@apollo/server": "^4.7.3", | |
| "graphql": "^16.6.0", | |
| "nodemon": "^2.0.22" | |
| }, | |
| "devDependencies": { | |
| "@graphql-tools/mock": "^9.0.0", | |
| "@graphql-tools/schema": "^10.0.0" | |
| }, | |
| "engines": { | |
| "node": "16.20.0" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GraphQLScalarType, Kind, GraphQLError } from 'graphql' | |
| const MAX_INT = Number.MAX_SAFE_INTEGER | |
| const MIN_INT = Number.MIN_SAFE_INTEGER | |
| const coerceBigint = value => { | |
| if (value === '') { | |
| throw new GraphQLError( | |
| 'Bigint не может представлять не 53-битное целочисленное значение: (пустая строка)' | |
| ) | |
| } | |
| const num = Number(value) | |
| if (num > MAX_INT || num < MIN_INT) { | |
| throw new GraphQLError( | |
| `Bigint не может представлять не 53-битное целочисленное значение: ${String(value)}` | |
| ) | |
| } | |
| const int = Math.floor(num) | |
| if (int !== num) { | |
| throw new GraphQLError(`Bigint не может представлять нецелое значение: ${String(value)}`) | |
| } | |
| return int | |
| } | |
| export const bigintScalar = new GraphQLScalarType({ | |
| name: 'Bigint', | |
| description: | |
| 'Скалярный тип `Bigint` представляет нефракционные целые числовые значения. Bigint может представлять значения между -(2^53) + 1 и 2^53 - 1.', | |
| serialize: coerceBigint, | |
| parseValue: coerceBigint, | |
| parseLiteral(ast) { | |
| if (ast.kind === Kind.INT) { | |
| const num = parseInt(ast.value, 10) | |
| if (num <= MAX_INT && num >= MIN_INT) { | |
| return num | |
| } | |
| } | |
| return null | |
| }, | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GraphQLScalarType, Kind, GraphQLError } from 'graphql' | |
| export const dateScalar = new GraphQLScalarType({ | |
| name: 'Date', | |
| description: 'Пользовательский скалярный тип даты', | |
| serialize(value) { | |
| if (value instanceof Date) { | |
| return value.getTime() // Convert outgoing Date to integer for JSON | |
| } | |
| throw new GraphQLError('Сериализатор GraphQL Date Scalar ожидает объект `Date`') | |
| }, | |
| parseValue(value) { | |
| if (typeof value === 'number') { | |
| return new Date(value) // Convert incoming integer to Date | |
| } | |
| throw new GraphQLError('Парсер GraphQL Date Scalar ожидает получить `number`') | |
| }, | |
| parseLiteral(ast) { | |
| if (ast.kind === Kind.INT) { | |
| // Convert hard-coded AST string to integer and then to Date | |
| return new Date(parseInt(ast.value, 10)) | |
| } | |
| // Invalid hard-coded value (not an integer) | |
| return null | |
| }, | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| scalar Date | |
| scalar Bigint | |
| type Query { | |
| "Получение списка континентов" | |
| continents(pagination: Pagination): [Continent!] | |
| "Получение континента по коду" | |
| continent(code: String): Continent | |
| "Получение списка стран" | |
| countries(pagination: Pagination): [Country!] | |
| "Получение страны по коду" | |
| country(code: String): Country | |
| test: String # test query | |
| age: Bigint! | |
| date: Date | |
| } | |
| "Пагинация по списку" | |
| input Pagination { | |
| "Смещение" | |
| offset: Int | |
| "Лимит" | |
| limit: Int | |
| } | |
| "Континент" | |
| type Continent { | |
| "Код континента" | |
| code: String! | |
| "Название континента" | |
| name: String | |
| "Страны континента" | |
| countries(pagination: Pagination): [Country] | |
| } | |
| "Страна" | |
| type Country { | |
| "Код страны" | |
| code: String! | |
| "Название страны" | |
| name: String | |
| "Название страны на родном языке" | |
| native: String | |
| "Телефонный код страны" | |
| phone: String | |
| "Континент, к которому принадлежит страна" | |
| continent: Continent | |
| "Штаты/области страны" | |
| states(pagination: Pagination): [State!] | |
| } | |
| "Штат" | |
| type State { | |
| "Код штата/области" | |
| code: String! | |
| "Название штата/области" | |
| name: String | |
| "Страна, к которой принадлежит штат/область" | |
| country: Country | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment