const { createClient } = require('graphql-ws'); const WebSocket = require('ws'); const { PubSub } = require('graphql-subscriptions'); const { parse, print } = require('graphql'); const fs = require('fs'); const pubsub = new PubSub(); const PROJECTS_MUTATED = 'PROJECTS_MUTATED'; // Read the schema file const schema = fs.readFileSync('./schemas/directus.graphql', 'utf8'); // Parse the schema const document = parse(schema); // Find the projects type definition const projectsType = document.definitions.find( def => def.kind === 'ObjectTypeDefinition' && def.name.value === 'projects' ); // Find the directus_users type definition const directusUsersType = document.definitions.find( def => def.kind === 'ObjectTypeDefinition' && def.name.value === 'directus_users' ); // Extract the fields excluding the ones ending with '_func', of object type, and specific fields const extractFields = (type) => { const fields = type.fields .filter(field => !field.name.value.endsWith('_func') && field.type.kind === 'NamedType' && !['avatar', 'role'].includes(field.name.value)) .map(field => field.name.value); // Check if 'id' field exists in the type if (type.fields.some(field => field.name.value === 'id')) { fields.unshift('id'); // Add 'id' at the start of the fields array } return fields.join('\n'); }; const projectsFields = extractFields(projectsType); const directusUsersFields = extractFields(directusUsersType); const client = createClient({ url: 'wss://directus.andert.me/graphql', keepAlive: 30000, webSocketImpl: WebSocket, connectionParams: async () => { return { access_token: process.env.DIRECTUS_API }; }, }); const finalQuery = ` subscription { projects_mutated { key event data { ${projectsFields.replace('user_created', `user_created { ${directusUsersFields} }`).replace('user_updated', `user_updated { ${directusUsersFields} }`)} } } } `; console.log(finalQuery); client.subscribe( { query: finalQuery, }, { next: data => { if (data && data.data && data.data.projects_mutated) { pubsub.publish(PROJECTS_MUTATED, { projects_mutated: data.data.projects_mutated }); } }, error: error => console.error('error:', error), } ); module.exports = { Subscription: { projects_mutated: { subscribe: () => pubsub.asyncIterator([PROJECTS_MUTATED]), resolve: payload => payload.projects_mutated, }, }, };