From 3bacf55ea0cbced8bb4be8be3d631aa513abad50 Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:42:38 +0100 Subject: [PATCH 01/16] Update format command to handle subdirectory Only the files in /src where formated with `yarn format` now the subfolder are also formated. + formating importCtf and savepointWrapper --- api/package.json | 2 +- api/src/plugins/importCtf.ts | 140 ++++++++++++++-------------- api/src/plugins/savepointWrapper.ts | 29 +++--- 3 files changed, 89 insertions(+), 82 deletions(-) diff --git a/api/package.json b/api/package.json index 45da6a043..e1084eb97 100644 --- a/api/package.json +++ b/api/package.json @@ -8,7 +8,7 @@ "start": "NODE_ENV=production node dist/index.js", "build": "tsc", "lint": "eslint --fix 'src/**/*.ts'", - "format": "prettier --write 'src/*.ts'", + "format": "prettier --write 'src/**/*.ts'", "dev": "NODE_ENV=development nodemon src/index.ts", "dev:migrate": "DATABASE_URL= yarn run db-migrate -e dev up" }, diff --git a/api/src/plugins/importCtf.ts b/api/src/plugins/importCtf.ts index 55486059a..ed66ec5ca 100644 --- a/api/src/plugins/importCtf.ts +++ b/api/src/plugins/importCtf.ts @@ -1,54 +1,57 @@ - import { makeExtendSchemaPlugin, gql } from "graphile-utils"; -import axios from "axios" -import savepointWrapper from "./savepointWrapper" +import axios from "axios"; +import savepointWrapper from "./savepointWrapper"; interface CTFTimeResponse { - title: string; - weight: number; - url: string, - logo: string, - ctftime_url: string, - description: string, - start: string, - finish: string + title: string; + weight: number; + url: string; + logo: string; + ctftime_url: string; + description: string; + start: string; + finish: string; } - async function fetchFromCtftime(id: number): Promise { - const url = `https://ctftime.org/api/v1/events/${id}/`; - const response = await axios.get(url, { - headers: { "User-Agent": "CTFNote" }, // The default axios user-agent is blacklisted by ctftime :/ - }); - return response.data + const url = `https://ctftime.org/api/v1/events/${id}/`; + const response = await axios.get(url, { + headers: { "User-Agent": "CTFNote" }, // The default axios user-agent is blacklisted by ctftime :/ + }); + return response.data; } +export default makeExtendSchemaPlugin((build) => { + const { pgSql: sql } = build; + return { + typeDefs: gql` + input ImportCtfInput { + ctftimeId: Int! + } -export default makeExtendSchemaPlugin(build => { - const { pgSql: sql } = build; - return { - typeDefs: gql` - - input ImportCtfInput { - ctftimeId: Int! - } - - type ImportCtfPayload { - ctf: Ctf @pgField - query: Query - } + type ImportCtfPayload { + ctf: Ctf @pgField + query: Query + } - extend type Mutation { - importCtf(input: ImportCtfInput) : ImportCtfPayload - } - `, - resolvers: { - Mutation: { - importCtf: async (_query, { input: { ctftimeId } }, { pgClient }, resolveInfo) => { - const ctf = await fetchFromCtftime(ctftimeId) - await savepointWrapper(pgClient, async () => { - const { rows: [newCtf] } = await pgClient.query( - `INSERT INTO ctfnote.ctf( + extend type Mutation { + importCtf(input: ImportCtfInput): ImportCtfPayload + } + `, + resolvers: { + Mutation: { + importCtf: async ( + _query, + { input: { ctftimeId } }, + { pgClient }, + resolveInfo + ) => { + const ctf = await fetchFromCtftime(ctftimeId); + await savepointWrapper(pgClient, async () => { + const { + rows: [newCtf], + } = await pgClient.query( + `INSERT INTO ctfnote.ctf( title, weight, ctf_url, @@ -60,32 +63,33 @@ export default makeExtendSchemaPlugin(build => { ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *; `, - [ - ctf.title, - ctf.weight, - ctf.url, - ctf.logo, - ctf.ctftime_url, - ctf.description, - ctf.start, - ctf.finish, - ] - ) - const [row] = await resolveInfo.graphile.selectGraphQLResultFromTable( - sql.fragment`ctfnote.ctf`, - (tableAlias, queryBuilder) => { - queryBuilder.where( - sql.fragment`${tableAlias}.id = ${sql.value(newCtf.id)}` - ); - } - ) - return { - data: row, - query: build.$$isQuery, - }; - }) - }, - }, + [ + ctf.title, + ctf.weight, + ctf.url, + ctf.logo, + ctf.ctftime_url, + ctf.description, + ctf.start, + ctf.finish, + ] + ); + const [row] = + await resolveInfo.graphile.selectGraphQLResultFromTable( + sql.fragment`ctfnote.ctf`, + (tableAlias, queryBuilder) => { + queryBuilder.where( + sql.fragment`${tableAlias}.id = ${sql.value(newCtf.id)}` + ); + } + ); + return { + data: row, + query: build.$$isQuery, + }; + }); }, - }; + }, + }, + }; }); diff --git a/api/src/plugins/savepointWrapper.ts b/api/src/plugins/savepointWrapper.ts index fbf5e1927..9eeb696bb 100644 --- a/api/src/plugins/savepointWrapper.ts +++ b/api/src/plugins/savepointWrapper.ts @@ -1,16 +1,19 @@ -import { Client } from "pg" +import { Client } from "pg"; -async function savepointWrapper(pgClient: Client, f: () => void): Promise { - const name = `"CHECKPOINT-${Math.floor(Math.random() * 0xffff)}"` - await pgClient.query(`SAVEPOINT ${name}`); - try { - await f() - } catch (e) { - await pgClient.query(`ROLLBACK TO SAVEPOINT ${name}`); - throw e; - } finally { - await pgClient.query(`RELEASE SAVEPOINT ${name}`); - } +async function savepointWrapper( + pgClient: Client, + f: () => void +): Promise { + const name = `"CHECKPOINT-${Math.floor(Math.random() * 0xffff)}"`; + await pgClient.query(`SAVEPOINT ${name}`); + try { + await f(); + } catch (e) { + await pgClient.query(`ROLLBACK TO SAVEPOINT ${name}`); + throw e; + } finally { + await pgClient.query(`RELEASE SAVEPOINT ${name}`); + } } -export default savepointWrapper; \ No newline at end of file +export default savepointWrapper; From ece1bf94eeeac586a3ef02272544cae9b3aa227a Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:43:08 +0100 Subject: [PATCH 02/16] removed useless parameters --- api/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/index.ts b/api/src/index.ts index 100d30619..d7ab7f825 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -70,7 +70,7 @@ function createApp(postgraphileOptions: PostGraphileOptions) { app.use( "/uploads", express.static("uploads", { - setHeaders: function (res, path, stat) { + setHeaders: function (res) { res.set("Content-Disposition", "attachment"); }, }) From cd9382ddf7706ae3b3a2d6fd89ed22c5f5c7a56a Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:46:11 +0100 Subject: [PATCH 03/16] Format front --- front/src/components/CTF/Guests.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/front/src/components/CTF/Guests.vue b/front/src/components/CTF/Guests.vue index 5322675eb..8d5c2e80a 100644 --- a/front/src/components/CTF/Guests.vue +++ b/front/src/components/CTF/Guests.vue @@ -58,7 +58,11 @@ export default defineComponent({ }, computed: { guests() { - return this.team.filter((p) => p.role == Role.UserGuest || (p.role == Role.UserFriend && this.ctf.endTime > this.now)); + return this.team.filter( + (p) => + p.role == Role.UserGuest || + (p.role == Role.UserFriend && this.ctf.endTime > this.now) + ); }, guestsWithInvitation() { return this.guests.map((g) => { From e76e646335c26709d8cb38cf01d97f2a5e098f20 Mon Sep 17 00:00:00 2001 From: SakiiR SakiiR Date: Thu, 16 Dec 2021 17:18:43 +0100 Subject: [PATCH 04/16] Base search migrations & front dialog --- api/migrations/39-search-ctfs.sql | 18 + api/migrations/40-search-tasks.sql | 16 + front/graphql.schema.json | 176 ++++++ front/src/App.vue | 15 + front/src/apollo/index.ts | 5 +- front/src/components/Dialogs/SearchDialog.vue | 57 ++ front/src/ctfnote/auth.ts | 6 +- front/src/ctfnote/index.ts | 2 + front/src/ctfnote/search.ts | 12 + front/src/generated/graphql.ts | 593 +++++++++++------- front/src/graphql/Search.graphql | 19 + 11 files changed, 680 insertions(+), 239 deletions(-) create mode 100644 api/migrations/39-search-ctfs.sql create mode 100644 api/migrations/40-search-tasks.sql create mode 100644 front/src/components/Dialogs/SearchDialog.vue create mode 100644 front/src/ctfnote/search.ts create mode 100644 front/src/graphql/Search.graphql diff --git a/api/migrations/39-search-ctfs.sql b/api/migrations/39-search-ctfs.sql new file mode 100644 index 000000000..c094c3a52 --- /dev/null +++ b/api/migrations/39-search-ctfs.sql @@ -0,0 +1,18 @@ +CREATE OR REPLACE FUNCTION ctfnote.search_ctfs (search text) + RETURNS SETOF ctfnote.ctf + AS $$ + SELECT + * + FROM + ctfnote.ctf + AS + ctf + WHERE + ctf.title ilike ('%' || search || '%') + OR + ctf.description ilike ('%' || search || '%') ; +$$ +LANGUAGE SQL +STABLE; + +GRANT EXECUTE ON FUNCTION ctfnote.search_ctfs TO user_guest; diff --git a/api/migrations/40-search-tasks.sql b/api/migrations/40-search-tasks.sql new file mode 100644 index 000000000..94e91f679 --- /dev/null +++ b/api/migrations/40-search-tasks.sql @@ -0,0 +1,16 @@ +CREATE OR REPLACE FUNCTION ctfnote.search_tasks (search text) + RETURNS SETOF ctfnote.task + AS $$ + SELECT + * + FROM + ctfnote.task + AS + task + WHERE + task.title ilike ('%' || search || '%'); +$$ +LANGUAGE SQL +STABLE; + +GRANT EXECUTE ON FUNCTION ctfnote.search_tasks TO user_guest; diff --git a/front/graphql.schema.json b/front/graphql.schema.json index a37fcd22d..d2e7456c8 100644 --- a/front/graphql.schema.json +++ b/front/graphql.schema.json @@ -6002,6 +6002,176 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "searchCtfs", + "description": "Reads and enables pagination through a set of `Ctf`.", + "args": [ + { + "name": "after", + "description": "Read all values in the set after (below) this cursor.", + "type": { + "kind": "SCALAR", + "name": "Cursor", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "before", + "description": "Read all values in the set before (above) this cursor.", + "type": { + "kind": "SCALAR", + "name": "Cursor", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "first", + "description": "Only read the first `n` values of the set.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "last", + "description": "Only read the last `n` values of the set.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "offset", + "description": "Skip the first `n` values from our `after` cursor, an alternative to cursor\nbased pagination. May not be used with `last`.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "search", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CtfsConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "searchTasks", + "description": "Reads and enables pagination through a set of `Task`.", + "args": [ + { + "name": "after", + "description": "Read all values in the set after (below) this cursor.", + "type": { + "kind": "SCALAR", + "name": "Cursor", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "before", + "description": "Read all values in the set before (above) this cursor.", + "type": { + "kind": "SCALAR", + "name": "Cursor", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "first", + "description": "Only read the first `n` values of the set.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "last", + "description": "Only read the last `n` values of the set.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "offset", + "description": "Skip the first `n` values from our `after` cursor, an alternative to cursor\nbased pagination. May not be used with `last`.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "search", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "TasksConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "settingByNodeId", "description": "Reads a single `Setting` using its globally unique `ID`.", @@ -7028,6 +7198,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "USER_FRIEND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "USER_GUEST", "description": null, diff --git a/front/src/App.vue b/front/src/App.vue index ae455124a..99c496a0f 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -5,10 +5,25 @@ import { useGlobalQueryLoading } from '@vue/apollo-composable'; import { defineComponent, watch } from 'vue'; +import SearchDialog from 'src/components/Dialogs/SearchDialog.vue'; + export default defineComponent({ name: 'App', mounted() { const loading = useGlobalQueryLoading(); + + // Maybe we want to move this listener somewhere else + // Because this will be rendered/executed when the user is not authenticated as well + document.addEventListener('keyup', (e: KeyboardEvent) => { + if (!(e.ctrlKey && e.key == 'k')) return; + + e.preventDefault(); + + this.$q.dialog({ + component: SearchDialog, + }); + }); + watch( loading, (isLoading) => { diff --git a/front/src/apollo/index.ts b/front/src/apollo/index.ts index e02c7a676..ede061a86 100644 --- a/front/src/apollo/index.ts +++ b/front/src/apollo/index.ts @@ -5,6 +5,7 @@ import { WebSocketLink } from '@apollo/client/link/ws'; import { getMainDefinition } from '@apollo/client/utilities'; import { createUploadLink } from 'apollo-upload-client'; import { extractFiles } from 'extract-files'; +import { JWT_KEY } from 'src/ctfnote/auth'; const protocol = document.location.protocol == 'https:' ? 'wss:' : 'ws:'; @@ -15,7 +16,7 @@ const wsLink = new WebSocketLink({ reconnect: true, lazy: true, connectionParams: () => { - const token = localStorage.getItem('JWT'); + const token = localStorage.getItem(JWT_KEY); return { Authorization: token ? `Bearer ${token}` : '', }; @@ -54,7 +55,7 @@ const splitLink = split( const link = from([ new ApolloLink((operation, forward) => { - const token = localStorage.getItem('JWT'); + const token = localStorage.getItem(JWT_KEY); if (token) { operation.setContext( ({ headers }: { headers: { [key: string]: string } }) => ({ diff --git a/front/src/components/Dialogs/SearchDialog.vue b/front/src/components/Dialogs/SearchDialog.vue new file mode 100644 index 000000000..87f18fcd8 --- /dev/null +++ b/front/src/components/Dialogs/SearchDialog.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/front/src/ctfnote/auth.ts b/front/src/ctfnote/auth.ts index 9b67f0002..20d689e26 100644 --- a/front/src/ctfnote/auth.ts +++ b/front/src/ctfnote/auth.ts @@ -11,7 +11,7 @@ import { useRouter } from 'vue-router'; import { prefetchMe } from './me'; -const JWT_KEY = 'JWT'; +export const JWT_KEY = 'JWT'; export function saveJWT(jwt: string | null | undefined) { if (!jwt) { @@ -33,11 +33,11 @@ export async function refreshJWT(): Promise { const token = result.data.newToken; if (token) { - localStorage.setItem('JWT', token); + localStorage.setItem(JWT_KEY, token); return true; } else { return false; -} + } } /* Mutations */ diff --git a/front/src/ctfnote/index.ts b/front/src/ctfnote/index.ts index b4c2c8b0b..c461e85ca 100644 --- a/front/src/ctfnote/index.ts +++ b/front/src/ctfnote/index.ts @@ -8,6 +8,7 @@ import * as tasks from './tasks'; import * as ui from './ui'; import * as utils from './utils'; import * as uploads from './uploads'; +import * as search from './search'; export const ctfnote = { profiles, @@ -20,6 +21,7 @@ export const ctfnote = { tasks, utils, uploads, + search, }; export type Ctfnote = typeof ctfnote; diff --git a/front/src/ctfnote/search.ts b/front/src/ctfnote/search.ts new file mode 100644 index 000000000..19dbcad8b --- /dev/null +++ b/front/src/ctfnote/search.ts @@ -0,0 +1,12 @@ +import { useSearchCtFsQuery } from 'src/generated/graphql'; +import { wrapQuery } from 'src/ctfnote/utils'; +import { buildCtf } from './ctfs'; + +export function useSearchCtfs(search: string) { + const q = useSearchCtFsQuery({ search }); + + const query = wrapQuery(q, null, (data) => { + return data.searchCtfs.edges.map(e => buildCtf(e.node)); + }); + return query; +} \ No newline at end of file diff --git a/front/src/generated/graphql.ts b/front/src/generated/graphql.ts index b918bbc18..b6e0781bd 100644 --- a/front/src/generated/graphql.ts +++ b/front/src/generated/graphql.ts @@ -2,6 +2,7 @@ import gql from 'graphql-tag'; import * as VueApolloComposable from '@vue/apollo-composable'; import * as VueCompositionApi from 'vue'; 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 }; @@ -37,7 +38,7 @@ export type ChangePasswordInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; newpassword: Scalars['String']; oldpassword: Scalars['String']; }; @@ -66,7 +67,7 @@ export type CreateCtfInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The `Ctf` to be created by this mutation. */ ctf: CtfInput; }; @@ -92,7 +93,7 @@ export type CreateCtfPayload = { /** The output of our create `Ctf` mutation. */ export type CreateCtfPayloadCtfEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the create `Invitation` mutation. */ @@ -101,7 +102,7 @@ export type CreateInvitationInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The `Invitation` to be created by this mutation. */ invitation: InvitationInput; }; @@ -112,8 +113,8 @@ export type CreateInvitationLinkInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - role?: Maybe; + clientMutationId?: InputMaybe; + role?: InputMaybe; }; /** The output of our `createInvitationLink` mutation. */ @@ -152,7 +153,7 @@ export type CreateInvitationPayload = { /** The output of our create `Invitation` mutation. */ export type CreateInvitationPayloadInvitationEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `createResetPasswordLink` mutation. */ @@ -161,8 +162,8 @@ export type CreateResetPasswordLinkInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - userId?: Maybe; + clientMutationId?: InputMaybe; + userId?: InputMaybe; }; /** The output of our `createResetPasswordLink` mutation. */ @@ -179,10 +180,10 @@ export type CreateResetPasswordLinkPayload = { }; export type CreateTaskInput = { - category?: Maybe; + category?: InputMaybe; ctfId: Scalars['Int']; - description?: Maybe; - flag?: Maybe; + description?: InputMaybe; + flag?: InputMaybe; title: Scalars['String']; }; @@ -217,60 +218,60 @@ export type Ctf = Node & { export type CtfInvitationsArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; export type CtfTasksArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** A condition to be used against `Ctf` object types. All fields are tested for equality and combined with a logical ‘and.’ */ export type CtfCondition = { /** Checks for equality with the object’s `endTime` field. */ - endTime?: Maybe; + endTime?: InputMaybe; /** Checks for equality with the object’s `id` field. */ - id?: Maybe; + id?: InputMaybe; /** Checks for equality with the object’s `secretsId` field. */ - secretsId?: Maybe; + secretsId?: InputMaybe; /** Checks for equality with the object’s `startTime` field. */ - startTime?: Maybe; + startTime?: InputMaybe; }; /** An input for mutations affecting `Ctf` */ export type CtfInput = { - ctfUrl?: Maybe; - ctftimeUrl?: Maybe; - description?: Maybe; + ctfUrl?: InputMaybe; + ctftimeUrl?: InputMaybe; + description?: InputMaybe; endTime: Scalars['Datetime']; - logoUrl?: Maybe; + logoUrl?: InputMaybe; startTime: Scalars['Datetime']; title: Scalars['String']; - weight?: Maybe; + weight?: InputMaybe; }; /** Represents an update to a `Ctf`. Fields that are set will be updated. */ export type CtfPatch = { - ctfUrl?: Maybe; - ctftimeUrl?: Maybe; - description?: Maybe; - endTime?: Maybe; - logoUrl?: Maybe; - startTime?: Maybe; - title?: Maybe; - weight?: Maybe; + ctfUrl?: InputMaybe; + ctftimeUrl?: InputMaybe; + description?: InputMaybe; + endTime?: InputMaybe; + logoUrl?: InputMaybe; + startTime?: InputMaybe; + title?: InputMaybe; + weight?: InputMaybe; }; export type CtfSecret = Node & { @@ -285,13 +286,13 @@ export type CtfSecret = Node & { export type CtfSecretCtfsBySecretsIdArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** @@ -300,12 +301,12 @@ export type CtfSecretCtfsBySecretsIdArgs = { */ export type CtfSecretCondition = { /** Checks for equality with the object’s `id` field. */ - id?: Maybe; + id?: InputMaybe; }; /** Represents an update to a `CtfSecret`. Fields that are set will be updated. */ export type CtfSecretPatch = { - credentials?: Maybe; + credentials?: InputMaybe; }; /** A connection to a list of `CtfSecret` values. */ @@ -382,7 +383,7 @@ export type DeleteCtfByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Ctf` to be deleted. */ nodeId: Scalars['ID']; }; @@ -393,7 +394,7 @@ export type DeleteCtfInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; }; @@ -419,7 +420,7 @@ export type DeleteCtfPayload = { /** The output of our delete `Ctf` mutation. */ export type DeleteCtfPayloadCtfEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `deleteInvitationByNodeId` mutation. */ @@ -428,7 +429,7 @@ export type DeleteInvitationByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Invitation` to be deleted. */ nodeId: Scalars['ID']; }; @@ -439,7 +440,7 @@ export type DeleteInvitationInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; ctfId: Scalars['Int']; profileId: Scalars['Int']; }; @@ -468,7 +469,7 @@ export type DeleteInvitationPayload = { /** The output of our delete `Invitation` mutation. */ export type DeleteInvitationPayloadInvitationEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `deleteTaskByNodeId` mutation. */ @@ -477,7 +478,7 @@ export type DeleteTaskByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Task` to be deleted. */ nodeId: Scalars['ID']; }; @@ -488,7 +489,7 @@ export type DeleteTaskInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; }; @@ -514,7 +515,7 @@ export type DeleteTaskPayload = { /** The output of our delete `Task` mutation. */ export type DeleteTaskPayloadTaskEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `deleteUser` mutation. */ @@ -523,8 +524,8 @@ export type DeleteUserInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - userId?: Maybe; + clientMutationId?: InputMaybe; + userId?: InputMaybe; }; /** The output of our `deleteUser` mutation. */ @@ -568,9 +569,9 @@ export type Invitation = Node & { */ export type InvitationCondition = { /** Checks for equality with the object’s `ctfId` field. */ - ctfId?: Maybe; + ctfId?: InputMaybe; /** Checks for equality with the object’s `profileId` field. */ - profileId?: Maybe; + profileId?: InputMaybe; }; /** An input for mutations affecting `Invitation` */ @@ -631,7 +632,7 @@ export type LoginInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; login: Scalars['String']; password: Scalars['String']; }; @@ -738,7 +739,7 @@ export type MutationCreateResetPasswordLinkArgs = { /** The root mutation type which contains root level fields which mutate data. */ export type MutationCreateTaskArgs = { - input?: Maybe; + input?: InputMaybe; }; @@ -786,7 +787,7 @@ export type MutationDeleteUserArgs = { /** The root mutation type which contains root level fields which mutate data. */ export type MutationImportCtfArgs = { - input?: Maybe; + input?: InputMaybe; }; @@ -939,39 +940,39 @@ export type Profile = Node & { export type ProfileInvitationsArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; export type ProfileWorkOnTasksArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** A condition to be used against `Profile` object types. All fields are tested for equality and combined with a logical ‘and.’ */ export type ProfileCondition = { /** Checks for equality with the object’s `id` field. */ - id?: Maybe; + id?: InputMaybe; /** Checks for equality with the object’s `username` field. */ - username?: Maybe; + username?: InputMaybe; }; /** Represents an update to a `Profile`. Fields that are set will be updated. */ export type ProfilePatch = { - color?: Maybe; - description?: Maybe; - username?: Maybe; + color?: InputMaybe; + description?: InputMaybe; + username?: InputMaybe; }; /** A connection to a list of `Profile` values. */ @@ -1048,6 +1049,10 @@ export type Query = Node & { * which can only query top level fields if they are in a particular form. */ query: Query; + /** Reads and enables pagination through a set of `Ctf`. */ + searchCtfs?: Maybe; + /** Reads and enables pagination through a set of `Task`. */ + searchTasks?: Maybe; /** Reads a single `Setting` using its globally unique `ID`. */ settingByNodeId?: Maybe; /** Reads and enables pagination through a set of `Setting`. */ @@ -1093,45 +1098,45 @@ export type QueryCtfSecretByNodeIdArgs = { /** The root query type which gives access points into the data universe. */ export type QueryCtfSecretsArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** The root query type which gives access points into the data universe. */ export type QueryCtfsArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** The root query type which gives access points into the data universe. */ export type QueryGuestsArgs = { - after?: Maybe; - before?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; }; /** The root query type which gives access points into the data universe. */ export type QueryIncomingCtfArgs = { - after?: Maybe; - before?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; }; @@ -1150,13 +1155,13 @@ export type QueryInvitationByNodeIdArgs = { /** The root query type which gives access points into the data universe. */ export type QueryInvitationsArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; @@ -1168,11 +1173,11 @@ export type QueryNodeArgs = { /** The root query type which gives access points into the data universe. */ export type QueryPastCtfArgs = { - after?: Maybe; - before?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; }; @@ -1196,13 +1201,35 @@ export type QueryProfileByUsernameArgs = { /** The root query type which gives access points into the data universe. */ export type QueryProfilesArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; +}; + + +/** The root query type which gives access points into the data universe. */ +export type QuerySearchCtfsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + search?: InputMaybe; +}; + + +/** The root query type which gives access points into the data universe. */ +export type QuerySearchTasksArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + search?: InputMaybe; }; @@ -1214,12 +1241,12 @@ export type QuerySettingByNodeIdArgs = { /** The root query type which gives access points into the data universe. */ export type QuerySettingsArgs = { - after?: Maybe; - before?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; @@ -1237,24 +1264,24 @@ export type QueryTaskByNodeIdArgs = { /** The root query type which gives access points into the data universe. */ export type QueryTasksArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** The root query type which gives access points into the data universe. */ export type QueryUsersArgs = { - after?: Maybe; - before?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; @@ -1273,13 +1300,13 @@ export type QueryWorkOnTaskByNodeIdArgs = { /** The root query type which gives access points into the data universe. */ export type QueryWorkOnTasksArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** All input for the `register` mutation. */ @@ -1288,7 +1315,7 @@ export type RegisterInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; login: Scalars['String']; password: Scalars['String']; }; @@ -1312,7 +1339,7 @@ export type RegisterWithPasswordInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; ctfnotePassword: Scalars['String']; login: Scalars['String']; password: Scalars['String']; @@ -1337,10 +1364,10 @@ export type RegisterWithTokenInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - login?: Maybe; - password?: Maybe; - token?: Maybe; + clientMutationId?: InputMaybe; + login?: InputMaybe; + password?: InputMaybe; + token?: InputMaybe; }; /** The output of our `registerWithToken` mutation. */ @@ -1362,9 +1389,9 @@ export type ResetPasswordInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - password?: Maybe; - token?: Maybe; + clientMutationId?: InputMaybe; + password?: InputMaybe; + token?: InputMaybe; }; export type ResetPasswordLinkResponse = { @@ -1387,10 +1414,10 @@ export type ResetPasswordPayload = { export enum Role { UserAdmin = 'USER_ADMIN', + UserFriend = 'USER_FRIEND', UserGuest = 'USER_GUEST', UserManager = 'USER_MANAGER', - UserMember = 'USER_MEMBER', - UserFriend = 'USER_FRIEND', + UserMember = 'USER_MEMBER' } export type Setting = Node & { @@ -1406,11 +1433,11 @@ export type Setting = Node & { /** Represents an update to a `Setting`. Fields that are set will be updated. */ export type SettingPatch = { - registrationAllowed?: Maybe; - registrationDefaultRole?: Maybe; - registrationPassword?: Maybe; - registrationPasswordAllowed?: Maybe; - style?: Maybe; + registrationAllowed?: InputMaybe; + registrationDefaultRole?: InputMaybe; + registrationPassword?: InputMaybe; + registrationPasswordAllowed?: InputMaybe; + style?: InputMaybe; }; /** A connection to a list of `Setting` values. */ @@ -1448,8 +1475,8 @@ export type StartWorkingOnInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - taskId?: Maybe; + clientMutationId?: InputMaybe; + taskId?: InputMaybe; }; /** The output of our `startWorkingOn` mutation. */ @@ -1474,7 +1501,7 @@ export type StartWorkingOnPayload = { /** The output of our `startWorkingOn` mutation. */ export type StartWorkingOnPayloadWorkOnTaskEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `stopWorkingOn` mutation. */ @@ -1483,8 +1510,8 @@ export type StopWorkingOnInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - taskId?: Maybe; + clientMutationId?: InputMaybe; + taskId?: InputMaybe; }; /** The output of our `stopWorkingOn` mutation. */ @@ -1509,7 +1536,7 @@ export type StopWorkingOnPayload = { /** The output of our `stopWorkingOn` mutation. */ export type StopWorkingOnPayloadWorkOnTaskEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** The root subscription type: contains realtime events you can subscribe to with the `subscription` operation. */ @@ -1544,29 +1571,29 @@ export type Task = Node & { export type TaskWorkOnTasksArgs = { - after?: Maybe; - before?: Maybe; - condition?: Maybe; - first?: Maybe; - last?: Maybe; - offset?: Maybe; - orderBy?: Maybe>; + after?: InputMaybe; + before?: InputMaybe; + condition?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + offset?: InputMaybe; + orderBy?: InputMaybe>; }; /** A condition to be used against `Task` object types. All fields are tested for equality and combined with a logical ‘and.’ */ export type TaskCondition = { /** Checks for equality with the object’s `ctfId` field. */ - ctfId?: Maybe; + ctfId?: InputMaybe; /** Checks for equality with the object’s `id` field. */ - id?: Maybe; + id?: InputMaybe; }; /** Represents an update to a `Task`. Fields that are set will be updated. */ export type TaskPatch = { - category?: Maybe; - description?: Maybe; - flag?: Maybe; - title?: Maybe; + category?: InputMaybe; + description?: InputMaybe; + flag?: InputMaybe; + title?: InputMaybe; }; /** A connection to a list of `Task` values. */ @@ -1608,7 +1635,7 @@ export type UpdateCtfByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Ctf` to be updated. */ nodeId: Scalars['ID']; /** An object where the defined keys will be set on the `Ctf` being updated. */ @@ -1621,7 +1648,7 @@ export type UpdateCtfInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; /** An object where the defined keys will be set on the `Ctf` being updated. */ patch: CtfPatch; @@ -1648,7 +1675,7 @@ export type UpdateCtfPayload = { /** The output of our update `Ctf` mutation. */ export type UpdateCtfPayloadCtfEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `updateCtfSecretByNodeId` mutation. */ @@ -1657,7 +1684,7 @@ export type UpdateCtfSecretByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `CtfSecret` to be updated. */ nodeId: Scalars['ID']; /** An object where the defined keys will be set on the `CtfSecret` being updated. */ @@ -1670,7 +1697,7 @@ export type UpdateCtfSecretInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; /** An object where the defined keys will be set on the `CtfSecret` being updated. */ patch: CtfSecretPatch; @@ -1695,7 +1722,7 @@ export type UpdateCtfSecretPayload = { /** The output of our update `CtfSecret` mutation. */ export type UpdateCtfSecretPayloadCtfSecretEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `updateProfileByNodeId` mutation. */ @@ -1704,7 +1731,7 @@ export type UpdateProfileByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Profile` to be updated. */ nodeId: Scalars['ID']; /** An object where the defined keys will be set on the `Profile` being updated. */ @@ -1717,7 +1744,7 @@ export type UpdateProfileByUsernameInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** An object where the defined keys will be set on the `Profile` being updated. */ patch: ProfilePatch; username: Scalars['String']; @@ -1729,7 +1756,7 @@ export type UpdateProfileInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; /** An object where the defined keys will be set on the `Profile` being updated. */ patch: ProfilePatch; @@ -1754,7 +1781,7 @@ export type UpdateProfilePayload = { /** The output of our update `Profile` mutation. */ export type UpdateProfilePayloadProfileEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `updateSettingByNodeId` mutation. */ @@ -1763,7 +1790,7 @@ export type UpdateSettingByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Setting` to be updated. */ nodeId: Scalars['ID']; /** An object where the defined keys will be set on the `Setting` being updated. */ @@ -1789,7 +1816,7 @@ export type UpdateSettingPayload = { /** The output of our update `Setting` mutation. */ export type UpdateSettingPayloadSettingEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `updateTaskByNodeId` mutation. */ @@ -1798,7 +1825,7 @@ export type UpdateTaskByNodeIdInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; /** The globally unique `ID` which will identify a single `Task` to be updated. */ nodeId: Scalars['ID']; /** An object where the defined keys will be set on the `Task` being updated. */ @@ -1811,7 +1838,7 @@ export type UpdateTaskInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; + clientMutationId?: InputMaybe; id: Scalars['Int']; /** An object where the defined keys will be set on the `Task` being updated. */ patch: TaskPatch; @@ -1838,7 +1865,7 @@ export type UpdateTaskPayload = { /** The output of our update `Task` mutation. */ export type UpdateTaskPayloadTaskEdgeArgs = { - orderBy?: Maybe>; + orderBy?: InputMaybe>; }; /** All input for the `updateUserRole` mutation. */ @@ -1847,9 +1874,9 @@ export type UpdateUserRoleInput = { * An arbitrary string value with no semantic meaning. Will be included in the * payload verbatim. May be used to track mutations by the client. */ - clientMutationId?: Maybe; - role?: Maybe; - userId?: Maybe; + clientMutationId?: InputMaybe; + role?: InputMaybe; + userId?: InputMaybe; }; /** The output of our `updateUserRole` mutation. */ @@ -1926,9 +1953,9 @@ export type WorkOnTask = Node & { */ export type WorkOnTaskCondition = { /** Checks for equality with the object’s `profileId` field. */ - profileId?: Maybe; + profileId?: InputMaybe; /** Checks for equality with the object’s `taskId` field. */ - taskId?: Maybe; + taskId?: InputMaybe; }; /** A connection to a list of `WorkOnTask` values. */ @@ -2079,8 +2106,8 @@ export type IncomingCtfsQueryVariables = Exact<{ [key: string]: never; }>; export type IncomingCtfsQuery = { __typename?: 'Query', incomingCtf?: { __typename?: 'CtfsConnection', nodes: Array<{ __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string }> } | null | undefined }; export type PastCtfsQueryVariables = Exact<{ - first?: Maybe; - offset?: Maybe; + first?: InputMaybe; + offset?: InputMaybe; }>; @@ -2090,11 +2117,11 @@ export type CreateCtfMutationVariables = Exact<{ title: Scalars['String']; startTime: Scalars['Datetime']; endTime: Scalars['Datetime']; - weight?: Maybe; - ctfUrl?: Maybe; - ctftimeUrl?: Maybe; - logoUrl?: Maybe; - description?: Maybe; + weight?: InputMaybe; + ctfUrl?: InputMaybe; + ctftimeUrl?: InputMaybe; + logoUrl?: InputMaybe; + description?: InputMaybe; }>; @@ -2116,14 +2143,14 @@ export type ImportctfMutation = { __typename?: 'Mutation', importCtf?: { __typen export type UpdateCtfByIdMutationVariables = Exact<{ id: Scalars['Int']; - title?: Maybe; - weight?: Maybe; - ctfUrl?: Maybe; - ctftimeUrl?: Maybe; - logoUrl?: Maybe; - startTime?: Maybe; - endTime?: Maybe; - description?: Maybe; + title?: InputMaybe; + weight?: InputMaybe; + ctfUrl?: InputMaybe; + ctftimeUrl?: InputMaybe; + logoUrl?: InputMaybe; + startTime?: InputMaybe; + endTime?: InputMaybe; + description?: InputMaybe; }>; @@ -2200,6 +2227,20 @@ export type SubscribeToProfileDeletedSubscriptionVariables = Exact<{ [key: strin export type SubscribeToProfileDeletedSubscription = { __typename?: 'Subscription', listen: { __typename?: 'ListenPayload', relatedNodeId?: string | null | undefined, relatedNode?: { __typename?: 'Ctf', nodeId: string } | { __typename?: 'CtfSecret', nodeId: string } | { __typename?: 'Invitation', nodeId: string } | { __typename?: 'Profile', nodeId: string, id: number, username: string, color?: string | null | undefined, description: string, role?: Role | null | undefined } | { __typename?: 'Query', nodeId: string } | { __typename?: 'Setting', nodeId: string } | { __typename?: 'Task', nodeId: string } | { __typename?: 'WorkOnTask', nodeId: string } | null | undefined } }; +export type SearchCtFsQueryVariables = Exact<{ + search: Scalars['String']; +}>; + + +export type SearchCtFsQuery = { __typename?: 'Query', searchCtfs?: { __typename?: 'CtfsConnection', edges: Array<{ __typename?: 'CtfsEdge', node: { __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string } }> } | null | undefined }; + +export type SearchTasksQueryVariables = Exact<{ + search: Scalars['String']; +}>; + + +export type SearchTasksQuery = { __typename?: 'Query', searchTasks?: { __typename?: 'TasksConnection', edges: Array<{ __typename?: 'TasksEdge', node: { __typename?: 'Task', nodeId: string, id: number, title: string, ctfId: number, padUrl: string, description: string, flag: string, solved?: boolean | null | undefined, category: string, workOnTasks: { __typename?: 'WorkOnTasksConnection', nodes: Array<{ __typename?: 'WorkOnTask', nodeId: string, profileId: number, profile?: { __typename?: 'Profile', id: number, username: string, color?: string | null | undefined, description: string, role?: Role | null | undefined, nodeId: string } | null | undefined }> } } }> } | null | undefined }; + export type CtfSecretFragment = { __typename?: 'CtfSecret', nodeId: string, credentials?: string | null | undefined }; export type GetCredentialsForCtfIdQueryVariables = Exact<{ @@ -2211,7 +2252,7 @@ export type GetCredentialsForCtfIdQuery = { __typename?: 'Query', ctfSecret?: { export type UpdateCredentialsForCtfIdMutationVariables = Exact<{ ctfId: Scalars['Int']; - credentials?: Maybe; + credentials?: InputMaybe; }>; @@ -2259,10 +2300,10 @@ export type TaskByIdQuery = { __typename?: 'Query', task?: { __typename?: 'Task' export type UpdateTaskMutationVariables = Exact<{ id: Scalars['Int']; - title?: Maybe; - description?: Maybe; - category?: Maybe; - flag?: Maybe; + title?: InputMaybe; + description?: InputMaybe; + category?: InputMaybe; + flag?: InputMaybe; }>; @@ -2271,9 +2312,9 @@ export type UpdateTaskMutation = { __typename?: 'Mutation', updateTask?: { __typ export type CreateTaskForCtfIdMutationVariables = Exact<{ ctfId: Scalars['Int']; title: Scalars['String']; - category?: Maybe; - description?: Maybe; - flag?: Maybe; + category?: InputMaybe; + description?: InputMaybe; + flag?: InputMaybe; }>; @@ -3385,6 +3426,68 @@ export function useSubscribeToProfileDeletedSubscription(options: VueApolloCompo return VueApolloComposable.useSubscription(SubscribeToProfileDeletedDocument, {}, options); } export type SubscribeToProfileDeletedSubscriptionCompositionFunctionResult = VueApolloComposable.UseSubscriptionReturn; +export const SearchCtFsDocument = gql` + query SearchCTFs($search: String!) { + searchCtfs(search: $search) { + edges { + node { + ...CtfFragment + } + } + } +} + ${CtfFragmentDoc}`; + +/** + * __useSearchCtFsQuery__ + * + * To run a query within a Vue component, call `useSearchCtFsQuery` and pass it any options that fit your needs. + * When your component renders, `useSearchCtFsQuery` returns an object from Apollo Client that contains result, loading and error properties + * you can use to render your UI. + * + * @param variables that will be passed into the query + * @param options that will be passed into the query, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/query.html#options; + * + * @example + * const { result, loading, error } = useSearchCtFsQuery({ + * search: // value for 'search' + * }); + */ +export function useSearchCtFsQuery(variables: SearchCtFsQueryVariables | VueCompositionApi.Ref | ReactiveFunction, options: VueApolloComposable.UseQueryOptions | VueCompositionApi.Ref> | ReactiveFunction> = {}) { + return VueApolloComposable.useQuery(SearchCtFsDocument, variables, options); +} +export type SearchCtFsQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn; +export const SearchTasksDocument = gql` + query SearchTasks($search: String!) { + searchTasks(search: $search) { + edges { + node { + ...TaskFragment + } + } + } +} + ${TaskFragmentDoc}`; + +/** + * __useSearchTasksQuery__ + * + * To run a query within a Vue component, call `useSearchTasksQuery` and pass it any options that fit your needs. + * When your component renders, `useSearchTasksQuery` returns an object from Apollo Client that contains result, loading and error properties + * you can use to render your UI. + * + * @param variables that will be passed into the query + * @param options that will be passed into the query, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/query.html#options; + * + * @example + * const { result, loading, error } = useSearchTasksQuery({ + * search: // value for 'search' + * }); + */ +export function useSearchTasksQuery(variables: SearchTasksQueryVariables | VueCompositionApi.Ref | ReactiveFunction, options: VueApolloComposable.UseQueryOptions | VueCompositionApi.Ref> | ReactiveFunction> = {}) { + return VueApolloComposable.useQuery(SearchTasksDocument, variables, options); +} +export type SearchTasksQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn; export const GetCredentialsForCtfIdDocument = gql` query getCredentialsForCtfId($ctfId: Int!) { ctfSecret(id: $ctfId) { @@ -4237,6 +4340,28 @@ export const SubscribeToProfileDeleted = gql` } } ${ProfileFragment}`; +export const SearchCtFs = gql` + query SearchCTFs($search: String!) { + searchCtfs(search: $search) { + edges { + node { + ...CtfFragment + } + } + } +} + ${CtfFragment}`; +export const SearchTasks = gql` + query SearchTasks($search: String!) { + searchTasks(search: $search) { + edges { + node { + ...TaskFragment + } + } + } +} + ${TaskFragment}`; export const GetCredentialsForCtfId = gql` query getCredentialsForCtfId($ctfId: Int!) { ctfSecret(id: $ctfId) { diff --git a/front/src/graphql/Search.graphql b/front/src/graphql/Search.graphql new file mode 100644 index 000000000..3b8895bdf --- /dev/null +++ b/front/src/graphql/Search.graphql @@ -0,0 +1,19 @@ +query SearchCTFs($search: String!) { + searchCtfs(search: $search) { + edges { + node { + ...CtfFragment + } + } + } +} + +query SearchTasks($search: String!) { + searchTasks(search: $search) { + edges { + node { + ...TaskFragment + } + } + } +} From 4919d54a9d55f93ad7e01a31f23dbf0f2cb759b5 Mon Sep 17 00:00:00 2001 From: SakiiR SakiiR Date: Fri, 17 Dec 2021 13:50:07 +0100 Subject: [PATCH 05/16] First version --- front/src/components/Dialogs/SearchDialog.vue | 94 ++++++++++++++++++- front/src/ctfnote/ctfs.ts | 2 +- front/src/ctfnote/models.ts | 1 + front/src/ctfnote/search.ts | 38 ++++++-- front/src/generated/graphql.ts | 14 ++- front/src/graphql/Search.graphql | 3 + 6 files changed, 136 insertions(+), 16 deletions(-) diff --git a/front/src/components/Dialogs/SearchDialog.vue b/front/src/components/Dialogs/SearchDialog.vue index 87f18fcd8..26a2f9733 100644 --- a/front/src/components/Dialogs/SearchDialog.vue +++ b/front/src/components/Dialogs/SearchDialog.vue @@ -9,13 +9,34 @@ filled label="What are you searching for ?" hint="search for title or description" - debounce="500" autofocus :loading="loading" @update:model-value="onSearchChange" @keypress.enter="submit" + @keydown="searchInputKeyDown" /> + + + + + + {{ !!item.ctf ? item.ctf.title + '/' : '' }} + {{ item.title }} + + + + + + + @@ -27,6 +48,8 @@ diff --git a/front/src/components/Menu/MainMenu.vue b/front/src/components/Menu/MainMenu.vue index 4f9957ff7..0a1dff6b4 100644 --- a/front/src/components/Menu/MainMenu.vue +++ b/front/src/components/Menu/MainMenu.vue @@ -3,6 +3,7 @@ :drop-down-label="me.profile.username" drop-down-link="settings" :show-logout="true" + :show-search="true" > From ef5449c470480092f8a05caa655b86baaab56d21 Mon Sep 17 00:00:00 2001 From: SakiiR SakiiR Date: Mon, 20 Dec 2021 09:48:05 +0100 Subject: [PATCH 08/16] Handle CTRL-N & CTRL-P to cycle through search results Better style of search result task item --- front/src/components/Dialogs/SearchDialog.vue | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/front/src/components/Dialogs/SearchDialog.vue b/front/src/components/Dialogs/SearchDialog.vue index e9e5ae6e4..faa552db8 100644 --- a/front/src/components/Dialogs/SearchDialog.vue +++ b/front/src/components/Dialogs/SearchDialog.vue @@ -27,9 +27,11 @@ @click="onItemSelected(item)" > - {{ !!item.ctf ? item.ctf.title + '/' : '' }} - {{ item.title }} + + {{ !!item.ctf ? item.ctf.title + ' / ' : '' }} + {{ item.title }} + + @@ -72,11 +74,11 @@ export default defineComponent({ }, methods: { searchInputKeyDown(e: KeyboardEvent) { - if (e.key === 'ArrowDown') { + if (e.key === 'ArrowDown' || (e.ctrlKey && e.key === 'n')) { this.selectedItemIndex += 1; } - if (e.key === 'ArrowUp') { + if (e.key === 'ArrowUp' || (e.ctrlKey && e.key === 'p')) { this.selectedItemIndex += -1; } From 7151e362c3429d9a1b733d84072d2119de28bef6 Mon Sep 17 00:00:00 2001 From: SakiiR SakiiR Date: Mon, 10 Jan 2022 17:34:35 +0100 Subject: [PATCH 09/16] Now using the "postgraphile-plugin-connection-filter". --- api/migrations/39-search-ctfs.sql | 18 - api/migrations/39-search-tasks-n-ctfs.sql | 2 + api/migrations/40-search-tasks.sql | 16 - api/package.json | 4 +- api/src/index.ts | 2 + api/yarn.lock | 69 +- front/graphql.schema.json | 2741 +++++++++++++++++---- front/src/ctfnote/search.ts | 8 +- front/src/generated/graphql.ts | 377 ++- front/src/graphql/Search.graphql | 20 +- 10 files changed, 2637 insertions(+), 620 deletions(-) delete mode 100644 api/migrations/39-search-ctfs.sql create mode 100644 api/migrations/39-search-tasks-n-ctfs.sql delete mode 100644 api/migrations/40-search-tasks.sql diff --git a/api/migrations/39-search-ctfs.sql b/api/migrations/39-search-ctfs.sql deleted file mode 100644 index c094c3a52..000000000 --- a/api/migrations/39-search-ctfs.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE OR REPLACE FUNCTION ctfnote.search_ctfs (search text) - RETURNS SETOF ctfnote.ctf - AS $$ - SELECT - * - FROM - ctfnote.ctf - AS - ctf - WHERE - ctf.title ilike ('%' || search || '%') - OR - ctf.description ilike ('%' || search || '%') ; -$$ -LANGUAGE SQL -STABLE; - -GRANT EXECUTE ON FUNCTION ctfnote.search_ctfs TO user_guest; diff --git a/api/migrations/39-search-tasks-n-ctfs.sql b/api/migrations/39-search-tasks-n-ctfs.sql new file mode 100644 index 000000000..c8e739eac --- /dev/null +++ b/api/migrations/39-search-tasks-n-ctfs.sql @@ -0,0 +1,2 @@ +CREATE INDEX ON ctfnote.ctf (title); +CREATE INDEX ON ctfnote.task (title); diff --git a/api/migrations/40-search-tasks.sql b/api/migrations/40-search-tasks.sql deleted file mode 100644 index 94e91f679..000000000 --- a/api/migrations/40-search-tasks.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE OR REPLACE FUNCTION ctfnote.search_tasks (search text) - RETURNS SETOF ctfnote.task - AS $$ - SELECT - * - FROM - ctfnote.task - AS - task - WHERE - task.title ilike ('%' || search || '%'); -$$ -LANGUAGE SQL -STABLE; - -GRANT EXECUTE ON FUNCTION ctfnote.search_tasks TO user_guest; diff --git a/api/package.json b/api/package.json index e1084eb97..e3d28227d 100644 --- a/api/package.json +++ b/api/package.json @@ -27,8 +27,8 @@ "graphile-utils": "^4.11.2", "graphql": "^15.6.1", "graphql-upload": "^12.0.0", - "postgraphile": "^4.11.0", - "postgraphile-plugin-connection-filter": "^2.1.1", + "postgraphile": "^4.12.8", + "postgraphile-plugin-connection-filter": "^2.2.2", "postgres-migrations": "^5.3.0" }, "devDependencies": { diff --git a/api/src/index.ts b/api/src/index.ts index d7ab7f825..fe9e151a0 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -14,6 +14,7 @@ import createTasKPlugin from "./plugins/createTask"; import importCtfPlugin from "./plugins/importCtf"; import uploadLogoPlugin from "./plugins/uploadLogo"; import uploadScalar from "./plugins/uploadScalar"; +import ConnectionFilterPlugin from "postgraphile-plugin-connection-filter"; function getDbUrl(role: "user" | "admin") { const login = config.db[role].login; @@ -43,6 +44,7 @@ function createOptions() { importCtfPlugin, uploadLogoPlugin, createTasKPlugin, + ConnectionFilterPlugin, ], ownerConnectionString: getDbUrl("admin"), enableQueryBatching: true, diff --git a/api/yarn.lock b/api/yarn.lock index f32f6f155..d257c8acf 100644 --- a/api/yarn.lock +++ b/api/yarn.lock @@ -1345,24 +1345,24 @@ graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -graphile-build-pg@4.12.1: - version "4.12.1" - resolved "https://registry.yarnpkg.com/graphile-build-pg/-/graphile-build-pg-4.12.1.tgz#f6102a60968076beedfefeb102e8558255e65921" - integrity sha512-Rd9QBtbyLJ425VUeHggFCvh3s3oKR58mUU6JYK0sQTRjYbxrE/eWDNAQZQLuWeemfSHvgS5W0EzppkHjkoiWiQ== +graphile-build-pg@4.12.2: + version "4.12.2" + resolved "https://registry.yarnpkg.com/graphile-build-pg/-/graphile-build-pg-4.12.2.tgz#b816824488ba97f797f61c7d129e10e21fe64638" + integrity sha512-4zWS7yb2L3afNpzADX9iBc2do4UOd3abiHd/WG0ao8lharU4YxEDS5qKlE2/2s+gSNqW2okKXEuI1/ci9DXVbw== dependencies: "@graphile/lru" "4.11.0" chalk "^2.4.2" debug "^4.1.1" - graphile-build "4.12.0" + graphile-build "4.12.2" jsonwebtoken "^8.5.1" lodash ">=4 <5" lru-cache ">=4 <5" pg-sql2 "4.12.1" -graphile-build@4.12.0: - version "4.12.0" - resolved "https://registry.yarnpkg.com/graphile-build/-/graphile-build-4.12.0.tgz#726bdb1338f13b30cdec35ee3b0c9af8aa7f7dab" - integrity sha512-P4urOvOf4C8uzuuCq8BjFb+qffQvWUnZamrEyRC/0BfKKPkZhQ/HYqe9M7JkwiH8uFekHaTXDBrdR+OPoZEdhw== +graphile-build@4.12.2: + version "4.12.2" + resolved "https://registry.yarnpkg.com/graphile-build/-/graphile-build-4.12.2.tgz#156b0af43ebd2f60622bda573f0aa34b01735e2a" + integrity sha512-UqomiSnWPj4pjO6Q6PzT1YeH96k7e0JzCBI3X8kkELG+PP2BOQCNE5e+xLJvohJmUr0YBTgflPQo7P1ZESPwww== dependencies: "@graphile/lru" "4.11.0" chalk "^2.4.2" @@ -1374,7 +1374,7 @@ graphile-build@4.12.0: pluralize "^7.0.0" semver "^6.0.0" -graphile-utils@^4.11.2, graphile-utils@^4.12.1: +graphile-utils@^4.11.2: version "4.12.1" resolved "https://registry.yarnpkg.com/graphile-utils/-/graphile-utils-4.12.1.tgz#52039718d1f8a30bf73c60a6d14c619c58006b91" integrity sha512-+yfKs2W59lVgl/KcZrcGIZ3CQ/eyitZ+HHkbgAVRonA4PaWTSvaqLH4xNvvJu4X7sIGFxb4GWzCxTLnyjHRrmg== @@ -1383,6 +1383,15 @@ graphile-utils@^4.11.2, graphile-utils@^4.12.1: graphql ">=0.9 <0.14 || ^14.0.2 || ^15.4.0" tslib "^2.0.1" +graphile-utils@^4.12.2: + version "4.12.2" + resolved "https://registry.yarnpkg.com/graphile-utils/-/graphile-utils-4.12.2.tgz#2858462672eecdb53c5327ffc22abb61f4e30e06" + integrity sha512-2UcTWWMFLFkKwbDLqlN0mF5sxLqz9y0p7I3zNOJpXtHVjrHyp7oQZsWComPsit/PWIrIgtDUagP+HPkypBRrqA== + dependencies: + debug "^4.1.1" + graphql ">=0.9 <0.14 || ^14.0.2 || ^15.4.0" + tslib "^2.0.1" + graphql-parse-resolve-info@4.12.0: version "4.12.0" resolved "https://registry.yarnpkg.com/graphql-parse-resolve-info/-/graphql-parse-resolve-info-4.12.0.tgz#b5e83c1f56236660dee2cee9541ba70463e859a9" @@ -1409,10 +1418,10 @@ graphql-upload@^12.0.0: isobject "^4.0.0" object-path "^0.11.5" -graphql-ws@^5.1.2: - version "5.5.0" - resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.5.0.tgz#79f10248d23d104369eaef93acb9f887276a2c42" - integrity sha512-WQepPMGQQoqS2VsrI2I3RMLCVz3CW4/6ZqGV6ABDOwH4R62DzjxwMlwZbj6vhSI/7IM3/C911yITwgs77iO/hw== +graphql-ws@^5.5.5: + version "5.5.5" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.5.5.tgz#f375486d3f196e2a2527b503644693ae3a8670a9" + integrity sha512-hvyIS71vs4Tu/yUYHPvGXsTgo0t3arU820+lT5VjZS2go0ewp2LqyCgxEN56CzOG7Iys52eRhHBiD1gGRdiQtw== "graphql@>=0.9 <0.14 || ^14.0.2 || ^15.4.0", "graphql@^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.2 || ^15.0.0", graphql@^15.3.0, graphql@^15.6.1: version "15.6.1" @@ -2259,26 +2268,26 @@ pluralize@^7.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== -postgraphile-core@4.12.1: - version "4.12.1" - resolved "https://registry.yarnpkg.com/postgraphile-core/-/postgraphile-core-4.12.1.tgz#fcee9d54b02a56666a8026df56e0b0540e712cf4" - integrity sha512-BukrJ3j+H4dtEaCCZOPjLZ6+DJnAYHPOvFpDC85w9T4xlpLFCx7/E8ZlZFm7z/P6f/s8SS8EpL7lazms6uB8FQ== +postgraphile-core@4.12.2: + version "4.12.2" + resolved "https://registry.yarnpkg.com/postgraphile-core/-/postgraphile-core-4.12.2.tgz#a15107cf297ed8091004621e73ba4a53d31e1d2a" + integrity sha512-+2OWlPVsMAVjYRMBSI/CT4GUB0mkSmPKGopKapfvhW40SCUBiPB/kqTylX2viRRnN8FuZtS3cRaTPiWr1K+DIg== dependencies: - graphile-build "4.12.0" - graphile-build-pg "4.12.1" + graphile-build "4.12.2" + graphile-build-pg "4.12.2" tslib "^2.0.1" -postgraphile-plugin-connection-filter@^2.1.1: +postgraphile-plugin-connection-filter@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/postgraphile-plugin-connection-filter/-/postgraphile-plugin-connection-filter-2.2.2.tgz#c2444a01a4a6506f9e8a485f18b6cf5bcd17e43b" integrity sha512-/PkdMwaIfGM++C8G5QUAF1iosAVEyIbPaaYteCMgfNWjW215SP9+8L+ewfi6Dm9Weaf+qKnNERWx7xlY8kuWOw== dependencies: tslib "^2.3.0" -postgraphile@^4.11.0: - version "4.12.4" - resolved "https://registry.yarnpkg.com/postgraphile/-/postgraphile-4.12.4.tgz#c07395618e12f3e35f401ec7c75d7e34e48de69b" - integrity sha512-ylx3w9MQ9tSOXCIPIzqseyTX57R6PJOQrQYdNn3SMrj6Glrt7mpzNNLW5BDwQvuViLnIIOaUEkDdHG1IaHHMmA== +postgraphile@^4.12.8: + version "4.12.8" + resolved "https://registry.yarnpkg.com/postgraphile/-/postgraphile-4.12.8.tgz#f42f2114e69e074c3ab11bad4431f8f893edd403" + integrity sha512-n8QqLkTtLmVItXeXAdEby4Qv8d6l7/AcDDqHy0BsMojVZgpwfmAIlF8lMOF4xOqqeUydnO0HCiVZjqaBhxjVJw== dependencies: "@graphile/lru" "4.11.0" "@types/json5" "^0.0.30" @@ -2290,11 +2299,11 @@ postgraphile@^4.11.0: commander "^2.19.0" debug "^4.1.1" finalhandler "^1.0.6" - graphile-build "4.12.0" - graphile-build-pg "4.12.1" - graphile-utils "^4.12.1" + graphile-build "4.12.2" + graphile-build-pg "4.12.2" + graphile-utils "^4.12.2" graphql "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.2 || ^15.0.0" - graphql-ws "^5.1.2" + graphql-ws "^5.5.5" http-errors "^1.5.1" iterall "^1.0.2" json5 "^2.1.1" @@ -2303,7 +2312,7 @@ postgraphile@^4.11.0: pg ">=6.1.0 <9" pg-connection-string "^2.0.0" pg-sql2 "4.12.1" - postgraphile-core "4.12.1" + postgraphile-core "4.12.2" subscriptions-transport-ws "^0.9.18" tslib "^2.1.0" ws "^7.4.2" diff --git a/front/graphql.schema.json b/front/graphql.schema.json index d2e7456c8..b8c1bd557 100644 --- a/front/graphql.schema.json +++ b/front/graphql.schema.json @@ -20,6 +20,165 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "BooleanFilter", + "description": "A filter to be used against Boolean fields. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "distinctFrom", + "description": "Not equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "equalTo", + "description": "Equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThan", + "description": "Greater than the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThanOrEqualTo", + "description": "Greater than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "in", + "description": "Included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isNull", + "description": "Is null (if `true` is specified) or is not null (if `false` is specified).", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThan", + "description": "Less than the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualTo", + "description": "Less than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFrom", + "description": "Equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualTo", + "description": "Not equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIn", + "description": "Not included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "ChangePasswordInput", @@ -826,6 +985,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -1007,6 +1178,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "TaskFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -1173,6 +1356,18 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "title", + "description": "Checks for equality with the object’s `title` field.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -1181,28 +1376,36 @@ }, { "kind": "INPUT_OBJECT", - "name": "CtfInput", - "description": "An input for mutations affecting `Ctf`", + "name": "CtfFilter", + "description": "A filter to be used against `Ctf` object types. All fields are combined with a logical ‘and.’", "fields": null, "inputFields": [ { - "name": "ctfUrl", - "description": null, + "name": "and", + "description": "Checks for all expressions in this list.", "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + } + } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "ctftimeUrl", - "description": null, + "name": "endTime", + "description": "Filter by the object’s `endTime` field.", "type": { - "kind": "SCALAR", - "name": "String", + "kind": "INPUT_OBJECT", + "name": "DatetimeFilter", "ofType": null }, "defaultValue": null, @@ -1210,11 +1413,11 @@ "deprecationReason": null }, { - "name": "description", - "description": null, + "name": "granted", + "description": "Filter by the object’s `granted` field.", "type": { - "kind": "SCALAR", - "name": "String", + "kind": "INPUT_OBJECT", + "name": "BooleanFilter", "ofType": null }, "defaultValue": null, @@ -1222,27 +1425,23 @@ "deprecationReason": null }, { - "name": "endTime", - "description": null, + "name": "id", + "description": "Filter by the object’s `id` field.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Datetime", - "ofType": null - } + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "logoUrl", - "description": null, + "name": "not", + "description": "Negates the expression.", "type": { - "kind": "SCALAR", - "name": "String", + "kind": "INPUT_OBJECT", + "name": "CtfFilter", "ofType": null }, "defaultValue": null, @@ -1250,15 +1449,19 @@ "deprecationReason": null }, { - "name": "startTime", - "description": null, + "name": "or", + "description": "Checks for any expressions in this list.", "type": { - "kind": "NON_NULL", + "kind": "LIST", "name": null, "ofType": { - "kind": "SCALAR", - "name": "Datetime", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + } } }, "defaultValue": null, @@ -1266,27 +1469,35 @@ "deprecationReason": null }, { - "name": "title", - "description": null, + "name": "secretsId", + "description": "Filter by the object’s `secretsId` field.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "weight", - "description": null, + "name": "startTime", + "description": "Filter by the object’s `startTime` field.", "type": { - "kind": "SCALAR", - "name": "Float", + "kind": "INPUT_OBJECT", + "name": "DatetimeFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "Filter by the object’s `title` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "StringFilter", "ofType": null }, "defaultValue": null, @@ -1300,8 +1511,8 @@ }, { "kind": "INPUT_OBJECT", - "name": "CtfPatch", - "description": "Represents an update to a `Ctf`. Fields that are set will be updated.", + "name": "CtfInput", + "description": "An input for mutations affecting `Ctf`", "fields": null, "inputFields": [ { @@ -1344,14 +1555,133 @@ "name": "endTime", "description": null, "type": { - "kind": "SCALAR", - "name": "Datetime", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logoUrl", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startTime", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "weight", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CtfPatch", + "description": "Represents an update to a `Ctf`. Fields that are set will be updated.", + "fields": null, + "inputFields": [ + { + "name": "ctfUrl", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ctftimeUrl", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endTime", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "logoUrl", "description": null, @@ -1462,6 +1792,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -1598,6 +1940,81 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "CtfSecretFilter", + "description": "A filter to be used against `CtfSecret` object types. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "and", + "description": "Checks for all expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CtfSecretFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "Filter by the object’s `id` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "not", + "description": "Negates the expression.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfSecretFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "or", + "description": "Checks for any expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CtfSecretFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "CtfSecretPatch", @@ -1995,6 +2412,18 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "TITLE_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TITLE_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -2021,16 +2450,16 @@ }, { "kind": "INPUT_OBJECT", - "name": "DeleteCtfByNodeIdInput", - "description": "All input for the `deleteCtfByNodeId` mutation.", + "name": "DatetimeFilter", + "description": "A filter to be used against Datetime fields. All fields are combined with a logical ‘and.’", "fields": null, "inputFields": [ { - "name": "clientMutationId", - "description": "An arbitrary string value with no semantic meaning. Will be included in the\npayload verbatim. May be used to track mutations by the client.", + "name": "distinctFrom", + "description": "Not equal to the specified value, treating null like an ordinary value.", "type": { "kind": "SCALAR", - "name": "String", + "name": "Datetime", "ofType": null }, "defaultValue": null, @@ -2038,38 +2467,23 @@ "deprecationReason": null }, { - "name": "nodeId", - "description": "The globally unique `ID` which will identify a single `Ctf` to be deleted.", + "name": "equalTo", + "description": "Equal to the specified value.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } + "kind": "SCALAR", + "name": "Datetime", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - } - ], - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INPUT_OBJECT", - "name": "DeleteCtfInput", - "description": "All input for the `deleteCtf` mutation.", - "fields": null, - "inputFields": [ + }, { - "name": "clientMutationId", - "description": "An arbitrary string value with no semantic meaning. Will be included in the\npayload verbatim. May be used to track mutations by the client.", + "name": "greaterThan", + "description": "Greater than the specified value.", "type": { "kind": "SCALAR", - "name": "String", + "name": "Datetime", "ofType": null }, "defaultValue": null, @@ -2077,23 +2491,197 @@ "deprecationReason": null }, { - "name": "id", - "description": null, + "name": "greaterThanOrEqualTo", + "description": "Greater than or equal to the specified value.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - } + "kind": "SCALAR", + "name": "Datetime", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - } - ], - "interfaces": null, + }, + { + "name": "in", + "description": "Included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isNull", + "description": "Is null (if `true` is specified) or is not null (if `false` is specified).", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThan", + "description": "Less than the specified value.", + "type": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualTo", + "description": "Less than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFrom", + "description": "Equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualTo", + "description": "Not equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIn", + "description": "Not included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Datetime", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteCtfByNodeIdInput", + "description": "All input for the `deleteCtfByNodeId` mutation.", + "fields": null, + "inputFields": [ + { + "name": "clientMutationId", + "description": "An arbitrary string value with no semantic meaning. Will be included in the\npayload verbatim. May be used to track mutations by the client.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodeId", + "description": "The globally unique `ID` which will identify a single `Ctf` to be deleted.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteCtfInput", + "description": "All input for the `deleteCtf` mutation.", + "fields": null, + "inputFields": [ + { + "name": "clientMutationId", + "description": "An arbitrary string value with no semantic meaning. Will be included in the\npayload verbatim. May be used to track mutations by the client.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, "enumValues": null, "possibleTypes": null }, @@ -2768,106 +3356,265 @@ "possibleTypes": null }, { - "kind": "OBJECT", - "name": "Invitation", - "description": null, - "fields": [ + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "description": "A filter to be used against Int fields. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ { - "name": "ctf", - "description": "Reads a single `Ctf` that is related to this `Invitation`.", - "args": [], + "name": "distinctFrom", + "description": "Not equal to the specified value, treating null like an ordinary value.", "type": { - "kind": "OBJECT", - "name": "Ctf", + "kind": "SCALAR", + "name": "Int", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "ctfId", - "description": null, - "args": [], + "name": "equalTo", + "description": "Equal to the specified value.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - } + "kind": "SCALAR", + "name": "Int", + "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "nodeId", - "description": "A globally unique identifier. Can be used in various places throughout the system to identify this single value.", - "args": [], + "name": "greaterThan", + "description": "Greater than the specified value.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } + "kind": "SCALAR", + "name": "Int", + "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "profile", - "description": "Reads a single `Profile` that is related to this `Invitation`.", - "args": [], + "name": "greaterThanOrEqualTo", + "description": "Greater than or equal to the specified value.", "type": { - "kind": "OBJECT", - "name": "Profile", + "kind": "SCALAR", + "name": "Int", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "profileId", - "description": null, - "args": [], + "name": "in", + "description": "Included in the specified list.", "type": { - "kind": "NON_NULL", + "kind": "LIST", "name": null, "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } } }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Node", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INPUT_OBJECT", - "name": "InvitationCondition", - "description": "A condition to be used against `Invitation` object types. All fields are tested\nfor equality and combined with a logical ‘and.’", - "fields": null, - "inputFields": [ + }, { - "name": "ctfId", - "description": "Checks for equality with the object’s `ctfId` field.", + "name": "isNull", + "description": "Is null (if `true` is specified) or is not null (if `false` is specified).", "type": { "kind": "SCALAR", - "name": "Int", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThan", + "description": "Less than the specified value.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualTo", + "description": "Less than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFrom", + "description": "Equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualTo", + "description": "Not equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIn", + "description": "Not included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Invitation", + "description": null, + "fields": [ + { + "name": "ctf", + "description": "Reads a single `Ctf` that is related to this `Invitation`.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ctf", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ctfId", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodeId", + "description": "A globally unique identifier. Can be used in various places throughout the system to identify this single value.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "profile", + "description": "Reads a single `Profile` that is related to this `Invitation`.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Profile", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "profileId", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "InvitationCondition", + "description": "A condition to be used against `Invitation` object types. All fields are tested\nfor equality and combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "ctfId", + "description": "Checks for equality with the object’s `ctfId` field.", + "type": { + "kind": "SCALAR", + "name": "Int", "ofType": null }, "defaultValue": null, @@ -2891,6 +3638,93 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "description": "A filter to be used against `Invitation` object types. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "and", + "description": "Checks for all expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ctfId", + "description": "Filter by the object’s `ctfId` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "not", + "description": "Negates the expression.", + "type": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "or", + "description": "Checks for any expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "profileId", + "description": "Filter by the object’s `profileId` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "InvitationInput", @@ -4497,6 +5331,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -4651,11 +5497,11 @@ "deprecationReason": null }, { - "name": "first", - "description": "Only read the first `n` values of the set.", + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", "type": { - "kind": "SCALAR", - "name": "Int", + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", "ofType": null }, "defaultValue": null, @@ -4663,9 +5509,21 @@ "deprecationReason": null }, { - "name": "last", - "description": "Only read the last `n` values of the set.", - "type": { + "name": "first", + "description": "Only read the first `n` values of the set.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "last", + "description": "Only read the last `n` values of the set.", + "type": { "kind": "SCALAR", "name": "Int", "ofType": null @@ -4766,6 +5624,105 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "description": "A filter to be used against `Profile` object types. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "and", + "description": "Checks for all expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "Filter by the object’s `id` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "not", + "description": "Negates the expression.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "or", + "description": "Checks for any expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "role", + "description": "Filter by the object’s `role` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "RoleFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "username", + "description": "Filter by the object’s `username` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "StringFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "ProfilePatch", @@ -5157,6 +6114,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfSecretFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5262,6 +6231,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5355,6 +6336,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5428,6 +6421,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5587,6 +6592,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "InvitationFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5749,6 +6766,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CtfFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -5921,6 +6950,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProfileFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -6003,8 +7044,37 @@ "deprecationReason": null }, { - "name": "searchCtfs", - "description": "Reads and enables pagination through a set of `Ctf`.", + "name": "settingByNodeId", + "description": "Reads a single `Setting` using its globally unique `ID`.", + "args": [ + { + "name": "nodeId", + "description": "The globally unique `ID` to be used in selecting a single `Setting`.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Setting", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "settings", + "description": "Reads and enables pagination through a set of `Setting`.", "args": [ { "name": "after", @@ -6067,126 +7137,78 @@ "deprecationReason": null }, { - "name": "search", - "description": null, + "name": "orderBy", + "description": "The method to use when ordering `Setting`.", "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SettingsOrderBy", + "ofType": null + } + } }, - "defaultValue": null, + "defaultValue": "[PRIMARY_KEY_ASC]", "isDeprecated": false, "deprecationReason": null } ], "type": { "kind": "OBJECT", - "name": "CtfsConnection", + "name": "SettingsConnection", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "searchTasks", - "description": "Reads and enables pagination through a set of `Task`.", + "name": "task", + "description": null, "args": [ { - "name": "after", - "description": "Read all values in the set after (below) this cursor.", + "name": "id", + "description": null, "type": { - "kind": "SCALAR", - "name": "Cursor", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "type": { + "kind": "OBJECT", + "name": "Task", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "taskByNodeId", + "description": "Reads a single `Task` using its globally unique `ID`.", + "args": [ { - "name": "before", - "description": "Read all values in the set before (above) this cursor.", + "name": "nodeId", + "description": "The globally unique `ID` to be used in selecting a single `Task`.", "type": { - "kind": "SCALAR", - "name": "Cursor", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "first", - "description": "Only read the first `n` values of the set.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "last", - "description": "Only read the last `n` values of the set.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "offset", - "description": "Skip the first `n` values from our `after` cursor, an alternative to cursor\nbased pagination. May not be used with `last`.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "search", - "description": null, - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "TasksConnection", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "settingByNodeId", - "description": "Reads a single `Setting` using its globally unique `ID`.", - "args": [ - { - "name": "nodeId", - "description": "The globally unique `ID` to be used in selecting a single `Setting`.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } }, "defaultValue": null, "isDeprecated": false, @@ -6195,15 +7217,15 @@ ], "type": { "kind": "OBJECT", - "name": "Setting", + "name": "Task", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "settings", - "description": "Reads and enables pagination through a set of `Setting`.", + "name": "tasks", + "description": "Reads and enables pagination through a set of `Task`.", "args": [ { "name": "after", @@ -6230,150 +7252,11 @@ "deprecationReason": null }, { - "name": "first", - "description": "Only read the first `n` values of the set.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "last", - "description": "Only read the last `n` values of the set.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "offset", - "description": "Skip the first `n` values from our `after` cursor, an alternative to cursor\nbased pagination. May not be used with `last`.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orderBy", - "description": "The method to use when ordering `Setting`.", - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "SettingsOrderBy", - "ofType": null - } - } - }, - "defaultValue": "[PRIMARY_KEY_ASC]", - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "SettingsConnection", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "task", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Task", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "taskByNodeId", - "description": "Reads a single `Task` using its globally unique `ID`.", - "args": [ - { - "name": "nodeId", - "description": "The globally unique `ID` to be used in selecting a single `Task`.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Task", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "tasks", - "description": "Reads and enables pagination through a set of `Task`.", - "args": [ - { - "name": "after", - "description": "Read all values in the set after (below) this cursor.", - "type": { - "kind": "SCALAR", - "name": "Cursor", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "before", - "description": "Read all values in the set before (above) this cursor.", + "name": "condition", + "description": "A condition to be used in determining which values should be returned by the collection.", "type": { - "kind": "SCALAR", - "name": "Cursor", + "kind": "INPUT_OBJECT", + "name": "TaskCondition", "ofType": null }, "defaultValue": null, @@ -6381,11 +7264,11 @@ "deprecationReason": null }, { - "name": "condition", - "description": "A condition to be used in determining which values should be returned by the collection.", + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", "type": { "kind": "INPUT_OBJECT", - "name": "TaskCondition", + "name": "TaskFilter", "ofType": null }, "defaultValue": null, @@ -6664,6 +7547,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -7226,21 +8121,180 @@ "possibleTypes": null }, { - "kind": "OBJECT", - "name": "Setting", - "description": null, - "fields": [ + "kind": "INPUT_OBJECT", + "name": "RoleFilter", + "description": "A filter to be used against Role fields. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ { - "name": "nodeId", - "description": "A globally unique identifier. Can be used in various places throughout the system to identify this single value.", - "args": [], + "name": "distinctFrom", + "description": "Not equal to the specified value, treating null like an ordinary value.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "equalTo", + "description": "Equal to the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThan", + "description": "Greater than the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThanOrEqualTo", + "description": "Greater than or equal to the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "in", + "description": "Included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "Role", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isNull", + "description": "Is null (if `true` is specified) or is not null (if `false` is specified).", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThan", + "description": "Less than the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualTo", + "description": "Less than or equal to the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFrom", + "description": "Equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualTo", + "description": "Not equal to the specified value.", + "type": { + "kind": "ENUM", + "name": "Role", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIn", + "description": "Not included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "Role", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Setting", + "description": null, + "fields": [ + { + "name": "nodeId", + "description": "A globally unique identifier. Can be used in various places throughout the system to identify this single value.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null } }, "isDeprecated": false, @@ -7764,94 +8818,581 @@ "description": "Reads a single `Profile` that is related to this `WorkOnTask`.", "args": [], "type": { - "kind": "OBJECT", - "name": "Profile", + "kind": "OBJECT", + "name": "Profile", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "query", + "description": "Our root query field type. Allows us to run any query from our mutation payload.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Query", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "task", + "description": "Reads a single `Task` that is related to this `WorkOnTask`.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Task", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "workOnTask", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "WorkOnTask", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "workOnTaskEdge", + "description": "An edge for our `WorkOnTask`. May be used by Relay 1.", + "args": [ + { + "name": "orderBy", + "description": "The method to use when ordering `WorkOnTask`.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "WorkOnTasksOrderBy", + "ofType": null + } + } + }, + "defaultValue": "[PRIMARY_KEY_ASC]", + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "WorkOnTasksEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "StringFilter", + "description": "A filter to be used against String fields. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "distinctFrom", + "description": "Not equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "distinctFromInsensitive", + "description": "Not equal to the specified value, treating null like an ordinary value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endsWith", + "description": "Ends with the specified string (case-sensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endsWithInsensitive", + "description": "Ends with the specified string (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "equalTo", + "description": "Equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "equalToInsensitive", + "description": "Equal to the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThan", + "description": "Greater than the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThanInsensitive", + "description": "Greater than the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThanOrEqualTo", + "description": "Greater than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "greaterThanOrEqualToInsensitive", + "description": "Greater than or equal to the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "in", + "description": "Included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inInsensitive", + "description": "Included in the specified list (case-insensitive).", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includes", + "description": "Contains the specified string (case-sensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesInsensitive", + "description": "Contains the specified string (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isNull", + "description": "Is null (if `true` is specified) or is not null (if `false` is specified).", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThan", + "description": "Less than the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanInsensitive", + "description": "Less than the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualTo", + "description": "Less than or equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lessThanOrEqualToInsensitive", + "description": "Less than or equal to the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "like", + "description": "Matches the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "likeInsensitive", + "description": "Matches the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFrom", + "description": "Equal to the specified value, treating null like an ordinary value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notDistinctFromInsensitive", + "description": "Equal to the specified value, treating null like an ordinary value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEndsWith", + "description": "Does not end with the specified string (case-sensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEndsWithInsensitive", + "description": "Does not end with the specified string (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualTo", + "description": "Not equal to the specified value.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notEqualToInsensitive", + "description": "Not equal to the specified value (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIn", + "description": "Not included in the specified list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notInInsensitive", + "description": "Not included in the specified list (case-insensitive).", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIncludes", + "description": "Does not contain the specified string (case-sensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notIncludesInsensitive", + "description": "Does not contain the specified string (case-insensitive).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notLike", + "description": "Does not match the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notLikeInsensitive", + "description": "Does not match the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.", + "type": { + "kind": "SCALAR", + "name": "String", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "query", - "description": "Our root query field type. Allows us to run any query from our mutation payload.", - "args": [], + "name": "notStartsWith", + "description": "Does not start with the specified string (case-sensitive).", "type": { - "kind": "OBJECT", - "name": "Query", + "kind": "SCALAR", + "name": "String", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "task", - "description": "Reads a single `Task` that is related to this `WorkOnTask`.", - "args": [], + "name": "notStartsWithInsensitive", + "description": "Does not start with the specified string (case-insensitive).", "type": { - "kind": "OBJECT", - "name": "Task", + "kind": "SCALAR", + "name": "String", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "workOnTask", - "description": null, - "args": [], + "name": "startsWith", + "description": "Starts with the specified string (case-sensitive).", "type": { - "kind": "OBJECT", - "name": "WorkOnTask", + "kind": "SCALAR", + "name": "String", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "workOnTaskEdge", - "description": "An edge for our `WorkOnTask`. May be used by Relay 1.", - "args": [ - { - "name": "orderBy", - "description": "The method to use when ordering `WorkOnTask`.", - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "WorkOnTasksOrderBy", - "ofType": null - } - } - }, - "defaultValue": "[PRIMARY_KEY_ASC]", - "isDeprecated": false, - "deprecationReason": null - } - ], + "name": "startsWithInsensitive", + "description": "Starts with the specified string (case-insensitive).", "type": { - "kind": "OBJECT", - "name": "WorkOnTasksEdge", + "kind": "SCALAR", + "name": "String", "ofType": null }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null } ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "String", - "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", - "fields": null, - "inputFields": null, "interfaces": null, "enumValues": null, "possibleTypes": null @@ -8097,6 +9638,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filter", + "description": "A filter to be used in determining which values should be returned by the collection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "first", "description": "Only read the first `n` values of the set.", @@ -8207,6 +9760,129 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "title", + "description": "Checks for equality with the object’s `title` field.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "TaskFilter", + "description": "A filter to be used against `Task` object types. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "and", + "description": "Checks for all expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "TaskFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ctfId", + "description": "Filter by the object’s `ctfId` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "Filter by the object’s `id` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "not", + "description": "Negates the expression.", + "type": { + "kind": "INPUT_OBJECT", + "name": "TaskFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "or", + "description": "Checks for any expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "TaskFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "solved", + "description": "Filter by the object’s `solved` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "BooleanFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "Filter by the object’s `title` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "StringFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -8451,6 +10127,18 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "TITLE_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TITLE_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -9922,6 +11610,93 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "description": "A filter to be used against `WorkOnTask` object types. All fields are combined with a logical ‘and.’", + "fields": null, + "inputFields": [ + { + "name": "and", + "description": "Checks for all expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "not", + "description": "Negates the expression.", + "type": { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "or", + "description": "Checks for any expressions in this list.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "WorkOnTaskFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "profileId", + "description": "Filter by the object’s `profileId` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "taskId", + "description": "Filter by the object’s `taskId` field.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IntFilter", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "WorkOnTasksConnection", diff --git a/front/src/ctfnote/search.ts b/front/src/ctfnote/search.ts index 191d592d0..80ec5d1d9 100644 --- a/front/src/ctfnote/search.ts +++ b/front/src/ctfnote/search.ts @@ -13,9 +13,9 @@ export async function searchCtfs(search: string): Promise { } }); - if (!result.data.searchCtfs) return []; + if (!result.data.ctfs) return []; - return result.data.searchCtfs?.edges.map(c => buildCtf(c.node)); + return result.data.ctfs?.nodes.map(c => buildCtf(c)); } export async function searchTasks(search: string): Promise { @@ -28,7 +28,7 @@ export async function searchTasks(search: string): Promise { } }); - if (!result.data.searchTasks) return []; + if (!result.data.tasks) return []; - return result.data.searchTasks?.edges.map(c => buildTask(c.node)); + return result.data.tasks?.nodes.map(t => buildTask(t)); } \ No newline at end of file diff --git a/front/src/generated/graphql.ts b/front/src/generated/graphql.ts index 0856a2160..55d8bb396 100644 --- a/front/src/generated/graphql.ts +++ b/front/src/generated/graphql.ts @@ -32,6 +32,32 @@ export type Scalars = { Upload: File; }; +/** A filter to be used against Boolean fields. All fields are combined with a logical ‘and.’ */ +export type BooleanFilter = { + /** Not equal to the specified value, treating null like an ordinary value. */ + distinctFrom?: InputMaybe; + /** Equal to the specified value. */ + equalTo?: InputMaybe; + /** Greater than the specified value. */ + greaterThan?: InputMaybe; + /** Greater than or equal to the specified value. */ + greaterThanOrEqualTo?: InputMaybe; + /** Included in the specified list. */ + in?: InputMaybe>; + /** Is null (if `true` is specified) or is not null (if `false` is specified). */ + isNull?: InputMaybe; + /** Less than the specified value. */ + lessThan?: InputMaybe; + /** Less than or equal to the specified value. */ + lessThanOrEqualTo?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value. */ + notDistinctFrom?: InputMaybe; + /** Not equal to the specified value. */ + notEqualTo?: InputMaybe; + /** Not included in the specified list. */ + notIn?: InputMaybe>; +}; + /** All input for the `changePassword` mutation. */ export type ChangePasswordInput = { /** @@ -221,6 +247,7 @@ export type CtfInvitationsArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -232,6 +259,7 @@ export type CtfTasksArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -248,6 +276,30 @@ export type CtfCondition = { secretsId?: InputMaybe; /** Checks for equality with the object’s `startTime` field. */ startTime?: InputMaybe; + /** Checks for equality with the object’s `title` field. */ + title?: InputMaybe; +}; + +/** A filter to be used against `Ctf` object types. All fields are combined with a logical ‘and.’ */ +export type CtfFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Filter by the object’s `endTime` field. */ + endTime?: InputMaybe; + /** Filter by the object’s `granted` field. */ + granted?: InputMaybe; + /** Filter by the object’s `id` field. */ + id?: InputMaybe; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; + /** Filter by the object’s `secretsId` field. */ + secretsId?: InputMaybe; + /** Filter by the object’s `startTime` field. */ + startTime?: InputMaybe; + /** Filter by the object’s `title` field. */ + title?: InputMaybe; }; /** An input for mutations affecting `Ctf` */ @@ -289,6 +341,7 @@ export type CtfSecretCtfsBySecretsIdArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -304,6 +357,18 @@ export type CtfSecretCondition = { id?: InputMaybe; }; +/** A filter to be used against `CtfSecret` object types. All fields are combined with a logical ‘and.’ */ +export type CtfSecretFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Filter by the object’s `id` field. */ + id?: InputMaybe; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; +}; + /** Represents an update to a `CtfSecret`. Fields that are set will be updated. */ export type CtfSecretPatch = { credentials?: InputMaybe; @@ -374,8 +439,36 @@ export enum CtfsOrderBy { SecretsIdAsc = 'SECRETS_ID_ASC', SecretsIdDesc = 'SECRETS_ID_DESC', StartTimeAsc = 'START_TIME_ASC', - StartTimeDesc = 'START_TIME_DESC' -} + StartTimeDesc = 'START_TIME_DESC', + TitleAsc = 'TITLE_ASC', + TitleDesc = 'TITLE_DESC' +} + +/** A filter to be used against Datetime fields. All fields are combined with a logical ‘and.’ */ +export type DatetimeFilter = { + /** Not equal to the specified value, treating null like an ordinary value. */ + distinctFrom?: InputMaybe; + /** Equal to the specified value. */ + equalTo?: InputMaybe; + /** Greater than the specified value. */ + greaterThan?: InputMaybe; + /** Greater than or equal to the specified value. */ + greaterThanOrEqualTo?: InputMaybe; + /** Included in the specified list. */ + in?: InputMaybe>; + /** Is null (if `true` is specified) or is not null (if `false` is specified). */ + isNull?: InputMaybe; + /** Less than the specified value. */ + lessThan?: InputMaybe; + /** Less than or equal to the specified value. */ + lessThanOrEqualTo?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value. */ + notDistinctFrom?: InputMaybe; + /** Not equal to the specified value. */ + notEqualTo?: InputMaybe; + /** Not included in the specified list. */ + notIn?: InputMaybe>; +}; /** All input for the `deleteCtfByNodeId` mutation. */ export type DeleteCtfByNodeIdInput = { @@ -551,6 +644,32 @@ export type ImportCtfPayload = { query?: Maybe; }; +/** A filter to be used against Int fields. All fields are combined with a logical ‘and.’ */ +export type IntFilter = { + /** Not equal to the specified value, treating null like an ordinary value. */ + distinctFrom?: InputMaybe; + /** Equal to the specified value. */ + equalTo?: InputMaybe; + /** Greater than the specified value. */ + greaterThan?: InputMaybe; + /** Greater than or equal to the specified value. */ + greaterThanOrEqualTo?: InputMaybe; + /** Included in the specified list. */ + in?: InputMaybe>; + /** Is null (if `true` is specified) or is not null (if `false` is specified). */ + isNull?: InputMaybe; + /** Less than the specified value. */ + lessThan?: InputMaybe; + /** Less than or equal to the specified value. */ + lessThanOrEqualTo?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value. */ + notDistinctFrom?: InputMaybe; + /** Not equal to the specified value. */ + notEqualTo?: InputMaybe; + /** Not included in the specified list. */ + notIn?: InputMaybe>; +}; + export type Invitation = Node & { __typename?: 'Invitation'; /** Reads a single `Ctf` that is related to this `Invitation`. */ @@ -574,6 +693,20 @@ export type InvitationCondition = { profileId?: InputMaybe; }; +/** A filter to be used against `Invitation` object types. All fields are combined with a logical ‘and.’ */ +export type InvitationFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Filter by the object’s `ctfId` field. */ + ctfId?: InputMaybe; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; + /** Filter by the object’s `profileId` field. */ + profileId?: InputMaybe; +}; + /** An input for mutations affecting `Invitation` */ export type InvitationInput = { ctfId: Scalars['Int']; @@ -943,6 +1076,7 @@ export type ProfileInvitationsArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -954,6 +1088,7 @@ export type ProfileWorkOnTasksArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -968,6 +1103,22 @@ export type ProfileCondition = { username?: InputMaybe; }; +/** A filter to be used against `Profile` object types. All fields are combined with a logical ‘and.’ */ +export type ProfileFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Filter by the object’s `id` field. */ + id?: InputMaybe; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; + /** Filter by the object’s `role` field. */ + role?: InputMaybe; + /** Filter by the object’s `username` field. */ + username?: InputMaybe; +}; + /** Represents an update to a `Profile`. Fields that are set will be updated. */ export type ProfilePatch = { color?: InputMaybe; @@ -1049,10 +1200,6 @@ export type Query = Node & { * which can only query top level fields if they are in a particular form. */ query: Query; - /** Reads and enables pagination through a set of `Ctf`. */ - searchCtfs?: Maybe; - /** Reads and enables pagination through a set of `Task`. */ - searchTasks?: Maybe; /** Reads a single `Setting` using its globally unique `ID`. */ settingByNodeId?: Maybe; /** Reads and enables pagination through a set of `Setting`. */ @@ -1101,6 +1248,7 @@ export type QueryCtfSecretsArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1113,6 +1261,7 @@ export type QueryCtfsArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1124,6 +1273,7 @@ export type QueryCtfsArgs = { export type QueryGuestsArgs = { after?: InputMaybe; before?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1134,6 +1284,7 @@ export type QueryGuestsArgs = { export type QueryIncomingCtfArgs = { after?: InputMaybe; before?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1158,6 +1309,7 @@ export type QueryInvitationsArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1175,6 +1327,7 @@ export type QueryNodeArgs = { export type QueryPastCtfArgs = { after?: InputMaybe; before?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1204,6 +1357,7 @@ export type QueryProfilesArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1211,28 +1365,6 @@ export type QueryProfilesArgs = { }; -/** The root query type which gives access points into the data universe. */ -export type QuerySearchCtfsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; - offset?: InputMaybe; - search?: InputMaybe; -}; - - -/** The root query type which gives access points into the data universe. */ -export type QuerySearchTasksArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; - offset?: InputMaybe; - search?: InputMaybe; -}; - - /** The root query type which gives access points into the data universe. */ export type QuerySettingByNodeIdArgs = { nodeId: Scalars['ID']; @@ -1267,6 +1399,7 @@ export type QueryTasksArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1303,6 +1436,7 @@ export type QueryWorkOnTasksArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1420,6 +1554,32 @@ export enum Role { UserMember = 'USER_MEMBER' } +/** A filter to be used against Role fields. All fields are combined with a logical ‘and.’ */ +export type RoleFilter = { + /** Not equal to the specified value, treating null like an ordinary value. */ + distinctFrom?: InputMaybe; + /** Equal to the specified value. */ + equalTo?: InputMaybe; + /** Greater than the specified value. */ + greaterThan?: InputMaybe; + /** Greater than or equal to the specified value. */ + greaterThanOrEqualTo?: InputMaybe; + /** Included in the specified list. */ + in?: InputMaybe>; + /** Is null (if `true` is specified) or is not null (if `false` is specified). */ + isNull?: InputMaybe; + /** Less than the specified value. */ + lessThan?: InputMaybe; + /** Less than or equal to the specified value. */ + lessThanOrEqualTo?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value. */ + notDistinctFrom?: InputMaybe; + /** Not equal to the specified value. */ + notEqualTo?: InputMaybe; + /** Not included in the specified list. */ + notIn?: InputMaybe>; +}; + export type Setting = Node & { __typename?: 'Setting'; /** A globally unique identifier. Can be used in various places throughout the system to identify this single value. */ @@ -1539,6 +1699,84 @@ export type StopWorkingOnPayloadWorkOnTaskEdgeArgs = { orderBy?: InputMaybe>; }; +/** A filter to be used against String fields. All fields are combined with a logical ‘and.’ */ +export type StringFilter = { + /** Not equal to the specified value, treating null like an ordinary value. */ + distinctFrom?: InputMaybe; + /** Not equal to the specified value, treating null like an ordinary value (case-insensitive). */ + distinctFromInsensitive?: InputMaybe; + /** Ends with the specified string (case-sensitive). */ + endsWith?: InputMaybe; + /** Ends with the specified string (case-insensitive). */ + endsWithInsensitive?: InputMaybe; + /** Equal to the specified value. */ + equalTo?: InputMaybe; + /** Equal to the specified value (case-insensitive). */ + equalToInsensitive?: InputMaybe; + /** Greater than the specified value. */ + greaterThan?: InputMaybe; + /** Greater than the specified value (case-insensitive). */ + greaterThanInsensitive?: InputMaybe; + /** Greater than or equal to the specified value. */ + greaterThanOrEqualTo?: InputMaybe; + /** Greater than or equal to the specified value (case-insensitive). */ + greaterThanOrEqualToInsensitive?: InputMaybe; + /** Included in the specified list. */ + in?: InputMaybe>; + /** Included in the specified list (case-insensitive). */ + inInsensitive?: InputMaybe>; + /** Contains the specified string (case-sensitive). */ + includes?: InputMaybe; + /** Contains the specified string (case-insensitive). */ + includesInsensitive?: InputMaybe; + /** Is null (if `true` is specified) or is not null (if `false` is specified). */ + isNull?: InputMaybe; + /** Less than the specified value. */ + lessThan?: InputMaybe; + /** Less than the specified value (case-insensitive). */ + lessThanInsensitive?: InputMaybe; + /** Less than or equal to the specified value. */ + lessThanOrEqualTo?: InputMaybe; + /** Less than or equal to the specified value (case-insensitive). */ + lessThanOrEqualToInsensitive?: InputMaybe; + /** Matches the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters. */ + like?: InputMaybe; + /** Matches the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters. */ + likeInsensitive?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value. */ + notDistinctFrom?: InputMaybe; + /** Equal to the specified value, treating null like an ordinary value (case-insensitive). */ + notDistinctFromInsensitive?: InputMaybe; + /** Does not end with the specified string (case-sensitive). */ + notEndsWith?: InputMaybe; + /** Does not end with the specified string (case-insensitive). */ + notEndsWithInsensitive?: InputMaybe; + /** Not equal to the specified value. */ + notEqualTo?: InputMaybe; + /** Not equal to the specified value (case-insensitive). */ + notEqualToInsensitive?: InputMaybe; + /** Not included in the specified list. */ + notIn?: InputMaybe>; + /** Not included in the specified list (case-insensitive). */ + notInInsensitive?: InputMaybe>; + /** Does not contain the specified string (case-sensitive). */ + notIncludes?: InputMaybe; + /** Does not contain the specified string (case-insensitive). */ + notIncludesInsensitive?: InputMaybe; + /** Does not match the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters. */ + notLike?: InputMaybe; + /** Does not match the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters. */ + notLikeInsensitive?: InputMaybe; + /** Does not start with the specified string (case-sensitive). */ + notStartsWith?: InputMaybe; + /** Does not start with the specified string (case-insensitive). */ + notStartsWithInsensitive?: InputMaybe; + /** Starts with the specified string (case-sensitive). */ + startsWith?: InputMaybe; + /** Starts with the specified string (case-insensitive). */ + startsWithInsensitive?: InputMaybe; +}; + /** The root subscription type: contains realtime events you can subscribe to with the `subscription` operation. */ export type Subscription = { __typename?: 'Subscription'; @@ -1574,6 +1812,7 @@ export type TaskWorkOnTasksArgs = { after?: InputMaybe; before?: InputMaybe; condition?: InputMaybe; + filter?: InputMaybe; first?: InputMaybe; last?: InputMaybe; offset?: InputMaybe; @@ -1586,6 +1825,26 @@ export type TaskCondition = { ctfId?: InputMaybe; /** Checks for equality with the object’s `id` field. */ id?: InputMaybe; + /** Checks for equality with the object’s `title` field. */ + title?: InputMaybe; +}; + +/** A filter to be used against `Task` object types. All fields are combined with a logical ‘and.’ */ +export type TaskFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Filter by the object’s `ctfId` field. */ + ctfId?: InputMaybe; + /** Filter by the object’s `id` field. */ + id?: InputMaybe; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; + /** Filter by the object’s `solved` field. */ + solved?: InputMaybe; + /** Filter by the object’s `title` field. */ + title?: InputMaybe; }; /** Represents an update to a `Task`. Fields that are set will be updated. */ @@ -1626,7 +1885,9 @@ export enum TasksOrderBy { IdDesc = 'ID_DESC', Natural = 'NATURAL', PrimaryKeyAsc = 'PRIMARY_KEY_ASC', - PrimaryKeyDesc = 'PRIMARY_KEY_DESC' + PrimaryKeyDesc = 'PRIMARY_KEY_DESC', + TitleAsc = 'TITLE_ASC', + TitleDesc = 'TITLE_DESC' } /** All input for the `updateCtfByNodeId` mutation. */ @@ -1958,6 +2219,20 @@ export type WorkOnTaskCondition = { taskId?: InputMaybe; }; +/** A filter to be used against `WorkOnTask` object types. All fields are combined with a logical ‘and.’ */ +export type WorkOnTaskFilter = { + /** Checks for all expressions in this list. */ + and?: InputMaybe>; + /** Negates the expression. */ + not?: InputMaybe; + /** Checks for any expressions in this list. */ + or?: InputMaybe>; + /** Filter by the object’s `profileId` field. */ + profileId?: InputMaybe; + /** Filter by the object’s `taskId` field. */ + taskId?: InputMaybe; +}; + /** A connection to a list of `WorkOnTask` values. */ export type WorkOnTasksConnection = { __typename?: 'WorkOnTasksConnection'; @@ -2232,14 +2507,14 @@ export type SearchCtFsQueryVariables = Exact<{ }>; -export type SearchCtFsQuery = { __typename?: 'Query', searchCtfs?: { __typename?: 'CtfsConnection', edges: Array<{ __typename?: 'CtfsEdge', node: { __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string } }> } | null | undefined }; +export type SearchCtFsQuery = { __typename?: 'Query', ctfs?: { __typename?: 'CtfsConnection', nodes: Array<{ __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string }> } | null | undefined }; export type SearchTasksQueryVariables = Exact<{ search: Scalars['String']; }>; -export type SearchTasksQuery = { __typename?: 'Query', searchTasks?: { __typename?: 'TasksConnection', edges: Array<{ __typename?: 'TasksEdge', node: { __typename?: 'Task', nodeId: string, id: number, title: string, ctfId: number, padUrl: string, description: string, flag: string, solved?: boolean | null | undefined, category: string, ctf?: { __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string } | null | undefined, workOnTasks: { __typename?: 'WorkOnTasksConnection', nodes: Array<{ __typename?: 'WorkOnTask', nodeId: string, profileId: number, profile?: { __typename?: 'Profile', id: number, username: string, color?: string | null | undefined, description: string, role?: Role | null | undefined, nodeId: string } | null | undefined }> } } }> } | null | undefined }; +export type SearchTasksQuery = { __typename?: 'Query', tasks?: { __typename?: 'TasksConnection', nodes: Array<{ __typename?: 'Task', nodeId: string, id: number, title: string, ctfId: number, padUrl: string, description: string, flag: string, solved?: boolean | null | undefined, category: string, ctf?: { __typename?: 'Ctf', nodeId: string, id: number, granted?: boolean | null | undefined, ctfUrl?: string | null | undefined, ctftimeUrl?: string | null | undefined, description: string, endTime: string, logoUrl?: string | null | undefined, startTime: string, weight: number, title: string } | null | undefined, workOnTasks: { __typename?: 'WorkOnTasksConnection', nodes: Array<{ __typename?: 'WorkOnTask', nodeId: string, profileId: number, profile?: { __typename?: 'Profile', id: number, username: string, color?: string | null | undefined, description: string, role?: Role | null | undefined, nodeId: string } | null | undefined }> } }> } | null | undefined }; export type CtfSecretFragment = { __typename?: 'CtfSecret', nodeId: string, credentials?: string | null | undefined }; @@ -3428,11 +3703,9 @@ export function useSubscribeToProfileDeletedSubscription(options: VueApolloCompo export type SubscribeToProfileDeletedSubscriptionCompositionFunctionResult = VueApolloComposable.UseSubscriptionReturn; export const SearchCtFsDocument = gql` query SearchCTFs($search: String!) { - searchCtfs(search: $search) { - edges { - node { - ...CtfFragment - } + ctfs(filter: {title: {includes: $search}}) { + nodes { + ...CtfFragment } } } @@ -3459,13 +3732,11 @@ export function useSearchCtFsQuery(variables: SearchCtFsQueryVariables | VueComp export type SearchCtFsQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn; export const SearchTasksDocument = gql` query SearchTasks($search: String!) { - searchTasks(search: $search) { - edges { - node { - ...TaskFragment - ctf { - ...CtfFragment - } + tasks(filter: {title: {includes: $search}}) { + nodes { + ...TaskFragment + ctf { + ...CtfFragment } } } @@ -4346,24 +4617,20 @@ export const SubscribeToProfileDeleted = gql` ${ProfileFragment}`; export const SearchCtFs = gql` query SearchCTFs($search: String!) { - searchCtfs(search: $search) { - edges { - node { - ...CtfFragment - } + ctfs(filter: {title: {includes: $search}}) { + nodes { + ...CtfFragment } } } ${CtfFragment}`; export const SearchTasks = gql` query SearchTasks($search: String!) { - searchTasks(search: $search) { - edges { - node { - ...TaskFragment - ctf { - ...CtfFragment - } + tasks(filter: {title: {includes: $search}}) { + nodes { + ...TaskFragment + ctf { + ...CtfFragment } } } diff --git a/front/src/graphql/Search.graphql b/front/src/graphql/Search.graphql index 16fbf2d21..b1e47e25b 100644 --- a/front/src/graphql/Search.graphql +++ b/front/src/graphql/Search.graphql @@ -1,21 +1,17 @@ query SearchCTFs($search: String!) { - searchCtfs(search: $search) { - edges { - node { - ...CtfFragment - } + ctfs(filter: { title: { includes: $search } }) { + nodes { + ...CtfFragment } } } query SearchTasks($search: String!) { - searchTasks(search: $search) { - edges { - node { - ...TaskFragment - ctf { - ...CtfFragment - } + tasks(filter: { title: { includes: $search } }) { + nodes { + ...TaskFragment + ctf { + ...CtfFragment } } } From 00efd4781d4f84135d2081fc546475071d88ff7e Mon Sep 17 00:00:00 2001 From: SakiiR SakiiR Date: Thu, 31 Mar 2022 11:58:52 +0200 Subject: [PATCH 10/16] Added a composable for the search ctf and task dialog Moved to hotkeys-js to handle hotkeys Moved the composable in the MainLayout to handle authenticated status Typos --- front/package.json | 1 + front/src/App.vue | 16 +---- front/src/components/Dialogs/SearchDialog.vue | 59 ++++++++++++------- front/src/composables/search.ts | 34 +++++++++++ front/src/layouts/MainLayout.vue | 4 ++ front/yarn.lock | 5 ++ 6 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 front/src/composables/search.ts diff --git a/front/package.json b/front/package.json index fa71e8cce..545ba8dd3 100644 --- a/front/package.json +++ b/front/package.json @@ -22,6 +22,7 @@ "apollo-upload-client": "^16.0.0", "color-hash": "^2.0.1", "core-js": "^3.6.5", + "hotkeys-js": "^3.8.7", "quasar": "^2.0.0", "slugify": "^1.6.1", "ts-essentials": "^9.0.0" diff --git a/front/src/App.vue b/front/src/App.vue index 99c496a0f..6b34cf7f6 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -1,29 +1,17 @@ +