93 lines
2.6 KiB
JavaScript
93 lines
2.6 KiB
JavaScript
const { createClient } = require('graphql-ws');
|
|
const WebSocket = require('ws');
|
|
const { PubSub } = require('graphql-subscriptions');
|
|
const { parse } = 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);
|
|
// Function to find a type definition by name
|
|
const findTypeDefinition = (typeName) => {
|
|
return document.definitions.find(
|
|
def => def.kind === 'ObjectTypeDefinition' && def.name.value === typeName
|
|
);
|
|
};
|
|
|
|
// Extract the fields excluding the ones ending with '_func', of object type, and specific fields
|
|
const extractFields = (type, depth = 0) => {
|
|
return type.fields
|
|
.filter(field => !field.name.value.endsWith('_func') && !['avatar', 'role'].includes(field.name.value))
|
|
.map(field => {
|
|
if (field.type.kind === 'NamedType' && depth < 1) {
|
|
// If the field is of object type and we are not too deep, recursively extract its fields
|
|
const nestedType = findTypeDefinition(field.type.name.value);
|
|
if (nestedType) {
|
|
return `${field.name.value} {\n${extractFields(nestedType, depth + 1)}\n}`;
|
|
}
|
|
}
|
|
return field.name.value;
|
|
})
|
|
.join('\n');
|
|
};
|
|
|
|
const projectsType = findTypeDefinition('projects');
|
|
const projectsFields = extractFields(projectsType);
|
|
|
|
const client = createClient({
|
|
url: 'wss://directus.andert.me/graphql',
|
|
keepAlive: 30000,
|
|
webSocketImpl: WebSocket,
|
|
connectionParams: async () => {
|
|
return { access_token: process.env.DIRECTUS_API };
|
|
},
|
|
});
|
|
|
|
const generateSubscriptionQuery = (typeName) => {
|
|
const typeDefinition = findTypeDefinition(typeName);
|
|
const fields = extractFields(typeDefinition);
|
|
|
|
return `
|
|
subscription {
|
|
${typeName}_mutated {
|
|
key
|
|
event
|
|
data {
|
|
${fields}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
};
|
|
|
|
// Generate subscription query for 'projects'
|
|
const projectsQuery = generateSubscriptionQuery('projects');
|
|
// const todosQuery = generateSubscriptionQuery('todos');
|
|
|
|
client.subscribe(
|
|
{
|
|
query: projectsQuery,
|
|
},
|
|
{
|
|
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,
|
|
},
|
|
},
|
|
}; |