| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import {
- GraphQLList,
- GraphQLNonNull,
- GraphQLObjectType,
- GraphQLSchema,
- GraphQLType,
- isEnumType,
- isInputObjectType,
- isObjectType,
- isScalarType,
- } from 'graphql';
- import { Plugin } from 'vite';
- import { generateSchema } from './utils/schema-generator.js';
- import { ConfigLoaderApi, getConfigLoaderApi } from './vite-plugin-config-loader.js';
- export type FieldInfoTuple = readonly [
- type: string,
- nullable: boolean,
- list: boolean,
- isPaginatedList: boolean,
- ];
- export interface SchemaInfo {
- types: {
- [typename: string]: {
- [fieldname: string]: FieldInfoTuple;
- };
- };
- inputs: {
- [typename: string]: {
- [fieldname: string]: FieldInfoTuple;
- };
- };
- scalars: string[];
- enums: {
- [typename: string]: string[];
- };
- }
- const virtualModuleId = 'virtual:admin-api-schema';
- const resolvedVirtualModuleId = `\0${virtualModuleId}`;
- export function adminApiSchemaPlugin(): Plugin {
- let configLoaderApi: ConfigLoaderApi;
- let schemaInfo: SchemaInfo;
- return {
- name: 'vendure:admin-api-schema',
- configResolved({ plugins }) {
- configLoaderApi = getConfigLoaderApi(plugins);
- },
- async buildStart() {
- const { vendureConfig } = await configLoaderApi.getVendureConfig();
- if (!schemaInfo) {
- const safeSchema = await generateSchema({ vendureConfig });
- schemaInfo = generateSchemaInfo(safeSchema);
- }
- },
- resolveId(id) {
- if (id === virtualModuleId) {
- return resolvedVirtualModuleId;
- }
- },
- load(id) {
- if (id === resolvedVirtualModuleId) {
- return `
- export const schemaInfo = ${JSON.stringify(schemaInfo)};
- `;
- }
- },
- };
- }
- function getTypeInfo(type: GraphQLType) {
- let nullable = true;
- let list = false;
- let isPaginatedList = false;
- // Unwrap NonNull
- if (type instanceof GraphQLNonNull) {
- nullable = false;
- type = type.ofType;
- }
- // Unwrap List
- if (type instanceof GraphQLList) {
- list = true;
- type = type.ofType;
- }
- if (type instanceof GraphQLObjectType) {
- if (type.getInterfaces().some(i => i.name === 'PaginatedList')) {
- isPaginatedList = true;
- }
- }
- return [type.toString().replace(/!$/, ''), nullable, list, isPaginatedList] as const;
- }
- function generateSchemaInfo(schema: GraphQLSchema): SchemaInfo {
- const types = schema.getTypeMap();
- const result: SchemaInfo = { types: {}, inputs: {}, scalars: [], enums: {} };
- Object.values(types).forEach(type => {
- if (isObjectType(type)) {
- const fields = type.getFields();
- result.types[type.name] = {};
- Object.entries(fields).forEach(([fieldName, field]) => {
- result.types[type.name][fieldName] = getTypeInfo(field.type);
- });
- }
- if (isInputObjectType(type)) {
- const fields = type.getFields();
- result.inputs[type.name] = {};
- Object.entries(fields).forEach(([fieldName, field]) => {
- result.inputs[type.name][fieldName] = getTypeInfo(field.type);
- });
- }
- if (isScalarType(type)) {
- result.scalars.push(type.name);
- }
- if (isEnumType(type)) {
- result.enums[type.name] = type.getValues().map(v => v.value);
- }
- });
- return result;
- }
|