diff --git a/ccm-core-apiclient/src/main/typescript/clients/themes.ts b/ccm-core-apiclient/src/main/typescript/clients/themes.ts index b119ae5bb..2dbe4ea3d 100644 --- a/ccm-core-apiclient/src/main/typescript/clients/themes.ts +++ b/ccm-core-apiclient/src/main/typescript/clients/themes.ts @@ -8,6 +8,7 @@ import { ThemeInfo, ThemeManifest, ThemeFileInfo, + buildThemeFileInfoFromRecord, buildThemeInfoFromRecord, } from "../entities/themes"; @@ -159,19 +160,96 @@ export class ThemesApiClient { } } - // async getThemeFile( - // themeName: string, - // path: string | null = null - // ): Promise { - // try { - // const response: ApiResponse = - // } catch (err) { - // if (path) { - // throw `Failed to get file ${path} of theme ${themeName}: ${err}`; - // } else { - // throw `Failed to get root directory of - // theme ${themeName}: ${err}`; - // } - // } - // } + async getThemeFileInfo( + themeName: string, + path = "" + ): Promise { + try { + const response: ApiResponse = await this.#apiClient.get( + `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}/@info` + ); + + if (response.ok) { + const result: Record< + string, + unknown + > = (await response.json()) as Record; + + return buildThemeFileInfoFromRecord(result); + } else { + throw `Failed to get theme file info for file ${path} + of theme ${themeName}: + ${response.status} ${response.statusText}`; + } + } catch (err) { + throw `Failed to get theme file info for file ${path} + of theme ${themeName}: ${err}`; + } + } + + async listThemesFiles( + themeName: string, + path = "" + ): Promise { + try { + const isDirectory = await this.getThemeFileInfo(themeName, path); + if (!isDirectory) { + throw `Failed to list files in directory ${path} + of theme ${themeName}: Is not a directory.`; + } + + const response: ApiResponse = await this.#apiClient.get( + `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}` + ); + + if (response.ok) { + return (await response.json()) as ThemeFileInfo[]; + } else { + throw `Failed to list files in directory ${path} + of theme ${themeName}: + ${response.status} ${response.statusText}`; + } + } catch (err) { + throw `Failed to list files in directory ${path} + of theme ${themeName}: ${err}`; + } + } + + async getThemeFile(themeName: string, path = ""): Promise { + try { + const isDirectory = await this.getThemeFileInfo(themeName, path); + if (!isDirectory) { + throw `Failed to get file ${path} + from theme ${themeName}: Is a directory.`; + } + + const response: ApiResponse = await this.#apiClient.get( + `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}` + ); + + if (response.ok) { + return response.arrayBuffer(); + } else { + throw `Failed to get file ${path} of theme ${themeName}: + ${response.status} ${response.statusText}`; + } + } catch (err) { + throw `Failed to get file ${path} of theme ${themeName}: ${err}`; + } + } + + async createOrUpdateThemeFile( + themeName: string, + path: string, + data: unknown + ): Promise { + try { + const response: ApiResponse = await this.#apiClient.put( + `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`, + data + ); + } catch (err) { + throw `Failed to create or update file ${path} in theme ${themeName}: ${err}`; + } + } } diff --git a/ccm-core-apiclient/src/main/typescript/entities/themes.ts b/ccm-core-apiclient/src/main/typescript/entities/themes.ts index a60a14518..c2ec28e23 100644 --- a/ccm-core-apiclient/src/main/typescript/entities/themes.ts +++ b/ccm-core-apiclient/src/main/typescript/entities/themes.ts @@ -73,3 +73,23 @@ export function buildThemeManifestFromRecord( defaultTemplate: record.defaultTemplate as string, }; } + +export function buildThemeFileInfoFromRecord( + record: Record +): ThemeFileInfo { + assertProperties(record, [ + "name", + "directory", + "mimeType", + "size", + "writable", + ]); + + return { + name: record.name as string, + directory: record.directory as boolean, + mimeType: record.mimeType as string, + size: record.size as number, + writable: record.writeable as boolean + }; +}