From 4a8345a6f8c0846c544c0c5652a30eb7531459f3 Mon Sep 17 00:00:00 2001 From: Sumanth Chinthagunta Date: Sun, 7 Jul 2024 08:30:37 -0700 Subject: [PATCH] feat: adding spectacular/role-houdini plugin --- apps/console/src/lib/graphql/client.ts | 19 +------------- packages/role-houdini/README.md | 4 +-- packages/role-houdini/package.json | 7 +++++- packages/role-houdini/src/client.ts | 15 +++--------- packages/role-houdini/src/config.ts | 34 ++++++++++++++++++++++++++ packages/role-houdini/src/index.ts | 16 +++++++++--- 6 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 packages/role-houdini/src/config.ts diff --git a/apps/console/src/lib/graphql/client.ts b/apps/console/src/lib/graphql/client.ts index 5adee76a..61c5b49b 100644 --- a/apps/console/src/lib/graphql/client.ts +++ b/apps/console/src/lib/graphql/client.ts @@ -21,23 +21,6 @@ const logMetadata: ClientPlugin = () => ({ }, }); -const setRolePlugin: ClientPlugin = () => ({ - start(ctx, { next }) { - const { - artifact: { pluginData }, - metadata, - } = ctx; - const role = pluginData?.['@spectacular/role-houdini']?.role; - - if (role && !metadata?.useRole) { - console.log('setting role:', role); - if (metadata) metadata.useRole = role; - else ctx.metadata = { useRole: role }; - } - next(ctx); - }, -}); - const subClient: ClientPlugin = subscription(({ session }) => createWSClient({ url: url.replace('https://', 'wss://').replace('http://', 'ws://'), @@ -105,5 +88,5 @@ export default new HoudiniClient({ // error(500, `(${ctx.artifact.name}): ` + errors.map((err) => err.message).join('. ') + '.') }, }, - plugins: [setRolePlugin, subClient, ...(browser ? [logMetadata] : [])], + plugins: [subClient, ...(browser ? [logMetadata] : [])], }); diff --git a/packages/role-houdini/README.md b/packages/role-houdini/README.md index 24849b4e..54dfd97f 100644 --- a/packages/role-houdini/README.md +++ b/packages/role-houdini/README.md @@ -15,12 +15,12 @@ Inspired by [grafbase-houdini](https://github.com/grafbase/grafbase/tree/main/pa } ``` -1. Add Role directive to any GLQ. e.g., `@role(name: "user")` +1. Add `@role` directive to your GraphQL Docs. e.g., `@role(name: "user")` ```gql query GetUser($userId: uuid!) @role(name: "user") { user(id: $userId) { - ...UserDetailsFragment @loading + ...UserDetailsFragment userOrgRoles(order_by: {organization: asc}) { organization role diff --git a/packages/role-houdini/package.json b/packages/role-houdini/package.json index 960ce426..3ad55919 100644 --- a/packages/role-houdini/package.json +++ b/packages/role-houdini/package.json @@ -19,15 +19,20 @@ "./client": { "import": "./dist/client.js", "require": "./dist/client.js" + }, + "./config": { + "import": "./dist/config.js", + "require": "./dist/config.js" } }, "scripts": { "clean": "rm -rf dist", "lint": "biome check", "format": "biome check --write", - "build": "pnpm build:plugin && pnpm build:client", + "build": "pnpm build:plugin && pnpm build:client && pnpm build:config", "build:plugin": "tsup src/index.ts --format esm,cjs --dts", "build:client": "tsup src/client.ts --format esm,cjs --dts", + "build:config": "tsup src/config.ts --format esm,cjs --dts", "dev": "tsup src/index.ts --format esm,cjs --watch --dts" }, "dependencies": { diff --git a/packages/role-houdini/src/client.ts b/packages/role-houdini/src/client.ts index 1b95a547..70a6453e 100644 --- a/packages/role-houdini/src/client.ts +++ b/packages/role-houdini/src/client.ts @@ -4,18 +4,11 @@ import type { ClientPlugin } from 'houdini'; const plugin: ClientPlugin = () => ({ start(ctx, { next }) { - const { - artifact: { pluginData }, - metadata, - } = ctx; - const role = pluginData?.['@spectacular/role-houdini']?.role; - - if (role && !metadata?.useRole) { - console.log('setting role:', role); - if (metadata) metadata.useRole = role; - else ctx.metadata = { useRole: role }; + const role = ctx.artifact.pluginData?.['@spectacular/role-houdini']?.role; + if (role && ctx.fetchParams?.headers) { + ctx.fetchParams.headers = { ...ctx.fetchParams.headers, 'x-hasura-role': role }; + console.log(ctx.fetchParams.headers); } - next(ctx); }, }); diff --git a/packages/role-houdini/src/config.ts b/packages/role-houdini/src/config.ts new file mode 100644 index 00000000..eef3f01a --- /dev/null +++ b/packages/role-houdini/src/config.ts @@ -0,0 +1,34 @@ +import type { ConfigFile } from 'houdini'; + +/** Configure the default set of scalars supported by Hasura */ +export default function config(config: ConfigFile): ConfigFile { + return { + ...config, + scalars: { + ...config.scalars, + hstore: { + type: 'string', + unmarshal(val) { + return Object.entries(val) + .map(([k, v]) => `"${k}" => "${v}"`) + .join(', '); + }, + marshal(val) { + return val; + }, + }, + citext: { + type: 'string', + ...config.scalars?.citext, + }, + uuid: { + type: 'string', + ...config.scalars?.citext, + }, + jsonb: { + type: 'Record', + ...config.scalars?.JSON, + }, + }, + }; +} diff --git a/packages/role-houdini/src/index.ts b/packages/role-houdini/src/index.ts index 601da59d..d4303cf3 100644 --- a/packages/role-houdini/src/index.ts +++ b/packages/role-houdini/src/index.ts @@ -7,12 +7,22 @@ export default plugin('role-houdini', async () => { // add the @role directive schema() { return ` - directive @role( - name: [String!] - ) on QUERY + directive @role( + name: String! + ) on QUERY `; }, + /** + * Add the client plugin to the runtime + */ + clientPlugins: { + '@spectacular/role-houdini/client': null, + }, + + /** Configure the default set of scalars supported by Hasura */ + config: '@spectacular/role-houdini/config', + /** * We want to perform special logic for the the @role directive so we're going to persist * data in the artifact if we detect it