@@ -970,6 +970,88 @@ export class PostHogAPIClient {
970970 }
971971 }
972972
973+ // Desktop file system shortcuts — the user-scoped "starred" items on the
974+ // desktop surface (e.g. starred channels). Unlike the file system rows above,
975+ // shortcuts are per-user, so they back cross-device starring without leaking
976+ // one user's stars to their teammates. Not in the generated OpenAPI client,
977+ // so we use the raw fetcher.
978+ async getDesktopFileSystemShortcuts ( ) : Promise < Schemas . FileSystemShortcut [ ] > {
979+ const SHORTCUTS_MAX_PAGES = 50 ;
980+ const SHORTCUTS_PAGE_SIZE = 200 ;
981+ const teamId = await this . getTeamId ( ) ;
982+ const all : Schemas . FileSystemShortcut [ ] = [ ] ;
983+ let urlPath : string = `/api/projects/${ teamId } /desktop_file_system_shortcut/?limit=${ SHORTCUTS_PAGE_SIZE } ` ;
984+ for ( let i = 0 ; i < SHORTCUTS_MAX_PAGES ; i ++ ) {
985+ const url = new URL ( `${ this . api . baseUrl } ${ urlPath } ` ) ;
986+ const response = await this . api . fetcher . fetch ( {
987+ method : "get" ,
988+ url,
989+ path : urlPath ,
990+ } ) ;
991+ if ( ! response . ok ) {
992+ throw new Error (
993+ `Failed to fetch desktop file system shortcuts: ${ response . statusText } ` ,
994+ ) ;
995+ }
996+ const page =
997+ ( await response . json ( ) ) as Schemas . PaginatedFileSystemShortcutList ;
998+ all . push ( ...page . results ) ;
999+ if ( ! page . next ) return all ;
1000+ const nextUrl = new URL ( page . next ) ;
1001+ urlPath = `${ nextUrl . pathname } ${ nextUrl . search } ` ;
1002+ }
1003+ log . warn (
1004+ `getDesktopFileSystemShortcuts hit MAX_PAGES (${ SHORTCUTS_MAX_PAGES } ); returning partial results` ,
1005+ { returned : all . length } ,
1006+ ) ;
1007+ return all ;
1008+ }
1009+
1010+ // Create a desktop shortcut for the current user. For a folder/channel the
1011+ // backend links by `ref` (the folder's full path), with `path` as the label.
1012+ async createDesktopFileSystemShortcut ( input : {
1013+ path : string ;
1014+ type : string ;
1015+ ref ?: string ;
1016+ href ?: string ;
1017+ } ) : Promise < Schemas . FileSystemShortcut > {
1018+ const teamId = await this . getTeamId ( ) ;
1019+ const urlPath = `/api/projects/${ teamId } /desktop_file_system_shortcut/` ;
1020+ const url = new URL ( `${ this . api . baseUrl } ${ urlPath } ` ) ;
1021+ const response = await this . api . fetcher . fetch ( {
1022+ method : "post" ,
1023+ url,
1024+ path : urlPath ,
1025+ overrides : {
1026+ body : JSON . stringify ( input ) ,
1027+ } ,
1028+ } ) ;
1029+ if ( ! response . ok ) {
1030+ throw new Error (
1031+ `Failed to create desktop file system shortcut: ${ response . statusText } ` ,
1032+ ) ;
1033+ }
1034+ return ( await response . json ( ) ) as Schemas . FileSystemShortcut ;
1035+ }
1036+
1037+ // Delete a desktop shortcut by id (used to unstar). A 404 means it's already
1038+ // gone, which is the desired end state, so we treat it as success.
1039+ async deleteDesktopFileSystemShortcut ( id : string ) : Promise < void > {
1040+ const teamId = await this . getTeamId ( ) ;
1041+ const urlPath = `/api/projects/${ teamId } /desktop_file_system_shortcut/${ encodeURIComponent ( id ) } /` ;
1042+ const url = new URL ( `${ this . api . baseUrl } ${ urlPath } ` ) ;
1043+ const response = await this . api . fetcher . fetch ( {
1044+ method : "delete" ,
1045+ url,
1046+ path : urlPath ,
1047+ } ) ;
1048+ if ( ! response . ok && response . status !== 404 ) {
1049+ throw new Error (
1050+ `Failed to delete desktop file system shortcut: ${ response . statusText } ` ,
1051+ ) ;
1052+ }
1053+ }
1054+
9731055 // Per-folder, versioned markdown instructions for a desktop folder. The
9741056 // endpoint is keyed on the FileSystem row id (must be `type === "folder"`).
9751057 // Returns the current latest version or null when none has been published.
0 commit comments