Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "polyapi",
"version": "0.24.20",
"version": "0.24.21",
"description": "Poly is a CLI tool to help create and manage your Poly definitions.",
"license": "MIT",
"repository": {
Expand Down
21 changes: 21 additions & 0 deletions src/commands/generate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ApiFunctionSpecification,
AuthFunctionSpecification,
CustomFunctionSpecification,
GraphQLSubscriptionSpecification,
ServerFunctionSpecification,
ServerVariableSpecification,
Specification,
Expand Down Expand Up @@ -62,6 +63,7 @@ const prepareDir = async (polyPath: string) => {
fs.mkdirSync(`${libPath}/client`);
fs.mkdirSync(`${libPath}/auth`);
fs.mkdirSync(`${libPath}/webhooks`);
fs.mkdirSync(`${libPath}/subscriptions`);
fs.mkdirSync(`${libPath}/server`);
fs.mkdirSync(`${libPath}/vari`);
fs.mkdirSync(`${libPath}/tabi`);
Expand Down Expand Up @@ -144,6 +146,9 @@ const generateJSFiles = async (
const tables = specs.filter(
(spec) => spec.type === 'table',
) as TableSpecification[];
const gqlSubscriptions = specs.filter(
(spec) => spec.type === 'graphqlSubscription',
) as GraphQLSubscriptionSpecification[];

await generateIndexJSFile(libPath);
await generatePolyCustomJSFile(libPath);
Expand All @@ -158,6 +163,7 @@ const generateJSFiles = async (
'custom functions',
);
await tryAsync(generateWebhooksJSFiles(libPath, webhookHandles), 'webhooks');
await tryAsync(generateGraphQLSubscriptionJSFiles(libPath, gqlSubscriptions), 'GraphQL subscriptions');
await tryAsync(
generateAuthFunctionJSFiles(libPath, authFunctions),
'auth functions',
Expand Down Expand Up @@ -284,6 +290,21 @@ const generateWebhooksJSFiles = async (
fs.copyFileSync(templateUrl('webhooks-index.js'), `${libPath}/webhooks/index.js`);
};

const generateGraphQLSubscriptionJSFiles = async (
libPath: string,
specifications: GraphQLSubscriptionSpecification[],
) => {
const template = handlebars.compile(loadTemplate('graphql-subscriptions.js.hbs'));
fs.writeFileSync(
`${libPath}/subscriptions/subscriptions.js`,
template({
specifications,
apiKey: getApiKey(),
}),
);
fs.copyFileSync(templateUrl('graphql-subscriptions-index.js'), `${libPath}/subscriptions/index.js`);
}

const generateServerFunctionJSFiles = async (
libPath: string,
specifications: ServerFunctionSpecification[],
Expand Down
2 changes: 2 additions & 0 deletions src/commands/generate/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ const getIDComment = (specification: Specification) => {
return `* Auth provider ID: ${specification.id}`;
case 'webhookHandle':
return `* Webhook ID: ${specification.id}`;
case 'graphqlSubscription':
return `* GraphQL Subscription ID: ${specification.id}`;
default:
return null;
}
Expand Down
8 changes: 8 additions & 0 deletions src/types/specifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type SpecificationType =
| 'serverVariable'
| 'snippet'
| 'table'
| 'graphqlSubscription'
| 'schema';

export interface ISpecification {
Expand Down Expand Up @@ -126,6 +127,12 @@ export interface WebhookHandleSpecification extends ISpecification {
function: FunctionSpecification;
}

export interface GraphQLSubscriptionSpecification extends ISpecification {
type: 'graphqlSubscription';
description: string;
function: FunctionSpecification;
}

export interface ServerVariableSpecification extends ISpecification {
type: 'serverVariable';
variable: VariableSpecification;
Expand Down Expand Up @@ -170,6 +177,7 @@ export type Specification =
| ServerVariableSpecification
| SnippetSpecification
| SchemaSpecification
| GraphQLSubscriptionSpecification
| TableSpecification;

interface CreateWebhookHandleDtoForSpecificationInput
Expand Down
4 changes: 3 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ export type GenerationError = {
};

export const echoGenerationError = (specification: Specification) => {
const typeMap = {
const typeMap: Record<SpecificationType, string> = {
apiFunction: 'API Function',
customFunction: 'Custom Function',
authFunction: 'Auth Function',
webhookHandle: 'Webhook Handle',
graphqlSubscription: 'Webhook Handle',
serverFunction: 'Server Function',
serverVariable: 'Variable',
schema: 'Schema',
snippet: 'Snippet',
table: 'Table'
};

const type = typeMap[specification.type];
Expand Down
35 changes: 35 additions & 0 deletions templates/graphql-subscriptions-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const set = require('lodash/set');
const { subscriptions } = require('./subscriptions');

const registerGraphQLSubscriptionEventListener = (clientID, getSocket, getApiKey, subscriptionId, callback) => {
const socket = getSocket();
socket.emit('registerSubscriptionHandler', {
clientID,
subscriptionId,
apiKey: getApiKey(),
}, registered => {
if (registered) {
socket.on(
`handleSubscriptionEvent:${subscriptionId}`,
async ({ event, params, executionId }) => {
await callback(event, params, { executionId });
}
);
} else {
console.log(`Could not register GraphQL subscription event handler for ${subscriptionId}`);
}
});

return () => {
socket.emit('unregisterSubscriptionHandler', {
clientID,
subscriptionId,
apiKey: getApiKey(),
});
}
};

module.exports = (clientID, getSocket, getApiKey) => subscriptions.reduce(
(acc, [path, id]) => set(acc, path, (callback) => registerGraphQLSubscriptionEventListener(clientID, getSocket, getApiKey, id, callback)),
{}
);
11 changes: 11 additions & 0 deletions templates/graphql-subscriptions.js.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
subscriptions: [
{{#each specifications}}
{{#if context}}
['{{context}}.{{name}}', '{{id}}'],
{{else}}
['{{name}}', '{{id}}'],
{{/if}}
{{/each}}
]
}
1 change: 1 addition & 0 deletions templates/index.d.ts.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ declare const poly: Poly;
export default poly;

export type UnregisterWebhookEventListener = () => void;
export type UnregisterGraphQLSubscriptionEventListener = () => void;
export type AuthFunctionCallback = (token?: string, url?: string, error?: any) => any;

export interface AuthFunctionResponse<T> {
Expand Down
2 changes: 2 additions & 0 deletions templates/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { io } = require('socket.io-client');
const apiFunctions = require('./api');
const clientFunctions = require('./client');
const webhooks = require('./webhooks');
const subscriptions = require('./subscriptions');
const authFunctions = require('./auth');
const serverFunctions = require('./server');
const vari = require('./vari');
Expand Down Expand Up @@ -68,6 +69,7 @@ merge(
serverFunctions(CLIENT_ID, polyCustom),
authFunctions(CLIENT_ID, getSocket, getApiKey),
webhooks(CLIENT_ID, getSocket, getApiKey),
subscriptions(CLIENT_ID, getSocket, getApiKey),
),
module.exports = {
...poly,
Expand Down