graphql-scalars
Version:
A collection of scalar types not included in base GraphQL.
84 lines (83 loc) • 3.07 kB
JavaScript
import { GraphQLScalarType, Kind } from 'graphql';
import { createGraphQLError } from '../../error.js';
import { generateGeoJSONType } from './codegenScalarType.js';
import { geojsonSchema } from './jsonSchema.js';
import { isValidBBox, isValidFeature, isValidFeatureCollection, isValidGeometry, } from './validators.js';
const validate = (value, ast) => {
let parsed;
if (typeof value === 'string') {
try {
parsed = JSON.parse(value);
}
catch (_a) {
throw createGraphQLError('Invalid GeoJSON: Failed to parse JSON string', ast ? { nodes: ast } : undefined);
}
}
else {
parsed = value;
}
if (!parsed || typeof parsed !== 'object') {
throw createGraphQLError('Invalid GeoJSON: Must be an object', ast ? { nodes: ast } : undefined);
}
if (!('type' in parsed)) {
throw createGraphQLError('Invalid GeoJSON: Missing type property', ast ? { nodes: ast } : undefined);
}
// Validate bbox if present
if ('bbox' in parsed && parsed.bbox !== undefined) {
if (!isValidBBox(parsed.bbox)) {
throw createGraphQLError('Invalid GeoJSON: Invalid bbox format', ast ? { nodes: ast } : undefined);
}
}
// Validate based on type
/*if (parsed.type === 'Feature') {
if (!isValidFeature(parsed)) {
throw createGraphQLError(
'Invalid GeoJSON: Invalid Feature object',
ast ? { nodes: ast } : undefined,
);
}
} else if (parsed.type === 'FeatureCollection') {
if (!isValidFeatureCollection(parsed)) {
throw createGraphQLError(
'Invalid GeoJSON: Invalid FeatureCollection object',
ast ? { nodes: ast } : undefined,
);
}
} else if (!isValidGeometry(parsed)) {
throw createGraphQLError(
'Invalid GeoJSON: Invalid Geometry object',
ast ? { nodes: ast } : undefined,
);
}*/
if (isValidFeature(parsed)) {
return parsed;
}
else if (isValidFeatureCollection(parsed)) {
return parsed;
}
else if (isValidGeometry(parsed)) {
return parsed;
}
// return parsed as GeoJSONObject;
throw createGraphQLError('Invalid GeoJSON: Object does not match any valid GeoJSON type', ast ? { nodes: ast } : undefined);
};
export const GraphQLGeoJSON = /*#__PURE__*/ new GraphQLScalarType({
name: 'GeoJSON',
description: 'A GeoJSON object as defined by RFC 7946: https://datatracker.ietf.org/doc/html/rfc7946',
serialize(value) {
return validate(value);
},
parseValue(value) {
return validate(value);
},
parseLiteral(ast) {
if (ast.kind !== Kind.STRING && ast.kind !== Kind.OBJECT) {
throw createGraphQLError(`Can only validate strings or objects as GeoJSON but got a: ${ast.kind}`, { nodes: [ast] });
}
return validate(ast.kind === Kind.STRING ? ast.value : ast, ast);
},
extensions: {
codegenScalarType: generateGeoJSONType(),
jsonSchema: geojsonSchema,
},
});