Skip to content

Commit

Permalink
feat(social): implement persisted operations
Browse files Browse the repository at this point in the history
  • Loading branch information
joshxfi committed Aug 17, 2024
1 parent f407dd3 commit 0325635
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 7 deletions.
5 changes: 0 additions & 5 deletions apps/partners/next-env.d.ts

This file was deleted.

7 changes: 5 additions & 2 deletions apps/social/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
"build": "next build",
"start": "next start",
"clean": "rm -rf ./node_modules .turbo .next",
"check-types": "tsc --noEmit",
"lint": "next lint"
"check-types": "tsc --noEmit && gql.tada check",
"lint": "next lint",
"gql:check": "gql.tada check",
"gql:generate-persisted": "gql.tada generate-persisted",
"gql:generate-schema": "gql.tada generate-schema http://localhost:3000/api/graphql"
},
"dependencies": {
"@fingerprintjs/botd": "^1.9.1",
Expand Down
36 changes: 36 additions & 0 deletions apps/social/src/app/api/graphql/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { cookies } from "next/headers";
import { createYoga } from "graphql-yoga";
import { getSession, lucia } from "@/lib/auth";
import persistedOperations from "@/persisted-operations.json";
import { social_schema, initContextCache } from "@umamin/gql";
import { useResponseCache } from "@graphql-yoga/plugin-response-cache";
import { useCSRFPrevention } from "@graphql-yoga/plugin-csrf-prevention";
import { usePersistedOperations } from "@graphql-yoga/plugin-persisted-operations";
import { useDisableIntrospection } from "@graphql-yoga/plugin-disable-introspection";

const { handleRequest } = createYoga({
Expand Down Expand Up @@ -46,6 +48,40 @@ const { handleRequest } = createYoga({
useDisableIntrospection({
isDisabled: () => process.env.NODE_ENV === "production",
}),
usePersistedOperations({
allowArbitraryOperations: process.env.NODE_ENV === "development",
customErrors: {
notFound: {
message: "Operation is not found",
extensions: {
http: {
status: 404,
},
},
},
keyNotFound: {
message: "Key is not found",
extensions: {
http: {
status: 404,
},
},
},
persistedQueryOnly: {
message: "Operation is not allowed",
extensions: {
http: {
status: 403,
},
},
},
},
skipDocumentValidation: true,
async getPersistedOperation(key: string) {
// @ts-ignore
return persistedOperations[key];
},
}),
],
});

Expand Down
39 changes: 39 additions & 0 deletions apps/social/src/graphql-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* eslint-disable */
/* prettier-ignore */

export type introspection_types = {
'Account': { kind: 'OBJECT'; name: 'Account'; fields: { 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'email': { name: 'email'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'picture': { name: 'picture'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
'Boolean': unknown;
'ID': unknown;
'Int': unknown;
'Mutation': { kind: 'OBJECT'; name: 'Mutation'; fields: { 'updatePicture': { name: 'updatePicture'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'updateQuietMode': { name: 'updateQuietMode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'updateUser': { name: 'updateUser'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
'PublicUser': { kind: 'OBJECT'; name: 'PublicUser'; fields: { 'bio': { name: 'bio'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'displayName': { name: 'displayName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'imageUrl': { name: 'imageUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'question': { name: 'question'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'quietMode': { name: 'quietMode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'username': { name: 'username'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
'Query': { kind: 'OBJECT'; name: 'Query'; fields: { 'user': { name: 'user'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'userByUsername': { name: 'userByUsername'; type: { kind: 'OBJECT'; name: 'PublicUser'; ofType: null; } }; }; };
'String': unknown;
'UpdateUserInput': { kind: 'INPUT_OBJECT'; name: 'UpdateUserInput'; isOneOf: false; inputFields: [{ name: 'bio'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'displayName'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'question'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'username'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }]; };
'User': { kind: 'OBJECT'; name: 'User'; fields: { 'accounts': { name: 'accounts'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Account'; ofType: null; }; }; } }; 'bio': { name: 'bio'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'displayName': { name: 'displayName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'imageUrl': { name: 'imageUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'question': { name: 'question'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'quietMode': { name: 'quietMode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'username': { name: 'username'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
};

/** An IntrospectionQuery representation of your schema.
*
* @remarks
* This is an introspection of your schema saved as a file by GraphQLSP.
* It will automatically be used by `gql.tada` to infer the types of your GraphQL documents.
* If you need to reuse this data or update your `scalars`, update `tadaOutputLocation` to
* instead save to a .ts instead of a .d.ts file.
*/
export type introspection = {
name: never;
query: 'Query';
mutation: 'Mutation';
subscription: never;
types: introspection_types;
};

import * as gqlTada from 'gql.tada';

declare module 'gql.tada' {
interface setupSchema {
introspection: introspection
}
}
3 changes: 3 additions & 0 deletions apps/social/src/persisted-operations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"e56708c4cacdba6c698de1f4bc45a999ca535fb519bd806caf9a62a6582159e4": "query UserByUsername($username: String!) {\n userByUsername(username: $username) {\n __typename\n id\n bio\n question\n username\n displayName\n question\n quietMode\n imageUrl\n createdAt\n }\n}"
}
47 changes: 47 additions & 0 deletions apps/social/src/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
type Account {
createdAt: Int!
email: String!
id: ID!
picture: String!
}

type Mutation {
updatePicture(imageUrl: String): String
updateQuietMode(quietMode: Boolean!): String
updateUser(input: UpdateUserInput!): String
}

type PublicUser {
bio: String
createdAt: Int!
displayName: String
id: ID!
imageUrl: String
question: String!
quietMode: Boolean!
username: String!
}

type Query {
user: User
userByUsername(username: String!): PublicUser
}

input UpdateUserInput {
bio: String
displayName: String!
question: String!
username: String!
}

type User {
accounts: [Account!]
bio: String
createdAt: Int!
displayName: String
id: ID!
imageUrl: String
question: String!
quietMode: Boolean!
username: String!
}

0 comments on commit 0325635

Please sign in to comment.