From 1882f33aaca5017de2ab01dd618f82bdb9e1501c Mon Sep 17 00:00:00 2001 From: Sameer Poswal <106386145+poswalsameer@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:34:00 +0530 Subject: [PATCH 01/12] Delete t.success('User details updated successfully') --- ...ccess('User details updated successfully') | 258 ------------------ 1 file changed, 258 deletions(-) delete mode 100644 t.success('User details updated successfully') diff --git a/t.success('User details updated successfully') b/t.success('User details updated successfully') deleted file mode 100644 index 333a0b57..00000000 --- a/t.success('User details updated successfully') +++ /dev/null @@ -1,258 +0,0 @@ - - SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS - - Commands marked with * may be preceded by a number, _N. - Notes in parentheses indicate the behavior if _N is given. - A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. - - h H Display this help. - q :q Q :Q ZZ Exit. - --------------------------------------------------------------------------- - - MMOOVVIINNGG - - e ^E j ^N CR * Forward one line (or _N lines). - y ^Y k ^K ^P * Backward one line (or _N lines). - f ^F ^V SPACE * Forward one window (or _N lines). - b ^B ESC-v * Backward one window (or _N lines). - z * Forward one window (and set window to _N). - w * Backward one window (and set window to _N). - ESC-SPACE * Forward one window, but don't stop at end-of-file. - d ^D * Forward one half-window (and set half-window to _N). - u ^U * Backward one half-window (and set half-window to _N). - ESC-) RightArrow * Right one half screen width (or _N positions). - ESC-( LeftArrow * Left one half screen width (or _N positions). - ESC-} ^RightArrow Right to last column displayed. - ESC-{ ^LeftArrow Left to first column. - F Forward forever; like "tail -f". - ESC-F Like F but stop when search pattern is found. - r ^R ^L Repaint screen. - R Repaint screen, discarding buffered input. - --------------------------------------------------- - Default "window" is the screen height. - Default "half-window" is half of the screen height. - --------------------------------------------------------------------------- - - SSEEAARRCCHHIINNGG - - /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. - ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. - n * Repeat previous search (for _N-th occurrence). - N * Repeat previous search in reverse direction. - ESC-n * Repeat previous search, spanning files. - ESC-N * Repeat previous search, reverse dir. & spanning files. - ESC-u Undo (toggle) search highlighting. - ESC-U Clear search highlighting. - &_p_a_t_t_e_r_n * Display only matching lines. - --------------------------------------------------- - A search pattern may begin with one or more of: - ^N or ! Search for NON-matching lines. - ^E or * Search multiple files (pass thru END OF FILE). - ^F or @ Start search at FIRST file (for /) or last file (for ?). - ^K Highlight matches, but don't move (KEEP position). - ^R Don't use REGULAR EXPRESSIONS. - ^W WRAP search if no match found. - --------------------------------------------------------------------------- - - JJUUMMPPIINNGG - - g < ESC-< * Go to first line in file (or line _N). - G > ESC-> * Go to last line in file (or line _N). - p % * Go to beginning of file (or _N percent into file). - t * Go to the (_N-th) next tag. - T * Go to the (_N-th) previous tag. - { ( [ * Find close bracket } ) ]. - } ) ] * Find open bracket { ( [. - ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. - ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. - --------------------------------------------------- - Each "find close bracket" command goes forward to the close bracket - matching the (_N-th) open bracket in the top line. - Each "find open bracket" command goes backward to the open bracket - matching the (_N-th) close bracket in the bottom line. - - m_<_l_e_t_t_e_r_> Mark the current top line with . - M_<_l_e_t_t_e_r_> Mark the current bottom line with . - '_<_l_e_t_t_e_r_> Go to a previously marked position. - '' Go to the previous position. - ^X^X Same as '. - ESC-M_<_l_e_t_t_e_r_> Clear a mark. - --------------------------------------------------- - A mark is any upper-case or lower-case letter. - Certain marks are predefined: - ^ means beginning of the file - $ means end of the file - --------------------------------------------------------------------------- - - CCHHAANNGGIINNGG FFIILLEESS - - :e [_f_i_l_e] Examine a new file. - ^X^V Same as :e. - :n * Examine the (_N-th) next file from the command line. - :p * Examine the (_N-th) previous file from the command line. - :x * Examine the first (or _N-th) file from the command line. - :d Delete the current file from the command line list. - = ^G :f Print current file name. - --------------------------------------------------------------------------- - - MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS - - -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. - --_<_n_a_m_e_> Toggle a command line option, by name. - __<_f_l_a_g_> Display the setting of a command line option. - ___<_n_a_m_e_> Display the setting of an option, by name. - +_c_m_d Execute the less cmd each time a new file is examined. - - !_c_o_m_m_a_n_d Execute the shell command with $SHELL. - |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. - s _f_i_l_e Save input to a file. - v Edit the current file with $VISUAL or $EDITOR. - V Print version number of "less". - --------------------------------------------------------------------------- - - OOPPTTIIOONNSS - - Most options may be changed either on the command line, - or from within less by using the - or -- command. - Options may be given in one of two forms: either a single - character preceded by a -, or a name preceded by --. - - -? ........ --help - Display help (from command line). - -a ........ --search-skip-screen - Search skips current screen. - -A ........ --SEARCH-SKIP-SCREEN - Search starts just after target line. - -b [_N] .... --buffers=[_N] - Number of buffers. - -B ........ --auto-buffers - Don't automatically allocate buffers for pipes. - -c ........ --clear-screen - Repaint by clearing rather than scrolling. - -d ........ --dumb - Dumb terminal. - -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r - Set screen colors. - -e -E .... --quit-at-eof --QUIT-AT-EOF - Quit at end of file. - -f ........ --force - Force open non-regular files. - -F ........ --quit-if-one-screen - Quit if entire file fits on first screen. - -g ........ --hilite-search - Highlight only last match for searches. - -G ........ --HILITE-SEARCH - Don't highlight any matches for searches. - -h [_N] .... --max-back-scroll=[_N] - Backward scroll limit. - -i ........ --ignore-case - Ignore case in searches that do not contain uppercase. - -I ........ --IGNORE-CASE - Ignore case in all searches. - -j [_N] .... --jump-target=[_N] - Screen position of target lines. - -J ........ --status-column - Display a status column at left edge of screen. - -k [_f_i_l_e] . --lesskey-file=[_f_i_l_e] - Use a lesskey file. - -K ........ --quit-on-intr - Exit less in response to ctrl-C. - -L ........ --no-lessopen - Ignore the LESSOPEN environment variable. - -m -M .... --long-prompt --LONG-PROMPT - Set prompt style. - -n -N .... --line-numbers --LINE-NUMBERS - Don't use line numbers. - -o [_f_i_l_e] . --log-file=[_f_i_l_e] - Copy to log file (standard input only). - -O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e] - Copy to log file (unconditionally overwrite). - -p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n] - Start at pattern (from command line). - -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] - Define new prompt. - -q -Q .... --quiet --QUIET --silent --SILENT - Quiet the terminal bell. - -r -R .... --raw-control-chars --RAW-CONTROL-CHARS - Output "raw" control characters. - -s ........ --squeeze-blank-lines - Squeeze multiple blank lines. - -S ........ --chop-long-lines - Chop (truncate) long lines rather than wrapping. - -t [_t_a_g] .. --tag=[_t_a_g] - Find a tag. - -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] - Use an alternate tags file. - -u -U .... --underline-special --UNDERLINE-SPECIAL - Change handling of backspaces. - -V ........ --version - Display the version number of "less". - -w ........ --hilite-unread - Highlight first new line after forward-screen. - -W ........ --HILITE-UNREAD - Highlight first new line after any forward movement. - -x [_N[,...]] --tabs=[_N[,...]] - Set tab stops. - -X ........ --no-init - Don't use termcap init/deinit strings. - -y [_N] .... --max-forw-scroll=[_N] - Forward scroll limit. - -z [_N] .... --window=[_N] - Set size of window. - -" [_c[_c]] . --quotes=[_c[_c]] - Set shell quote characters. - -~ ........ --tilde - Don't display tildes after end of file. - -# [_N] .... --shift=[_N] - Set horizontal scroll amount (0 = one half screen width). - --file-size - Automatically determine the size of the input file. - --follow-name - The F command changes files if the input file is renamed. - --incsearch - Search file as each pattern character is typed in. - --line-num-width=N - Set the width of the -N line number field to N characters. - --mouse - Enable mouse input. - --no-keypad - Don't send termcap keypad init/deinit strings. - --no-histdups - Remove duplicates from command history. - --rscroll=C - Set the character used to mark truncated lines. - --save-marks - Retain marks across invocations of less. - --status-col-width=N - Set the width of the -J status column to N characters. - --use-backslash - Subsequent options use backslash as escape char. - --use-color - Enables colored text. - --wheel-lines=N - Each click of the mouse wheel moves N lines. - - - --------------------------------------------------------------------------- - - LLIINNEE EEDDIITTIINNGG - - These keys can be used to edit text being entered - on the "command line" at the bottom of the screen. - - RightArrow ..................... ESC-l ... Move cursor right one character. - LeftArrow ...................... ESC-h ... Move cursor left one character. - ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. - ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. - HOME ........................... ESC-0 ... Move cursor to start of line. - END ............................ ESC-$ ... Move cursor to end of line. - BACKSPACE ................................ Delete char to left of cursor. - DELETE ......................... ESC-x ... Delete char under cursor. - ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. - ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. - ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. - UpArrow ........................ ESC-k ... Retrieve previous command line. - DownArrow ...................... ESC-j ... Retrieve next command line. - TAB ...................................... Complete filename & cycle. - SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. - ctrl-L ................................... Complete filename, list all. From 675f6e4db1bb461f102b33d687a45a29971b298b Mon Sep 17 00:00:00 2001 From: Sameer Poswal <106386145+poswalsameer@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:34:20 +0530 Subject: [PATCH 02/12] Delete t updateSelf = useCallback(async () => { --- t updateSelf = useCallback(async () => { | 664 ----------------------- 1 file changed, 664 deletions(-) delete mode 100644 t updateSelf = useCallback(async () => { diff --git a/t updateSelf = useCallback(async () => { b/t updateSelf = useCallback(async () => { deleted file mode 100644 index 95c798b9..00000000 --- a/t updateSelf = useCallback(async () => { +++ /dev/null @@ -1,664 +0,0 @@ -diff --git a/apps/platform/.eslintrc.cjs b/apps/platform/.eslintrc.cjs -index 28a8b27..fa9233a 100644 ---- a/apps/platform/.eslintrc.cjs -+++ b/apps/platform/.eslintrc.cjs -@@ -7,24 +7,13 @@ module.exports = { - }, - rules: { - 'import/no-extraneous-dependencies': 0, -- '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', -- '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': ['warn'], -- '@typescript-eslint/no-unsafe-call': 'off', -- '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/space-before-function-paren': 'off', - '@typescript-eslint/strict-boolean-expressions': 'off', -- '@typescript-eslint/prefer-nullish-coalescing': 'off', -- 'space-before-function-paren': 'off', -- '@typescript-eslint/member-delimiter-style': 'off', - '@typescript-eslint/no-confusing-void-expression': 'off', - '@typescript-eslint/no-floating-promises': 'off', -- '@typescript-eslint/no-misused-promises': 'off', -- '@typescript-eslint/no-unsafe-assignment': 'off', -- '@typescript-eslint/no-unsafe-member-access': 'off', -- '@typescript-eslint/no-unsafe-argument': 'off', -- '@typescript-eslint/no-unnecessary-condition': 'off' -+ '@typescript-eslint/no-misused-promises': 'off' - } - } -diff --git a/apps/platform/src/app/(main)/page.tsx b/apps/platform/src/app/(main)/page.tsx -index fe8fa2a..9a9cb2a 100644 ---- a/apps/platform/src/app/(main)/page.tsx -+++ b/apps/platform/src/app/(main)/page.tsx -@@ -6,7 +6,6 @@ import type { - ProjectWithCount, - Workspace - } from '@keyshade/schema' --import { ProjectController } from '@keyshade/api-client' - import { AddSVG } from '@public/svg/shared' - import { FolderSVG } from '@public/svg/dashboard' - import ProjectCard from '@/components/dashboard/projectCard' -@@ -38,6 +37,7 @@ import { - DialogHeader, - DialogTrigger - } from '@/components/ui/dialog' -+import ControllerInstance from '@/lib/controller-instance' -  - export default function Index(): JSX.Element { - const [isSheetOpen, setIsSheetOpen] = useState(false) -@@ -76,16 +76,13 @@ export default function Index(): JSX.Element { - // If a workspace is selected, we want to fetch all the projects - // under that workspace and display it in the dashboard. - useEffect(() => { -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - async function getAllProjects() { - if (currentWorkspace) { -- const { success, error, data } = await projectController.getAllProjects( -- { workspaceSlug: currentWorkspace.slug }, -- {} -- ) -+ const { success, error, data } = -+ await ControllerInstance.getInstance().projectController.getAllProjects( -+ { workspaceSlug: currentWorkspace.slug }, -+ {} -+ ) -  - if (success && data) { - setProjects(data.items) -@@ -105,16 +102,13 @@ export default function Index(): JSX.Element { - // Function to create a new project - const createNewProject = useCallback(async () => { - if (currentWorkspace) { -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - newProjectData.workspaceSlug = currentWorkspace.slug -  -- const { data, error, success } = await projectController.createProject( -- newProjectData, -- {} -- ) -+ const { data, error, success } = -+ await ControllerInstance.getInstance().projectController.createProject( -+ newProjectData, -+ {} -+ ) -  - if (success && data) { - setProjects([ -diff --git a/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx b/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -index 18134ab..e1bd8e6 100644 ---- a/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -+++ b/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -@@ -5,6 +5,7 @@ import { usePathname } from 'next/navigation' - import dayjs, { extend } from 'dayjs' - import relativeTime from 'dayjs/plugin/relativeTime' - import { NoteIconSVG } from '@public/svg/secret' -+import type { GetAllSecretsOfProjectResponse } from '@keyshade/schema' - import { - Accordion, - AccordionContent, -@@ -19,8 +20,6 @@ import { - TableHeader, - TableRow - } from '@/components/ui/table' --import type { Secret } from '@keyshade/schema' --import { SecretController } from '@keyshade/api-client' - import { ScrollArea } from '@/components/ui/scroll-area' - import { - Tooltip, -@@ -29,31 +28,28 @@ import { - TooltipTrigger - } from '@/components/ui/tooltip' - import { Skeleton } from '@/components/ui/skeleton' -+import ControllerInstance from '@/lib/controller-instance' -  - extend(relativeTime) -  - function SecretPage(): React.JSX.Element { -- const [allSecrets, setAllSecrets] = useState() -+ const [allSecrets, setAllSecrets] = -+ useState() - const [isLoading, setIsLoading] = useState(true) - const pathname = usePathname() -  - useEffect(() => { - setIsLoading(true) -  -- const secretController = new SecretController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - async function getAllSecretsByProjectSlug() { - const { success, error, data } = -- await secretController.getAllSecretsOfProject( -+ await ControllerInstance.getInstance().secretController.getAllSecretsOfProject( - { projectSlug: pathname.split('/')[2] }, - {} - ) -  - if (success && data) { -- //@ts-ignore -- setAllSecrets(data) -+ setAllSecrets(data.items) - } else { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) -@@ -68,9 +64,9 @@ function SecretPage(): React.JSX.Element { - if (isLoading) { - return ( -
 --  --  --  -+  -+  -+  -
 - ) - } -@@ -82,7 +78,7 @@ function SecretPage(): React.JSX.Element { - collapsible - type="single" - > -- {allSecrets?.map((secret) => { -+ {allSecrets?.map(({ secret, values }) => { - return ( -  -  -  -- {secret.versions.map((value) => { -+ {values.map((value) => { - return ( -  - {value.environment.slug} -@@ -147,7 +143,7 @@ function SecretPage(): React.JSX.Element { - ) - } -  --function SerectLoader(): React.JSX.Element { -+function SecretLoader(): React.JSX.Element { - return ( -
 -
 -diff --git a/apps/platform/src/app/(main)/project/[project]/layout.tsx b/apps/platform/src/app/(main)/project/[project]/layout.tsx -index 1eb511b..9edfb0b 100644 ---- a/apps/platform/src/app/(main)/project/[project]/layout.tsx -+++ b/apps/platform/src/app/(main)/project/[project]/layout.tsx -@@ -2,6 +2,7 @@ - import { useEffect, useState } from 'react' - import { useSearchParams } from 'next/navigation' - import { AddSVG } from '@public/svg/shared' -+import type { Project } from '@keyshade/schema' - import { Button } from '@/components/ui/button' - import { - Dialog, -@@ -13,8 +14,7 @@ import { - } from '@/components/ui/dialog' - import { Input } from '@/components/ui/input' - import { Label } from '@/components/ui/label' --import { ProjectController } from '@keyshade/api-client' --import type { Project } from '@keyshade/schema' -+import ControllerInstance from '@/lib/controller-instance' -  - interface DetailedProjectPageProps { - params: { project: string } -@@ -38,29 +38,22 @@ function DetailedProjectPage({ - const tab = searchParams.get('tab') ?? 'rollup-details' -  - useEffect(() => { -+ async function getProjectBySlug() { -+ const { success, error, data } = -+ await ControllerInstance.getInstance().projectController.getProject( -+ { projectSlug: params.project }, -+ {} -+ ) -  -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- -- async function getProjectBySlug(){ -- const {success, error, data} = await projectController.getProject( -- {projectSlug: params.project}, -- {} -- ) -- -- if( success && data ){ -- //@ts-ignore -+ if (success && data) { - setCurrentProject(data) -- } -- else{ -+ } else { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) - } - } -  - getProjectBySlug() -- - }, [params.project]) -  - return ( -diff --git a/apps/platform/src/app/(main)/settings/@profile/page.tsx b/apps/platform/src/app/(main)/settings/@profile/page.tsx -index 21de60b..4559ec6 100644 ---- a/apps/platform/src/app/(main)/settings/@profile/page.tsx -+++ b/apps/platform/src/app/(main)/settings/@profile/page.tsx -@@ -1,54 +1,52 @@ - 'use client' --import React, { useEffect, useState } from 'react' -+import React, { useCallback, useEffect, useState } from 'react' - import { toast } from 'sonner' --import type { User } from '@keyshade/schema' - import InputLoading from './loading' - import { Input } from '@/components/ui/input' - import { Separator } from '@/components/ui/separator' -+import ControllerInstance from '@/lib/controller-instance' - import { Button } from '@/components/ui/button' --import { apiClient } from '@/lib/api-client' -- --type UserData = Omit< -- User, -- 'id' | 'isActive' | 'isOnboardingFinished' | 'isAdmin' | 'authProvider' --> --async function getUserDetails(): Promise { -- try { -- return await apiClient.get('/user') -- } catch (error) { -- // eslint-disable-next-line no-console -- we need to log the error -- console.error(error) -- } --} -- --async function updateUserDetails(userData: UserData): Promise { -- try { -- await apiClient.put('/user', userData) -- } catch (error) { -- // eslint-disable-next-line no-console -- we need to log the error -- console.error(error) -- } --} -  - function ProfilePage(): React.JSX.Element { - const [isLoading, setIsLoading] = useState(true) -- const [userData, setUserData] = useState({ -+ const [userData, setUserData] = useState({ - email: '', - name: '', - profilePictureUrl: '' - }) - const [isModified, setIsModified] = useState(false) -  -+ const updateSelf = useCallback(async () => { -+ try { -+ await ControllerInstance.getInstance().userController.updateSelf( -+ { -+ name: userData.name, -+ email: userData.email -+ }, -+ {} -+ ) -+ toast.success('Profile updated successfully') -+ } catch (error) { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) -+ } -+ setIsModified(false) -+ }, [userData]) -+ - useEffect(() => { -- getUserDetails() -- .then((data) => { -- if (data) { -+ ControllerInstance.getInstance() -+ .userController.getSelf() -+ .then(({ data, success, error }) => { -+ if (success && data) { - setUserData({ - email: data.email, -- name: data.name ?? '', -- profilePictureUrl: data.profilePictureUrl -+ name: data.name, -+ profilePictureUrl: data.profilePictureUrl || '' - }) - setIsLoading(false) -+ } else { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) - } - }) - .catch((error) => { -@@ -67,7 +65,7 @@ function ProfilePage(): React.JSX.Element { - Upload a picture to change your avatar across Keyshade. -  -
 --
{' '} -+
 - {/* //! This is will be replaced by an image tag */} -
 - {/* Name */} -@@ -114,20 +112,7 @@ function ProfilePage(): React.JSX.Element { - )} -
 -
 -- { -- updateUserDetails(userData) -- .then(() => { -- toast.success('User details updated successfully') -- }) -- .catch(() => { -- toast.error('Failed to update user details') -- }) -- setIsModified(false) -- }} -- variant="secondary" -- > -+  -
 -diff --git a/apps/platform/src/components/shared/sidebar/index.tsx b/apps/platform/src/components/shared/sidebar/index.tsx -index ee7cd9b..7da768b 100644 ---- a/apps/platform/src/components/shared/sidebar/index.tsx -+++ b/apps/platform/src/components/shared/sidebar/index.tsx -@@ -6,8 +6,8 @@ import { - SettingsSVG, - TeamSVG - } from '@public/svg/shared' --import { Combobox } from '@/components/ui/combobox' - import SidebarTab from './sidebarTab' -+import { Combobox } from '@/components/ui/combobox' -  - function Sidebar(): JSX.Element { - const sidebarTabData = [ -diff --git a/apps/platform/src/components/ui/combobox.tsx b/apps/platform/src/components/ui/combobox.tsx -index b3107dc..8414098 100644 ---- a/apps/platform/src/components/ui/combobox.tsx -+++ b/apps/platform/src/components/ui/combobox.tsx -@@ -5,27 +5,6 @@ import { useEffect, useState } from 'react' - import { useRouter } from 'next/navigation' - import { toast } from 'sonner' - import { AddSVG } from '@public/svg/shared' --import { cn } from '@/lib/utils' --import { -- Command, -- CommandEmpty, -- CommandInput, -- CommandItem, -- CommandList --} from '@/components/ui/command' --import { -- Popover, -- PopoverContent, -- PopoverTrigger --} from '@/components/ui/popover' --import { apiClient } from '@/lib/api-client' --// import type { Workspace } from '@/types' --import { zWorkspace } from '@/types' --import { -- getCurrentWorkspace, -- setCurrentWorkspace, -- setWorkspace --} from '@/lib/workspace-storage' - import type { Workspace } from '@keyshade/schema' - import { Input } from './input' - import { Label } from './label' -@@ -38,39 +17,43 @@ import { - DialogTrigger - } from './dialog' - import { Button } from './button' --import { WorkspaceSchema } from '@keyshade/schema/schemas' -- --interface WorkspaceResponse { -- items: Workspace[] -- metadata: { -- page: number -- perPage: number -- pageCount: number -- totalCount: number -- links: { -- self: string -- first: string -- previous: string | null -- next: string | null -- last: string -- } -- } --} -+import { -+ getCurrentWorkspace, -+ setCurrentWorkspace, -+ setWorkspace -+} from '@/lib/workspace-storage' -+import { cn } from '@/lib/utils' -+import { -+ Popover, -+ PopoverContent, -+ PopoverTrigger -+} from '@/components/ui/popover' -+import { -+ Command, -+ CommandEmpty, -+ CommandInput, -+ CommandItem, -+ CommandList -+} from '@/components/ui/command' -+import ControllerInstance from '@/lib/controller-instance' -  - async function getAllWorkspace(): Promise { - try { -- const workspaceData: WorkspaceResponse = -- await apiClient.get('/workspace') -+ const { data, success, error } = -+ await ControllerInstance.getInstance().workspaceController.getWorkspacesOfUser( -+ {}, -+ {} -+ ) -  -- // TODO: We are getting error here from the success flag, need to see this again -- // const { success, data } = WorkspaceSchema.array().safeParse(workspaceData.items) -- // if (!success) { -- // throw new Error('Invalid data') -- // } -+ if (error) { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) -+ return undefined -+ } -  -- return workspaceData.items -- // return data -- // return workspaceData; -+ if (success && data) { -+ return data.items -+ } - } catch (error) { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) -@@ -92,9 +75,13 @@ export function Combobox(): React.JSX.Element { - } - setIsNameEmpty(false) - try { -- const response = await apiClient.post('/workspace', { -- name -- }) -+ const response = -+ await ControllerInstance.getInstance().workspaceController.createWorkspace( -+ { -+ name -+ }, -+ {} -+ ) - setCurrentWorkspace(response) - setOpen(false) - } catch (error) { -diff --git a/apps/platform/src/lib/controller-instance.ts b/apps/platform/src/lib/controller-instance.ts -index fe432b7..a766038 100644 ---- a/apps/platform/src/lib/controller-instance.ts -+++ b/apps/platform/src/lib/controller-instance.ts -@@ -1,30 +1,90 @@ --import { AuthController } from '@keyshade/api-client' -+import { -+ AuthController, -+ EnvironmentController, -+ ProjectController, -+ SecretController, -+ UserController, -+ VariableController, -+ WorkspaceController, -+ WorkspaceMembershipController, -+ WorkspaceRoleController -+} from '@keyshade/api-client' -  - export default class ControllerInstance { - private static instance: ControllerInstance | null -  -- private _authController: AuthController | null = null -+ private _authController: AuthController -+ private _userController: UserController -+ private _workspaceController: WorkspaceController -+ private _workspaceMembershipController: WorkspaceMembershipController -+ private _workspaceRoleController: WorkspaceRoleController -+ private _projectController: ProjectController -+ private _environmentController: EnvironmentController -+ private _secretController: SecretController -+ private _variableController: VariableController -  - get authController(): AuthController { -- if (!this._authController) { -- throw new Error('ControllerInstance not initialized') -- } - return this._authController - } -  -- static initialize(baseUrl: string): void { -- if (!ControllerInstance.instance) { -- const instance = new ControllerInstance() -+ get workspaceController(): WorkspaceController { -+ return this._workspaceController -+ } -+ -+ get workspaceMembershipController(): WorkspaceMembershipController { -+ return this._workspaceMembershipController -+ } -  -- instance._authController = new AuthController(baseUrl) -+ get workspaceRoleController(): WorkspaceRoleController { -+ return this._workspaceRoleController -+ } -  -- ControllerInstance.instance = instance -- } -+ get projectController(): ProjectController { -+ return this._projectController -+ } -+ -+ get environmentController(): EnvironmentController { -+ return this._environmentController -+ } -+ -+ get secretController(): SecretController { -+ return this._secretController -+ } -+ -+ get variableController(): VariableController { -+ return this._variableController -+ } -+ -+ get userController(): UserController { -+ return this._userController - } -  - static getInstance(): ControllerInstance { - if (!ControllerInstance.instance) { -- throw new Error('ControllerInstance not initialized') -+ ControllerInstance.instance = new ControllerInstance() -+ ControllerInstance.instance._authController = new AuthController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._userController = new UserController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._workspaceController = -+ new WorkspaceController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._workspaceMembershipController = -+ new WorkspaceMembershipController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._workspaceRoleController = -+ new WorkspaceRoleController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._projectController = new ProjectController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._environmentController = -+ new EnvironmentController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._secretController = new SecretController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._variableController = new VariableController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) - } - return ControllerInstance.instance - } -diff --git a/packages/api-client/src/index.ts b/packages/api-client/src/index.ts -index 79ab5f6..edd344f 100644 ---- a/packages/api-client/src/index.ts -+++ b/packages/api-client/src/index.ts -@@ -8,6 +8,7 @@ import WorkspaceController from '@api-client/controllers/workspace' - import WorkspaceRoleController from '@api-client/controllers/workspace-role' - import WorkspaceMembershipController from '@api-client/controllers/workspace-membership' - import AuthController from '@api-client/controllers/auth' -+import UserController from '@api-client/controllers/user' - export { - EnvironmentController, - SecretController, -@@ -18,5 +19,6 @@ export { - WorkspaceController, - WorkspaceRoleController, - WorkspaceMembershipController, -- AuthController -+ AuthController, -+ UserController - } -diff --git a/packages/schema/src/secret/index.ts b/packages/schema/src/secret/index.ts -index ff5b499..4277679 100644 ---- a/packages/schema/src/secret/index.ts -+++ b/packages/schema/src/secret/index.ts -@@ -100,15 +100,17 @@ export const GetAllSecretsOfProjectResponseSchema = PageResponseSchema( - name: z.string() - }) - }), -- values: z.object({ -- environment: z.object({ -- id: z.string(), -- name: z.string(), -- slug: z.string() -- }), -- value: z.string(), -- version: z.number() -- }) -+ values: z.array( -+ z.object({ -+ environment: z.object({ -+ id: z.string(), -+ name: z.string(), -+ slug: z.string() -+ }), -+ value: z.string(), -+ version: z.number() -+ }) -+ ) - }) - ) -  From 73d0888d9aea2633541e515e151f0411c685a26a Mon Sep 17 00:00:00 2001 From: Sameer Poswal <106386145+poswalsameer@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:35:40 +0530 Subject: [PATCH 03/12] Delete erDetails(userData) --- erDetails(userData) | 664 -------------------------------------------- 1 file changed, 664 deletions(-) delete mode 100644 erDetails(userData) diff --git a/erDetails(userData) b/erDetails(userData) deleted file mode 100644 index 95c798b9..00000000 --- a/erDetails(userData) +++ /dev/null @@ -1,664 +0,0 @@ -diff --git a/apps/platform/.eslintrc.cjs b/apps/platform/.eslintrc.cjs -index 28a8b27..fa9233a 100644 ---- a/apps/platform/.eslintrc.cjs -+++ b/apps/platform/.eslintrc.cjs -@@ -7,24 +7,13 @@ module.exports = { - }, - rules: { - 'import/no-extraneous-dependencies': 0, -- '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', -- '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': ['warn'], -- '@typescript-eslint/no-unsafe-call': 'off', -- '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/space-before-function-paren': 'off', - '@typescript-eslint/strict-boolean-expressions': 'off', -- '@typescript-eslint/prefer-nullish-coalescing': 'off', -- 'space-before-function-paren': 'off', -- '@typescript-eslint/member-delimiter-style': 'off', - '@typescript-eslint/no-confusing-void-expression': 'off', - '@typescript-eslint/no-floating-promises': 'off', -- '@typescript-eslint/no-misused-promises': 'off', -- '@typescript-eslint/no-unsafe-assignment': 'off', -- '@typescript-eslint/no-unsafe-member-access': 'off', -- '@typescript-eslint/no-unsafe-argument': 'off', -- '@typescript-eslint/no-unnecessary-condition': 'off' -+ '@typescript-eslint/no-misused-promises': 'off' - } - } -diff --git a/apps/platform/src/app/(main)/page.tsx b/apps/platform/src/app/(main)/page.tsx -index fe8fa2a..9a9cb2a 100644 ---- a/apps/platform/src/app/(main)/page.tsx -+++ b/apps/platform/src/app/(main)/page.tsx -@@ -6,7 +6,6 @@ import type { - ProjectWithCount, - Workspace - } from '@keyshade/schema' --import { ProjectController } from '@keyshade/api-client' - import { AddSVG } from '@public/svg/shared' - import { FolderSVG } from '@public/svg/dashboard' - import ProjectCard from '@/components/dashboard/projectCard' -@@ -38,6 +37,7 @@ import { - DialogHeader, - DialogTrigger - } from '@/components/ui/dialog' -+import ControllerInstance from '@/lib/controller-instance' -  - export default function Index(): JSX.Element { - const [isSheetOpen, setIsSheetOpen] = useState(false) -@@ -76,16 +76,13 @@ export default function Index(): JSX.Element { - // If a workspace is selected, we want to fetch all the projects - // under that workspace and display it in the dashboard. - useEffect(() => { -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - async function getAllProjects() { - if (currentWorkspace) { -- const { success, error, data } = await projectController.getAllProjects( -- { workspaceSlug: currentWorkspace.slug }, -- {} -- ) -+ const { success, error, data } = -+ await ControllerInstance.getInstance().projectController.getAllProjects( -+ { workspaceSlug: currentWorkspace.slug }, -+ {} -+ ) -  - if (success && data) { - setProjects(data.items) -@@ -105,16 +102,13 @@ export default function Index(): JSX.Element { - // Function to create a new project - const createNewProject = useCallback(async () => { - if (currentWorkspace) { -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - newProjectData.workspaceSlug = currentWorkspace.slug -  -- const { data, error, success } = await projectController.createProject( -- newProjectData, -- {} -- ) -+ const { data, error, success } = -+ await ControllerInstance.getInstance().projectController.createProject( -+ newProjectData, -+ {} -+ ) -  - if (success && data) { - setProjects([ -diff --git a/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx b/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -index 18134ab..e1bd8e6 100644 ---- a/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -+++ b/apps/platform/src/app/(main)/project/[project]/@secret/page.tsx -@@ -5,6 +5,7 @@ import { usePathname } from 'next/navigation' - import dayjs, { extend } from 'dayjs' - import relativeTime from 'dayjs/plugin/relativeTime' - import { NoteIconSVG } from '@public/svg/secret' -+import type { GetAllSecretsOfProjectResponse } from '@keyshade/schema' - import { - Accordion, - AccordionContent, -@@ -19,8 +20,6 @@ import { - TableHeader, - TableRow - } from '@/components/ui/table' --import type { Secret } from '@keyshade/schema' --import { SecretController } from '@keyshade/api-client' - import { ScrollArea } from '@/components/ui/scroll-area' - import { - Tooltip, -@@ -29,31 +28,28 @@ import { - TooltipTrigger - } from '@/components/ui/tooltip' - import { Skeleton } from '@/components/ui/skeleton' -+import ControllerInstance from '@/lib/controller-instance' -  - extend(relativeTime) -  - function SecretPage(): React.JSX.Element { -- const [allSecrets, setAllSecrets] = useState() -+ const [allSecrets, setAllSecrets] = -+ useState() - const [isLoading, setIsLoading] = useState(true) - const pathname = usePathname() -  - useEffect(() => { - setIsLoading(true) -  -- const secretController = new SecretController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- - async function getAllSecretsByProjectSlug() { - const { success, error, data } = -- await secretController.getAllSecretsOfProject( -+ await ControllerInstance.getInstance().secretController.getAllSecretsOfProject( - { projectSlug: pathname.split('/')[2] }, - {} - ) -  - if (success && data) { -- //@ts-ignore -- setAllSecrets(data) -+ setAllSecrets(data.items) - } else { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) -@@ -68,9 +64,9 @@ function SecretPage(): React.JSX.Element { - if (isLoading) { - return ( -
 --  --  --  -+  -+  -+  -
 - ) - } -@@ -82,7 +78,7 @@ function SecretPage(): React.JSX.Element { - collapsible - type="single" - > -- {allSecrets?.map((secret) => { -+ {allSecrets?.map(({ secret, values }) => { - return ( -  -  -  -- {secret.versions.map((value) => { -+ {values.map((value) => { - return ( -  - {value.environment.slug} -@@ -147,7 +143,7 @@ function SecretPage(): React.JSX.Element { - ) - } -  --function SerectLoader(): React.JSX.Element { -+function SecretLoader(): React.JSX.Element { - return ( -
 -
 -diff --git a/apps/platform/src/app/(main)/project/[project]/layout.tsx b/apps/platform/src/app/(main)/project/[project]/layout.tsx -index 1eb511b..9edfb0b 100644 ---- a/apps/platform/src/app/(main)/project/[project]/layout.tsx -+++ b/apps/platform/src/app/(main)/project/[project]/layout.tsx -@@ -2,6 +2,7 @@ - import { useEffect, useState } from 'react' - import { useSearchParams } from 'next/navigation' - import { AddSVG } from '@public/svg/shared' -+import type { Project } from '@keyshade/schema' - import { Button } from '@/components/ui/button' - import { - Dialog, -@@ -13,8 +14,7 @@ import { - } from '@/components/ui/dialog' - import { Input } from '@/components/ui/input' - import { Label } from '@/components/ui/label' --import { ProjectController } from '@keyshade/api-client' --import type { Project } from '@keyshade/schema' -+import ControllerInstance from '@/lib/controller-instance' -  - interface DetailedProjectPageProps { - params: { project: string } -@@ -38,29 +38,22 @@ function DetailedProjectPage({ - const tab = searchParams.get('tab') ?? 'rollup-details' -  - useEffect(() => { -+ async function getProjectBySlug() { -+ const { success, error, data } = -+ await ControllerInstance.getInstance().projectController.getProject( -+ { projectSlug: params.project }, -+ {} -+ ) -  -- const projectController = new ProjectController( -- process.env.NEXT_PUBLIC_BACKEND_URL -- ) -- -- async function getProjectBySlug(){ -- const {success, error, data} = await projectController.getProject( -- {projectSlug: params.project}, -- {} -- ) -- -- if( success && data ){ -- //@ts-ignore -+ if (success && data) { - setCurrentProject(data) -- } -- else{ -+ } else { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) - } - } -  - getProjectBySlug() -- - }, [params.project]) -  - return ( -diff --git a/apps/platform/src/app/(main)/settings/@profile/page.tsx b/apps/platform/src/app/(main)/settings/@profile/page.tsx -index 21de60b..4559ec6 100644 ---- a/apps/platform/src/app/(main)/settings/@profile/page.tsx -+++ b/apps/platform/src/app/(main)/settings/@profile/page.tsx -@@ -1,54 +1,52 @@ - 'use client' --import React, { useEffect, useState } from 'react' -+import React, { useCallback, useEffect, useState } from 'react' - import { toast } from 'sonner' --import type { User } from '@keyshade/schema' - import InputLoading from './loading' - import { Input } from '@/components/ui/input' - import { Separator } from '@/components/ui/separator' -+import ControllerInstance from '@/lib/controller-instance' - import { Button } from '@/components/ui/button' --import { apiClient } from '@/lib/api-client' -- --type UserData = Omit< -- User, -- 'id' | 'isActive' | 'isOnboardingFinished' | 'isAdmin' | 'authProvider' --> --async function getUserDetails(): Promise { -- try { -- return await apiClient.get('/user') -- } catch (error) { -- // eslint-disable-next-line no-console -- we need to log the error -- console.error(error) -- } --} -- --async function updateUserDetails(userData: UserData): Promise { -- try { -- await apiClient.put('/user', userData) -- } catch (error) { -- // eslint-disable-next-line no-console -- we need to log the error -- console.error(error) -- } --} -  - function ProfilePage(): React.JSX.Element { - const [isLoading, setIsLoading] = useState(true) -- const [userData, setUserData] = useState({ -+ const [userData, setUserData] = useState({ - email: '', - name: '', - profilePictureUrl: '' - }) - const [isModified, setIsModified] = useState(false) -  -+ const updateSelf = useCallback(async () => { -+ try { -+ await ControllerInstance.getInstance().userController.updateSelf( -+ { -+ name: userData.name, -+ email: userData.email -+ }, -+ {} -+ ) -+ toast.success('Profile updated successfully') -+ } catch (error) { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) -+ } -+ setIsModified(false) -+ }, [userData]) -+ - useEffect(() => { -- getUserDetails() -- .then((data) => { -- if (data) { -+ ControllerInstance.getInstance() -+ .userController.getSelf() -+ .then(({ data, success, error }) => { -+ if (success && data) { - setUserData({ - email: data.email, -- name: data.name ?? '', -- profilePictureUrl: data.profilePictureUrl -+ name: data.name, -+ profilePictureUrl: data.profilePictureUrl || '' - }) - setIsLoading(false) -+ } else { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) - } - }) - .catch((error) => { -@@ -67,7 +65,7 @@ function ProfilePage(): React.JSX.Element { - Upload a picture to change your avatar across Keyshade. -  -
 --
{' '} -+
 - {/* //! This is will be replaced by an image tag */} -
 - {/* Name */} -@@ -114,20 +112,7 @@ function ProfilePage(): React.JSX.Element { - )} -
 -
 -- { -- updateUserDetails(userData) -- .then(() => { -- toast.success('User details updated successfully') -- }) -- .catch(() => { -- toast.error('Failed to update user details') -- }) -- setIsModified(false) -- }} -- variant="secondary" -- > -+  -
 -diff --git a/apps/platform/src/components/shared/sidebar/index.tsx b/apps/platform/src/components/shared/sidebar/index.tsx -index ee7cd9b..7da768b 100644 ---- a/apps/platform/src/components/shared/sidebar/index.tsx -+++ b/apps/platform/src/components/shared/sidebar/index.tsx -@@ -6,8 +6,8 @@ import { - SettingsSVG, - TeamSVG - } from '@public/svg/shared' --import { Combobox } from '@/components/ui/combobox' - import SidebarTab from './sidebarTab' -+import { Combobox } from '@/components/ui/combobox' -  - function Sidebar(): JSX.Element { - const sidebarTabData = [ -diff --git a/apps/platform/src/components/ui/combobox.tsx b/apps/platform/src/components/ui/combobox.tsx -index b3107dc..8414098 100644 ---- a/apps/platform/src/components/ui/combobox.tsx -+++ b/apps/platform/src/components/ui/combobox.tsx -@@ -5,27 +5,6 @@ import { useEffect, useState } from 'react' - import { useRouter } from 'next/navigation' - import { toast } from 'sonner' - import { AddSVG } from '@public/svg/shared' --import { cn } from '@/lib/utils' --import { -- Command, -- CommandEmpty, -- CommandInput, -- CommandItem, -- CommandList --} from '@/components/ui/command' --import { -- Popover, -- PopoverContent, -- PopoverTrigger --} from '@/components/ui/popover' --import { apiClient } from '@/lib/api-client' --// import type { Workspace } from '@/types' --import { zWorkspace } from '@/types' --import { -- getCurrentWorkspace, -- setCurrentWorkspace, -- setWorkspace --} from '@/lib/workspace-storage' - import type { Workspace } from '@keyshade/schema' - import { Input } from './input' - import { Label } from './label' -@@ -38,39 +17,43 @@ import { - DialogTrigger - } from './dialog' - import { Button } from './button' --import { WorkspaceSchema } from '@keyshade/schema/schemas' -- --interface WorkspaceResponse { -- items: Workspace[] -- metadata: { -- page: number -- perPage: number -- pageCount: number -- totalCount: number -- links: { -- self: string -- first: string -- previous: string | null -- next: string | null -- last: string -- } -- } --} -+import { -+ getCurrentWorkspace, -+ setCurrentWorkspace, -+ setWorkspace -+} from '@/lib/workspace-storage' -+import { cn } from '@/lib/utils' -+import { -+ Popover, -+ PopoverContent, -+ PopoverTrigger -+} from '@/components/ui/popover' -+import { -+ Command, -+ CommandEmpty, -+ CommandInput, -+ CommandItem, -+ CommandList -+} from '@/components/ui/command' -+import ControllerInstance from '@/lib/controller-instance' -  - async function getAllWorkspace(): Promise { - try { -- const workspaceData: WorkspaceResponse = -- await apiClient.get('/workspace') -+ const { data, success, error } = -+ await ControllerInstance.getInstance().workspaceController.getWorkspacesOfUser( -+ {}, -+ {} -+ ) -  -- // TODO: We are getting error here from the success flag, need to see this again -- // const { success, data } = WorkspaceSchema.array().safeParse(workspaceData.items) -- // if (!success) { -- // throw new Error('Invalid data') -- // } -+ if (error) { -+ // eslint-disable-next-line no-console -- we need to log the error -+ console.error(error) -+ return undefined -+ } -  -- return workspaceData.items -- // return data -- // return workspaceData; -+ if (success && data) { -+ return data.items -+ } - } catch (error) { - // eslint-disable-next-line no-console -- we need to log the error - console.error(error) -@@ -92,9 +75,13 @@ export function Combobox(): React.JSX.Element { - } - setIsNameEmpty(false) - try { -- const response = await apiClient.post('/workspace', { -- name -- }) -+ const response = -+ await ControllerInstance.getInstance().workspaceController.createWorkspace( -+ { -+ name -+ }, -+ {} -+ ) - setCurrentWorkspace(response) - setOpen(false) - } catch (error) { -diff --git a/apps/platform/src/lib/controller-instance.ts b/apps/platform/src/lib/controller-instance.ts -index fe432b7..a766038 100644 ---- a/apps/platform/src/lib/controller-instance.ts -+++ b/apps/platform/src/lib/controller-instance.ts -@@ -1,30 +1,90 @@ --import { AuthController } from '@keyshade/api-client' -+import { -+ AuthController, -+ EnvironmentController, -+ ProjectController, -+ SecretController, -+ UserController, -+ VariableController, -+ WorkspaceController, -+ WorkspaceMembershipController, -+ WorkspaceRoleController -+} from '@keyshade/api-client' -  - export default class ControllerInstance { - private static instance: ControllerInstance | null -  -- private _authController: AuthController | null = null -+ private _authController: AuthController -+ private _userController: UserController -+ private _workspaceController: WorkspaceController -+ private _workspaceMembershipController: WorkspaceMembershipController -+ private _workspaceRoleController: WorkspaceRoleController -+ private _projectController: ProjectController -+ private _environmentController: EnvironmentController -+ private _secretController: SecretController -+ private _variableController: VariableController -  - get authController(): AuthController { -- if (!this._authController) { -- throw new Error('ControllerInstance not initialized') -- } - return this._authController - } -  -- static initialize(baseUrl: string): void { -- if (!ControllerInstance.instance) { -- const instance = new ControllerInstance() -+ get workspaceController(): WorkspaceController { -+ return this._workspaceController -+ } -+ -+ get workspaceMembershipController(): WorkspaceMembershipController { -+ return this._workspaceMembershipController -+ } -  -- instance._authController = new AuthController(baseUrl) -+ get workspaceRoleController(): WorkspaceRoleController { -+ return this._workspaceRoleController -+ } -  -- ControllerInstance.instance = instance -- } -+ get projectController(): ProjectController { -+ return this._projectController -+ } -+ -+ get environmentController(): EnvironmentController { -+ return this._environmentController -+ } -+ -+ get secretController(): SecretController { -+ return this._secretController -+ } -+ -+ get variableController(): VariableController { -+ return this._variableController -+ } -+ -+ get userController(): UserController { -+ return this._userController - } -  - static getInstance(): ControllerInstance { - if (!ControllerInstance.instance) { -- throw new Error('ControllerInstance not initialized') -+ ControllerInstance.instance = new ControllerInstance() -+ ControllerInstance.instance._authController = new AuthController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._userController = new UserController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._workspaceController = -+ new WorkspaceController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._workspaceMembershipController = -+ new WorkspaceMembershipController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._workspaceRoleController = -+ new WorkspaceRoleController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._projectController = new ProjectController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._environmentController = -+ new EnvironmentController(process.env.NEXT_PUBLIC_BACKEND_URL) -+ ControllerInstance.instance._secretController = new SecretController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) -+ ControllerInstance.instance._variableController = new VariableController( -+ process.env.NEXT_PUBLIC_BACKEND_URL -+ ) - } - return ControllerInstance.instance - } -diff --git a/packages/api-client/src/index.ts b/packages/api-client/src/index.ts -index 79ab5f6..edd344f 100644 ---- a/packages/api-client/src/index.ts -+++ b/packages/api-client/src/index.ts -@@ -8,6 +8,7 @@ import WorkspaceController from '@api-client/controllers/workspace' - import WorkspaceRoleController from '@api-client/controllers/workspace-role' - import WorkspaceMembershipController from '@api-client/controllers/workspace-membership' - import AuthController from '@api-client/controllers/auth' -+import UserController from '@api-client/controllers/user' - export { - EnvironmentController, - SecretController, -@@ -18,5 +19,6 @@ export { - WorkspaceController, - WorkspaceRoleController, - WorkspaceMembershipController, -- AuthController -+ AuthController, -+ UserController - } -diff --git a/packages/schema/src/secret/index.ts b/packages/schema/src/secret/index.ts -index ff5b499..4277679 100644 ---- a/packages/schema/src/secret/index.ts -+++ b/packages/schema/src/secret/index.ts -@@ -100,15 +100,17 @@ export const GetAllSecretsOfProjectResponseSchema = PageResponseSchema( - name: z.string() - }) - }), -- values: z.object({ -- environment: z.object({ -- id: z.string(), -- name: z.string(), -- slug: z.string() -- }), -- value: z.string(), -- version: z.number() -- }) -+ values: z.array( -+ z.object({ -+ environment: z.object({ -+ id: z.string(), -+ name: z.string(), -+ slug: z.string() -+ }), -+ value: z.string(), -+ version: z.number() -+ }) -+ ) - }) - ) -  From 4c4e96e2ca31307ea3a79f58b5d81a1fc74c072a Mon Sep 17 00:00:00 2001 From: poswalsameer Date: Fri, 20 Dec 2024 23:14:29 +0530 Subject: [PATCH 04/12] refactored the code for adding new variables to a project --- .../app/(main)/project/[project]/layout.tsx | 295 +++++++++++++++--- .../dashboard/projectCard/index.tsx | 3 +- 2 files changed, 249 insertions(+), 49 deletions(-) diff --git a/apps/platform/src/app/(main)/project/[project]/layout.tsx b/apps/platform/src/app/(main)/project/[project]/layout.tsx index 9edfb0bb..bdd48eef 100644 --- a/apps/platform/src/app/(main)/project/[project]/layout.tsx +++ b/apps/platform/src/app/(main)/project/[project]/layout.tsx @@ -2,7 +2,13 @@ import { useEffect, useState } from 'react' import { useSearchParams } from 'next/navigation' import { AddSVG } from '@public/svg/shared' -import type { Project } from '@keyshade/schema' +import type { + ClientResponse, + CreateVariableRequest, + Environment, + GetAllEnvironmentsOfProjectResponse, + Project +} from '@keyshade/schema' import { Button } from '@/components/ui/button' import { Dialog, @@ -15,6 +21,13 @@ import { import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import ControllerInstance from '@/lib/controller-instance' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/components/ui/select' interface DetailedProjectPageProps { params: { project: string } @@ -31,12 +44,49 @@ function DetailedProjectPage({ const [key, setKey] = useState('') // eslint-disable-next-line @typescript-eslint/no-unused-vars -- will be used later const [value, setValue] = useState('') - const [currentProject, setCurrentProject] = useState() + const [isOpen, setIsOpen] = useState(false) + const [newVariableData, setNewVariableData] = useState({ + variableName: '', + note: '', + environmentName: '', + environmentValue: '' + }) + const [availableEnvironments, setAvailableEnvironments] = useState([]) const searchParams = useSearchParams() const tab = searchParams.get('tab') ?? 'rollup-details' + const addVariable = async (e: any) => { + e.preventDefault() + + const request: CreateVariableRequest = { + name: newVariableData.variableName, + projectSlug: currentProject?.slug as string, + entries: newVariableData.environmentValue + ? [ + { + value: newVariableData.environmentValue, + environmentSlug: newVariableData.environmentName + } + ] + : undefined, + note: newVariableData.note + } + + const { success, error, data } = await ControllerInstance.getInstance().variableController.createVariable( + request, + {} + ) + + if(error){ + // eslint-disable-next-line no-console -- we need to log the error + console.error(error) + } + + setIsOpen(false) + } + useEffect(() => { async function getProjectBySlug() { const { success, error, data } = @@ -46,6 +96,7 @@ function DetailedProjectPage({ ) if (success && data) { + //@ts-ignore setCurrentProject(data) } else { // eslint-disable-next-line no-console -- we need to log the error @@ -56,60 +107,208 @@ function DetailedProjectPage({ getProjectBySlug() }, [params.project]) + useEffect(() => { + const getAllEnvironments = async () => { + const { success, error, data }: ClientResponse = await ControllerInstance.getInstance().environmentController.getAllEnvironmentsOfProject( + { projectSlug: currentProject!.slug }, + {} + ) + + if (success && data) { + setAvailableEnvironments(data.items) + } else { + // eslint-disable-next-line no-console -- we need to log the error + console.error(error) + } + } + + getAllEnvironments() + }, [currentProject]) + return (
{currentProject?.name}
- - - - - - - Add a new secret - - Add a new secret to the project. This secret will be encrypted - and stored securely. - - -
-
-
- - { - setKey(e.target.value) - }} - placeholder="Enter the name of the secret" - /> + {tab === 'secret' && ( + + + + + + + Add a new secret + + Add a new secret to the project. This secret will be encrypted + and stored securely. + + +
+
+
+ + { + setKey(e.target.value) + }} + placeholder="Enter the name of the secret" + /> +
+
+ + { + setValue(e.target.value) + }} + placeholder="Enter the value of the secret" + /> +
-
- - { - setValue(e.target.value) - }} - placeholder="Enter the value of the secret" - /> +
+
-
- + +
+ )} + {tab === 'variable' && ( + + + + + + + +
+

+ Add a new variable +

+

+ Add a new variable to the project +

+
+
+
+ +
+
+
+ + + setNewVariableData({ + ...newVariableData, + variableName: e.target.value + }) + } + className="h-[2.75rem] w-[20rem] border-0 bg-[#2a2a2a] text-gray-300 placeholder:text-gray-500" + /> +
+ +
+ + + setNewVariableData({ + ...newVariableData, + note: e.target.value + }) + } + className="h-[2.75rem] w-[20rem] border-0 bg-[#2a2a2a] text-gray-300 placeholder:text-gray-500" + /> +
+ +
+
+ + +
+ +
+ + + setNewVariableData({ + ...newVariableData, + environmentValue: e.target.value + }) + } + className="h-[2.75rem] w-[13.5rem] border-0 bg-[#2a2a2a] text-gray-300 placeholder:text-gray-500" + /> +
+
+ +
+ +
+
-
- -
+ + + )}
{tab === 'secret' && secret} diff --git a/apps/platform/src/components/dashboard/projectCard/index.tsx b/apps/platform/src/components/dashboard/projectCard/index.tsx index 4cd0ad52..1818c51f 100644 --- a/apps/platform/src/components/dashboard/projectCard/index.tsx +++ b/apps/platform/src/components/dashboard/projectCard/index.tsx @@ -25,6 +25,7 @@ function ProjectCard({ }: ProjectCardProps): JSX.Element { const { id, + slug, name, description, environmentCount, @@ -69,7 +70,7 @@ function ProjectCard({
From 5a01926d890aba8811f400426697df44f6bb346b Mon Sep 17 00:00:00 2001 From: kriptonian1 Date: Sat, 21 Dec 2024 16:58:19 +0530 Subject: [PATCH 05/12] fix: conditionally render project creation button based on project state --- apps/platform/src/app/(main)/page.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/platform/src/app/(main)/page.tsx b/apps/platform/src/app/(main)/page.tsx index 9a9cb2ac..62c9c92c 100644 --- a/apps/platform/src/app/(main)/page.tsx +++ b/apps/platform/src/app/(main)/page.tsx @@ -144,10 +144,12 @@ export default function Index(): JSX.Element { - + {isProjectEmpty ? null : ( + + )}
@@ -334,7 +336,9 @@ export default function Index(): JSX.Element {
Create a file and start setting up your environment and secret keys
- +
)} From 64c0d84b59086e079c1f60c62baaf1db5be6acbf Mon Sep 17 00:00:00 2001 From: kriptonian1 Date: Sat, 21 Dec 2024 17:49:03 +0530 Subject: [PATCH 06/12] fix: cast response as ClientResponse type for better type safety --- packages/api-client/src/core/response-parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api-client/src/core/response-parser.ts b/packages/api-client/src/core/response-parser.ts index 0d616d7d..866beb33 100644 --- a/packages/api-client/src/core/response-parser.ts +++ b/packages/api-client/src/core/response-parser.ts @@ -17,7 +17,7 @@ export async function parseResponse( success: false, data: null, error - } as ClientResponse + } as unknown as ClientResponse } let data: any = null @@ -30,5 +30,5 @@ export async function parseResponse( success: true, data, error: null - } as ClientResponse + } as unknown as ClientResponse } From e79093414bc3496dc2b06a2b33340ee9a8b96d4d Mon Sep 17 00:00:00 2001 From: kriptonian1 Date: Sat, 21 Dec 2024 18:21:12 +0530 Subject: [PATCH 07/12] feat: add reusable Textarea component with customizable styles --- apps/platform/src/components/ui/textarea.tsx | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 apps/platform/src/components/ui/textarea.tsx diff --git a/apps/platform/src/components/ui/textarea.tsx b/apps/platform/src/components/ui/textarea.tsx new file mode 100644 index 00000000..2a10e86f --- /dev/null +++ b/apps/platform/src/components/ui/textarea.tsx @@ -0,0 +1,22 @@ +import * as React from 'react' + +import { cn } from '@/lib/utils' + +const Textarea = React.forwardRef< + HTMLTextAreaElement, + React.ComponentProps<'textarea'> +>(({ className, ...props }, ref) => { + return ( +