UNPKG

@dossierhq/graphql

Version:

A library for creating GraphQL servers with Dossier.

62 lines 2.22 kB
/// <reference types="./LocationScalar.d.ts" /> import { GraphQLScalarType } from 'graphql'; import { Kind } from 'graphql/language/index.js'; export const LocationScalar = new GraphQLScalarType({ name: 'Location', description: 'Geographic location using EPSG:4326/WGS 84', serialize(value) { if (value === null) return null; assertLocation(value); return value; }, parseValue(value) { if (value === null) return null; assertLocation(value); return value; }, parseLiteral(ast) { if (ast.kind === Kind.OBJECT) { const lat = getFloatFieldValue(ast, 'lat'); const lng = getFloatFieldValue(ast, 'lng'); if (lat === null || lng === null) { throw new Error('Location must have lat and lng fields'); } return { lat, lng }; } if (ast.kind === Kind.NULL) { return null; } throw new Error(`Expected Location to be an object, got ${ast.kind}`); }, }); function assertLocation(value) { if (typeof value !== 'object' || value === null) { throw new Error(`Expected Location to be an object, got ${typeof value}`); } const { lat, lng } = value; if (typeof lat !== 'number') { throw new Error(`Expected Location.lat to be a number, got ${typeof lat}`); } if (typeof lng !== 'number') { throw new Error(`Expected Location.lng to be a number, got ${typeof lng}`); } if (lat < -90 || lat > 90) { throw new Error(`Expected Location.lat to be between -90 and 90, got ${lat}`); } if (lng < -180 || lng > 180) { throw new Error(`Expected Location.lng to be between -180 and 180, got ${lng}`); } } function getFloatFieldValue(ast, fieldName) { const field = ast.fields.find((it) => it.name.value === fieldName); if (field) { if (field.value.kind === Kind.FLOAT || field.value.kind === Kind.INT) { return parseFloat(field.value.value); } throw new Error(`Expected ${fieldName} to be a float, got ${field.value.kind}`); } return null; } //# sourceMappingURL=LocationScalar.js.map