diff --git a/backend/.local.env.template b/backend/.local.env.template
deleted file mode 100644
index 3c70b36..0000000
--- a/backend/.local.env.template
+++ /dev/null
@@ -1,16 +0,0 @@
-HASURA_GRAPHQL_ENDPOINT=
:/v1/graphql
-HASURA_GRAPHQL_ADMIN_SECRET=
-
-JWT_SECRET=
-
-EMAIL_HOST=smtp.163.com
-EMAIL_PORT=465
-EMAIL_SECURE=true
-EMAIL_ADDRESS=
-EMAIL_PASSWORD=
-
-(以下备注请在生产环境中删除)
-注:不同邮箱提供商的配置方法不同,请参考对应的文档或邮箱设置;
-- 部分邮箱需要手动开启 SMTP 服务;
-- 部分邮箱的密码(包括清华邮箱)填的是设备授权码,而不是账号密码;
-- 部分邮箱需要 OAuth2 或其他身份验证,请参考 https://nodemailer.com/smtp/oauth2/
diff --git a/backend/package.json b/backend/package.json
index 6b6f66f..422bb62 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -24,6 +24,7 @@
"start": "nodemon src/index.ts",
"build": "tsc",
"serve": "node build/index.js",
- "typecheck": "tsc --noEmit"
+ "typecheck": "tsc --noEmit",
+ "generate": "graphql-codegen"
}
}
diff --git a/backend/src/email.ts b/backend/src/email.ts
index 4c19628..a2fa72d 100644
--- a/backend/src/email.ts
+++ b/backend/src/email.ts
@@ -3,7 +3,7 @@ import nodemailer from "nodemailer";
const router = express.Router();
-const sendEmail = async (to: string, subject: string, text: string) => {
+export const sendEmail = async (to: string, subject: string, text: string) => {
const transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST!,
port: Number(process.env.EMAIL_PORT!),
diff --git a/backend/src/graphql.ts b/backend/src/graphql.ts
index 8e65cb6..be846df 100644
--- a/backend/src/graphql.ts
+++ b/backend/src/graphql.ts
@@ -78,6 +78,7 @@ export type Message = {
__typename?: 'message';
content: Scalars['String']['output'];
created_at: Scalars['timestamp']['output'];
+ reply_to_uuid?: Maybe;
/** An object relationship */
room: Room;
room_uuid: Scalars['uuid']['output'];
@@ -141,6 +142,7 @@ export type Message_Bool_Exp = {
_or?: InputMaybe>;
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room?: InputMaybe;
room_uuid?: InputMaybe;
user?: InputMaybe;
@@ -158,6 +160,7 @@ export enum Message_Constraint {
export type Message_Insert_Input = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room?: InputMaybe;
room_uuid?: InputMaybe;
user?: InputMaybe;
@@ -170,6 +173,7 @@ export type Message_Max_Fields = {
__typename?: 'message_max_fields';
content?: Maybe;
created_at?: Maybe;
+ reply_to_uuid?: Maybe;
room_uuid?: Maybe;
user_uuid?: Maybe;
uuid?: Maybe;
@@ -179,6 +183,7 @@ export type Message_Max_Fields = {
export type Message_Max_Order_By = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room_uuid?: InputMaybe;
user_uuid?: InputMaybe;
uuid?: InputMaybe;
@@ -189,6 +194,7 @@ export type Message_Min_Fields = {
__typename?: 'message_min_fields';
content?: Maybe;
created_at?: Maybe;
+ reply_to_uuid?: Maybe;
room_uuid?: Maybe;
user_uuid?: Maybe;
uuid?: Maybe;
@@ -198,6 +204,7 @@ export type Message_Min_Fields = {
export type Message_Min_Order_By = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room_uuid?: InputMaybe;
user_uuid?: InputMaybe;
uuid?: InputMaybe;
@@ -223,6 +230,7 @@ export type Message_On_Conflict = {
export type Message_Order_By = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room?: InputMaybe;
room_uuid?: InputMaybe;
user?: InputMaybe;
@@ -242,6 +250,8 @@ export enum Message_Select_Column {
/** column name */
CreatedAt = 'created_at',
/** column name */
+ ReplyToUuid = 'reply_to_uuid',
+ /** column name */
RoomUuid = 'room_uuid',
/** column name */
UserUuid = 'user_uuid',
@@ -253,6 +263,7 @@ export enum Message_Select_Column {
export type Message_Set_Input = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room_uuid?: InputMaybe;
user_uuid?: InputMaybe;
uuid?: InputMaybe;
@@ -270,6 +281,7 @@ export type Message_Stream_Cursor_Input = {
export type Message_Stream_Cursor_Value_Input = {
content?: InputMaybe;
created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
room_uuid?: InputMaybe;
user_uuid?: InputMaybe;
uuid?: InputMaybe;
@@ -282,6 +294,8 @@ export enum Message_Update_Column {
/** column name */
CreatedAt = 'created_at',
/** column name */
+ ReplyToUuid = 'reply_to_uuid',
+ /** column name */
RoomUuid = 'room_uuid',
/** column name */
UserUuid = 'user_uuid',
@@ -1319,7 +1333,7 @@ export type User_Room_Bool_Exp = {
/** unique or primary key constraints on table "user_room" */
export enum User_Room_Constraint {
- /** unique or primary key constraint on columns "user_uuid", "room_uuid" */
+ /** unique or primary key constraint on columns "room_uuid", "user_uuid" */
UserRoomPkey = 'user_room_pkey'
}
@@ -1547,6 +1561,14 @@ export type AddUserMutationVariables = Exact<{
export type AddUserMutation = { __typename?: 'mutation_root', insert_user_one?: { __typename?: 'user', uuid: any } | null };
+export type UpdateUserPasswordMutationVariables = Exact<{
+ uuid: Scalars['uuid']['input'];
+ password: Scalars['String']['input'];
+}>;
+
+
+export type UpdateUserPasswordMutation = { __typename?: 'mutation_root', update_user?: { __typename?: 'user_mutation_response', affected_rows: number } | null };
+
export type GetUsersByUsernameQueryVariables = Exact<{
username: Scalars['String']['input'];
}>;
@@ -1619,6 +1641,13 @@ export const AddUserDocument = gql`
}
}
`;
+export const UpdateUserPasswordDocument = gql`
+ mutation updateUserPassword($uuid: uuid!, $password: String!) {
+ update_user(where: {uuid: {_eq: $uuid}}, _set: {password: $password}) {
+ affected_rows
+ }
+}
+ `;
export const GetUsersByUsernameDocument = gql`
query getUsersByUsername($username: String!) {
user(where: {username: {_eq: $username}}) {
@@ -1656,9 +1685,12 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
addUser(variables: AddUserMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise {
return withWrapper((wrappedRequestHeaders) => client.request(AddUserDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'addUser', 'mutation', variables);
},
+ updateUserPassword(variables: UpdateUserPasswordMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise {
+ return withWrapper((wrappedRequestHeaders) => client.request(UpdateUserPasswordDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'updateUserPassword', 'mutation', variables);
+ },
getUsersByUsername(variables: GetUsersByUsernameQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise {
return withWrapper((wrappedRequestHeaders) => client.request(GetUsersByUsernameDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getUsersByUsername', 'query', variables);
}
};
}
-export type Sdk = ReturnType;
+export type Sdk = ReturnType;
\ No newline at end of file
diff --git a/backend/src/user.ts b/backend/src/user.ts
index a93bd91..117a0d8 100644
--- a/backend/src/user.ts
+++ b/backend/src/user.ts
@@ -1,6 +1,7 @@
import express from "express";
import jwt from "jsonwebtoken";
import { sdk as graphql } from "./index";
+import { sendEmail } from "./email";
interface userJWTPayload {
uuid: string;
@@ -72,3 +73,49 @@ router.post("/register", async (req, res) => {
});
export default router;
+
+router.post("/change-password/request", async (req, res) => {
+ const { username } = req.body;
+ if (!username) {
+ return res.status(422).send("Missing username");
+ }
+ try {
+ const queryResult = await graphql.getUsersByUsername({ username });
+ if (queryResult.user.length === 0) {
+ return res.status(404).send("User not found");
+ }
+ const user = queryResult.user[0];
+ const token = jwt.sign(
+ { uuid: user.uuid },
+ process.env.JWT_SECRET!,
+ { expiresIn: "1h" });
+ const link = `http://localhost:8888/user/change-password/action?token=${token}`;
+ await sendEmail(username, "Password Reset Request", `Click this link: ${link}`);
+ return res.status(200).send("Reset email sent");
+ } catch (err) {
+ console.error(err);
+ return res.sendStatus(500);
+ }
+});
+
+router.post("/change-password/action", async (req, res) => {
+ const { token, newPassword } = req.body;
+ if (!token || !newPassword) {
+ return res.status(422).send("Missing token or newPassword");
+ }
+ try {
+ const payload: any = jwt.verify(token, process.env.JWT_SECRET!);
+ const uuid = payload.uuid;
+ const result = await graphql.updateUserPassword({
+ uuid,
+ password: newPassword,
+ });
+ if (result.update_user?.affected_rows === 0) {
+ return res.status(404).send("User not found");
+ }
+ return res.status(200).send("Password updated successfully");
+ } catch (err) {
+ console.error(err);
+ return res.sendStatus(500);
+ }
+});
diff --git a/database/.local.env.template b/database/.local.env.template
deleted file mode 100644
index 89074f3..0000000
--- a/database/.local.env.template
+++ /dev/null
@@ -1,2 +0,0 @@
-HASURA_GRAPHQL_ENDPOINT=:/v1/graphql
-HASURA_GRAPHQL_ADMIN_SECRET=
diff --git a/database/graphql/user.graphql b/database/graphql/user.graphql
index d7780cd..7f5c1b7 100644
--- a/database/graphql/user.graphql
+++ b/database/graphql/user.graphql
@@ -4,6 +4,12 @@ mutation addUser($username: String!, $password: String!) {
}
}
+mutation updateUserPassword($uuid: uuid!, $password: String!) {
+ update_user(where: {uuid: {_eq: $uuid}}, _set: {password: $password}) {
+ affected_rows
+ }
+}
+
query getUsersByUsername($username: String!) {
user(where: {username: {_eq: $username}}) {
uuid
diff --git a/frontend/src/graphql.tsx b/frontend/src/graphql.tsx
new file mode 100644
index 0000000..783d319
--- /dev/null
+++ b/frontend/src/graphql.tsx
@@ -0,0 +1,1917 @@
+import { gql } from '@apollo/client';
+import * as Apollo from '@apollo/client';
+export type Maybe = T | null;
+export type InputMaybe = Maybe;
+export type Exact = { [K in keyof T]: T[K] };
+export type MakeOptional = Omit & { [SubKey in K]?: Maybe };
+export type MakeMaybe = Omit & { [SubKey in K]: Maybe };
+export type MakeEmpty = { [_ in K]?: never };
+export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
+const defaultOptions = {} as const;
+/** All built-in and custom scalars, mapped to their actual values */
+export type Scalars = {
+ ID: { input: string; output: string; }
+ String: { input: string; output: string; }
+ Boolean: { input: boolean; output: boolean; }
+ Int: { input: number; output: number; }
+ Float: { input: number; output: number; }
+ timestamp: { input: any; output: any; }
+ uuid: { input: any; output: any; }
+};
+
+/** Boolean expression to compare columns of type "Int". All fields are combined with logical 'AND'. */
+export type Int_Comparison_Exp = {
+ _eq?: InputMaybe;
+ _gt?: InputMaybe;
+ _gte?: InputMaybe;
+ _in?: InputMaybe>;
+ _is_null?: InputMaybe;
+ _lt?: InputMaybe;
+ _lte?: InputMaybe;
+ _neq?: InputMaybe;
+ _nin?: InputMaybe>;
+};
+
+/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */
+export type String_Comparison_Exp = {
+ _eq?: InputMaybe;
+ _gt?: InputMaybe;
+ _gte?: InputMaybe;
+ /** does the column match the given case-insensitive pattern */
+ _ilike?: InputMaybe;
+ _in?: InputMaybe>;
+ /** does the column match the given POSIX regular expression, case insensitive */
+ _iregex?: InputMaybe;
+ _is_null?: InputMaybe;
+ /** does the column match the given pattern */
+ _like?: InputMaybe;
+ _lt?: InputMaybe;
+ _lte?: InputMaybe;
+ _neq?: InputMaybe;
+ /** does the column NOT match the given case-insensitive pattern */
+ _nilike?: InputMaybe;
+ _nin?: InputMaybe>;
+ /** does the column NOT match the given POSIX regular expression, case insensitive */
+ _niregex?: InputMaybe;
+ /** does the column NOT match the given pattern */
+ _nlike?: InputMaybe;
+ /** does the column NOT match the given POSIX regular expression, case sensitive */
+ _nregex?: InputMaybe;
+ /** does the column NOT match the given SQL regular expression */
+ _nsimilar?: InputMaybe;
+ /** does the column match the given POSIX regular expression, case sensitive */
+ _regex?: InputMaybe;
+ /** does the column match the given SQL regular expression */
+ _similar?: InputMaybe;
+};
+
+/** ordering argument of a cursor */
+export enum Cursor_Ordering {
+ /** ascending ordering of the cursor */
+ Asc = 'ASC',
+ /** descending ordering of the cursor */
+ Desc = 'DESC'
+}
+
+/** columns and relationships of "message" */
+export type Message = {
+ __typename?: 'message';
+ content: Scalars['String']['output'];
+ created_at: Scalars['timestamp']['output'];
+ reply_to_uuid?: Maybe;
+ /** An object relationship */
+ room: Room;
+ room_uuid: Scalars['uuid']['output'];
+ /** An object relationship */
+ user: User;
+ user_uuid: Scalars['uuid']['output'];
+ uuid: Scalars['uuid']['output'];
+};
+
+/** aggregated selection of "message" */
+export type Message_Aggregate = {
+ __typename?: 'message_aggregate';
+ aggregate?: Maybe;
+ nodes: Array;
+};
+
+export type Message_Aggregate_Bool_Exp = {
+ count?: InputMaybe;
+};
+
+export type Message_Aggregate_Bool_Exp_Count = {
+ arguments?: InputMaybe>;
+ distinct?: InputMaybe;
+ filter?: InputMaybe;
+ predicate: Int_Comparison_Exp;
+};
+
+/** aggregate fields of "message" */
+export type Message_Aggregate_Fields = {
+ __typename?: 'message_aggregate_fields';
+ count: Scalars['Int']['output'];
+ max?: Maybe;
+ min?: Maybe;
+};
+
+
+/** aggregate fields of "message" */
+export type Message_Aggregate_FieldsCountArgs = {
+ columns?: InputMaybe>;
+ distinct?: InputMaybe;
+};
+
+/** order by aggregate values of table "message" */
+export type Message_Aggregate_Order_By = {
+ count?: InputMaybe;
+ max?: InputMaybe;
+ min?: InputMaybe;
+};
+
+/** input type for inserting array relation for remote table "message" */
+export type Message_Arr_Rel_Insert_Input = {
+ data: Array;
+ /** upsert condition */
+ on_conflict?: InputMaybe;
+};
+
+/** Boolean expression to filter rows from the table "message". All fields are combined with a logical 'AND'. */
+export type Message_Bool_Exp = {
+ _and?: InputMaybe>;
+ _not?: InputMaybe;
+ _or?: InputMaybe>;
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** unique or primary key constraints on table "message" */
+export enum Message_Constraint {
+ /** unique or primary key constraint on columns "uuid" */
+ MessagePkey = 'message_pkey'
+}
+
+/** input type for inserting data into table "message" */
+export type Message_Insert_Input = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** aggregate max on columns */
+export type Message_Max_Fields = {
+ __typename?: 'message_max_fields';
+ content?: Maybe;
+ created_at?: Maybe;
+ reply_to_uuid?: Maybe;
+ room_uuid?: Maybe;
+ user_uuid?: Maybe;
+ uuid?: Maybe;
+};
+
+/** order by max() on columns of table "message" */
+export type Message_Max_Order_By = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** aggregate min on columns */
+export type Message_Min_Fields = {
+ __typename?: 'message_min_fields';
+ content?: Maybe;
+ created_at?: Maybe;
+ reply_to_uuid?: Maybe;
+ room_uuid?: Maybe;
+ user_uuid?: Maybe;
+ uuid?: Maybe;
+};
+
+/** order by min() on columns of table "message" */
+export type Message_Min_Order_By = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** response of any mutation on the table "message" */
+export type Message_Mutation_Response = {
+ __typename?: 'message_mutation_response';
+ /** number of rows affected by the mutation */
+ affected_rows: Scalars['Int']['output'];
+ /** data from the rows affected by the mutation */
+ returning: Array;
+};
+
+/** on_conflict condition type for table "message" */
+export type Message_On_Conflict = {
+ constraint: Message_Constraint;
+ update_columns?: Array;
+ where?: InputMaybe;
+};
+
+/** Ordering options when selecting data from "message". */
+export type Message_Order_By = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** primary key columns input for table: message */
+export type Message_Pk_Columns_Input = {
+ uuid: Scalars['uuid']['input'];
+};
+
+/** select columns of table "message" */
+export enum Message_Select_Column {
+ /** column name */
+ Content = 'content',
+ /** column name */
+ CreatedAt = 'created_at',
+ /** column name */
+ ReplyToUuid = 'reply_to_uuid',
+ /** column name */
+ RoomUuid = 'room_uuid',
+ /** column name */
+ UserUuid = 'user_uuid',
+ /** column name */
+ Uuid = 'uuid'
+}
+
+/** input type for updating data in table "message" */
+export type Message_Set_Input = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** Streaming cursor of the table "message" */
+export type Message_Stream_Cursor_Input = {
+ /** Stream column input with initial value */
+ initial_value: Message_Stream_Cursor_Value_Input;
+ /** cursor ordering */
+ ordering?: InputMaybe;
+};
+
+/** Initial value of the column from where the streaming should start */
+export type Message_Stream_Cursor_Value_Input = {
+ content?: InputMaybe;
+ created_at?: InputMaybe;
+ reply_to_uuid?: InputMaybe;
+ room_uuid?: InputMaybe;
+ user_uuid?: InputMaybe;
+ uuid?: InputMaybe;
+};
+
+/** update columns of table "message" */
+export enum Message_Update_Column {
+ /** column name */
+ Content = 'content',
+ /** column name */
+ CreatedAt = 'created_at',
+ /** column name */
+ ReplyToUuid = 'reply_to_uuid',
+ /** column name */
+ RoomUuid = 'room_uuid',
+ /** column name */
+ UserUuid = 'user_uuid',
+ /** column name */
+ Uuid = 'uuid'
+}
+
+export type Message_Updates = {
+ /** sets the columns of the filtered rows to the given values */
+ _set?: InputMaybe;
+ /** filter the rows which have to be updated */
+ where: Message_Bool_Exp;
+};
+
+/** mutation root */
+export type Mutation_Root = {
+ __typename?: 'mutation_root';
+ /** delete data from the table: "message" */
+ delete_message?: Maybe;
+ /** delete single row from the table: "message" */
+ delete_message_by_pk?: Maybe;
+ /** delete data from the table: "room" */
+ delete_room?: Maybe;
+ /** delete single row from the table: "room" */
+ delete_room_by_pk?: Maybe;
+ /** delete data from the table: "user" */
+ delete_user?: Maybe;
+ /** delete single row from the table: "user" */
+ delete_user_by_pk?: Maybe;
+ /** delete data from the table: "user_room" */
+ delete_user_room?: Maybe;
+ /** delete single row from the table: "user_room" */
+ delete_user_room_by_pk?: Maybe;
+ /** insert data into the table: "message" */
+ insert_message?: Maybe;
+ /** insert a single row into the table: "message" */
+ insert_message_one?: Maybe;
+ /** insert data into the table: "room" */
+ insert_room?: Maybe;
+ /** insert a single row into the table: "room" */
+ insert_room_one?: Maybe;
+ /** insert data into the table: "user" */
+ insert_user?: Maybe;
+ /** insert a single row into the table: "user" */
+ insert_user_one?: Maybe;
+ /** insert data into the table: "user_room" */
+ insert_user_room?: Maybe;
+ /** insert a single row into the table: "user_room" */
+ insert_user_room_one?: Maybe;
+ /** update data of the table: "message" */
+ update_message?: Maybe;
+ /** update single row of the table: "message" */
+ update_message_by_pk?: Maybe;
+ /** update multiples rows of table: "message" */
+ update_message_many?: Maybe>>;
+ /** update data of the table: "room" */
+ update_room?: Maybe;
+ /** update single row of the table: "room" */
+ update_room_by_pk?: Maybe;
+ /** update multiples rows of table: "room" */
+ update_room_many?: Maybe>>;
+ /** update data of the table: "user" */
+ update_user?: Maybe;
+ /** update single row of the table: "user" */
+ update_user_by_pk?: Maybe;
+ /** update multiples rows of table: "user" */
+ update_user_many?: Maybe>>;
+ /** update data of the table: "user_room" */
+ update_user_room?: Maybe;
+ /** update single row of the table: "user_room" */
+ update_user_room_by_pk?: Maybe;
+ /** update multiples rows of table: "user_room" */
+ update_user_room_many?: Maybe>>;
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_MessageArgs = {
+ where: Message_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_Message_By_PkArgs = {
+ uuid: Scalars['uuid']['input'];
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_RoomArgs = {
+ where: Room_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_Room_By_PkArgs = {
+ uuid: Scalars['uuid']['input'];
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_UserArgs = {
+ where: User_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_User_By_PkArgs = {
+ uuid: Scalars['uuid']['input'];
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_User_RoomArgs = {
+ where: User_Room_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootDelete_User_Room_By_PkArgs = {
+ room_uuid: Scalars['uuid']['input'];
+ user_uuid: Scalars['uuid']['input'];
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_MessageArgs = {
+ objects: Array;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_Message_OneArgs = {
+ object: Message_Insert_Input;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_RoomArgs = {
+ objects: Array;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_Room_OneArgs = {
+ object: Room_Insert_Input;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_UserArgs = {
+ objects: Array;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_User_OneArgs = {
+ object: User_Insert_Input;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_User_RoomArgs = {
+ objects: Array;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootInsert_User_Room_OneArgs = {
+ object: User_Room_Insert_Input;
+ on_conflict?: InputMaybe;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_MessageArgs = {
+ _set?: InputMaybe;
+ where: Message_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_Message_By_PkArgs = {
+ _set?: InputMaybe;
+ pk_columns: Message_Pk_Columns_Input;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_Message_ManyArgs = {
+ updates: Array;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_RoomArgs = {
+ _set?: InputMaybe;
+ where: Room_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_Room_By_PkArgs = {
+ _set?: InputMaybe;
+ pk_columns: Room_Pk_Columns_Input;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_Room_ManyArgs = {
+ updates: Array;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_UserArgs = {
+ _set?: InputMaybe;
+ where: User_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_User_By_PkArgs = {
+ _set?: InputMaybe;
+ pk_columns: User_Pk_Columns_Input;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_User_ManyArgs = {
+ updates: Array;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_User_RoomArgs = {
+ _set?: InputMaybe;
+ where: User_Room_Bool_Exp;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_User_Room_By_PkArgs = {
+ _set?: InputMaybe;
+ pk_columns: User_Room_Pk_Columns_Input;
+};
+
+
+/** mutation root */
+export type Mutation_RootUpdate_User_Room_ManyArgs = {
+ updates: Array;
+};
+
+/** column ordering options */
+export enum Order_By {
+ /** in ascending order, nulls last */
+ Asc = 'asc',
+ /** in ascending order, nulls first */
+ AscNullsFirst = 'asc_nulls_first',
+ /** in ascending order, nulls last */
+ AscNullsLast = 'asc_nulls_last',
+ /** in descending order, nulls first */
+ Desc = 'desc',
+ /** in descending order, nulls first */
+ DescNullsFirst = 'desc_nulls_first',
+ /** in descending order, nulls last */
+ DescNullsLast = 'desc_nulls_last'
+}
+
+export type Query_Root = {
+ __typename?: 'query_root';
+ /** fetch data from the table: "message" */
+ message: Array;
+ /** fetch aggregated fields from the table: "message" */
+ message_aggregate: Message_Aggregate;
+ /** fetch data from the table: "message" using primary key columns */
+ message_by_pk?: Maybe;
+ /** fetch data from the table: "room" */
+ room: Array;
+ /** fetch aggregated fields from the table: "room" */
+ room_aggregate: Room_Aggregate;
+ /** fetch data from the table: "room" using primary key columns */
+ room_by_pk?: Maybe;
+ /** fetch data from the table: "user" */
+ user: Array;
+ /** fetch aggregated fields from the table: "user" */
+ user_aggregate: User_Aggregate;
+ /** fetch data from the table: "user" using primary key columns */
+ user_by_pk?: Maybe;
+ /** fetch data from the table: "user_room" */
+ user_room: Array