Rename, use Error subclasses instead of throwing strings

Jens Pelzetter 2020-08-14 20:00:31 +02:00
parent 2567bd1ee2
commit 83de873130
2 changed files with 459 additions and 321 deletions

View File

@ -0,0 +1,459 @@
import {
ApiClientError,
ApiError,
ApiResponse,
LibreCcmApiClient,
} from "@libreccm/ccm-apiclient-commons";
import {
ThemeInfo,
ThemeFileInfo,
buildThemeFileInfoFromRecord,
buildThemeInfoFromRecord,
} from "../entities/themes";
export class ThemesApiClient {
#apiClient: LibreCcmApiClient;
readonly #THEMES_API_PREFIX = "/api/themes";
constructor(apiClient: LibreCcmApiClient) {
this.#apiClient = apiClient;
}
async getThemeProviders(): Promise<string[]> {
const url = `${this.#THEMES_API_PREFIX}/providers`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
const result: unknown = await response.json();
return result as string[];
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to get theme providers`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get theme providers: ${err}`
);
}
}
}
async getAvailableThemes(): Promise<ThemeInfo[]> {
const url = `${this.#THEMES_API_PREFIX}/themes`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
const list: Record<
string,
unknown
>[] = (await response.json()) as Record<string, unknown>[];
return list.map((record) => buildThemeInfoFromRecord(record));
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to get avaiable themes`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get avaiable themes: ${err}`
);
}
}
}
async getTheme(themeName: string): Promise<ThemeInfo> {
const url = `${this.#THEMES_API_PREFIX}/themes/${themeName}`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
const record: Record<
string,
unknown
> = (await response.json()) as Record<string, unknown>;
return buildThemeInfoFromRecord(record);
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to get theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get theme ${themeName}: ${err}`
);
}
}
}
async createTheme(
themeName: string,
providerName: string
): Promise<ThemeInfo> {
const url = `${this.#THEMES_API_PREFIX}/themes/${themeName}`;
try {
const response: ApiResponse = await this.#apiClient.put(url, {
provider: providerName,
});
if (response.ok) {
const record: Record<
string,
unknown
> = (await response.json()) as Record<string, unknown>;
return buildThemeInfoFromRecord(record);
} else {
throw new ApiError(
response.status,
response.statusText,
"put",
`Failed to create theme ${themeName} using provider ${providerName}`,
url
);
}
} catch (err) {
if (err instanceof ApiClientError) {
throw err;
} else {
throw new ApiClientError(
`Failed to create theme ${themeName} using provider ${providerName}: ${err}`
);
}
}
}
async deleteTheme(themeName: string): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/themes/${themeName}`;
try {
const response: ApiResponse = await this.#apiClient.delete(url);
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"delete",
`Failed to delete theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to delete theme ${themeName}: ${err}`
);
}
}
}
async publishTheme(themeName: string): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/themes/${themeName}/live`;
try {
const response: ApiResponse = await this.#apiClient.post(url);
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"post",
`Failed to publish theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to publish theme ${themeName}: ${err}`
);
}
}
}
async unpublishTheme(themeName: string): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/themes/${themeName}/live`;
try {
const response: ApiResponse = await this.#apiClient.delete(url);
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"delete",
`Failed to unpublish theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to unpublish theme ${themeName}: ${err}`
);
}
}
}
async getThemeFileInfo(
themeName: string,
path = ""
): Promise<ThemeFileInfo> {
const url = `${
this.#THEMES_API_PREFIX
}/${themeName}/files/${path}/@info`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
const result: Record<
string,
unknown
> = (await response.json()) as Record<string, unknown>;
return buildThemeFileInfoFromRecord(result);
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to get theme file info for file ${path} of theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get theme file info for file ${path} of theme ${themeName}: ${err}`
);
}
}
}
async listThemesFiles(
themeName: string,
path = ""
): Promise<ThemeFileInfo[]> {
const isDirectory = await this.getThemeFileInfo(themeName, path);
if (!isDirectory) {
throw new ApiClientError(
`Failed to list files in directory ${path} of theme ${themeName}: Is not a directory.`
);
}
const url = `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
return (await response.json()) as ThemeFileInfo[];
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to list files in directory ${path} of theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to list files in directory ${path} of theme ${themeName}: ${err}`
);
}
}
}
async getThemeFile(themeName: string, path = ""): Promise<ArrayBuffer> {
const isDirectory = await this.getThemeFileInfo(themeName, path);
if (!isDirectory) {
throw new ApiClientError(
`Failed to get file ${path} from theme ${themeName}: Is a directory.`
);
}
const url = `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
return response.arrayBuffer();
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to get file ${path} of theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get file ${path} of theme ${themeName}: ${err}`
);
}
}
}
async createOrUpdateThemeFile(
themeName: string,
path: string,
data: string | Record<string, unknown> | ArrayBuffer
): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`;
try {
const response: ApiResponse = await this.#apiClient.put(url, data);
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"put",
`Failed to creat update theme file ${path} in theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to create or update file ${path} in theme ${themeName}: ${err}`
);
}
}
}
async deleteThemeFile(
themeName: string,
path: string,
recursive: boolean
): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`;
try {
const response: ApiResponse = await this.#apiClient.delete(url, {
recursive: recursive.toString(),
});
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"delete",
`Failed to delete file ${path} in theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to delete file ${path} in theme ${themeName}: ${err}`
);
}
}
}
async downloadTheme(themeName: string): Promise<ArrayBuffer> {
const url = `${this.#THEMES_API_PREFIX}/${themeName}/@download`;
try {
const response: ApiResponse = await this.#apiClient.get(url);
if (response.ok) {
return response.arrayBuffer();
} else {
throw new ApiError(
response.status,
response.statusText,
"get",
`Failed to download theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to download theme ${themeName}: ${err}`
);
}
}
}
async updateTheme(
themeName: string,
updateTheme: ArrayBuffer
): Promise<void> {
const url = `${this.#THEMES_API_PREFIX}/${themeName}/@update`;
try {
const response: ApiResponse = await this.#apiClient.post(
url,
updateTheme
);
if (response.ok) {
return;
} else {
throw new ApiError(
response.status,
response.statusText,
"post",
`Failed to update theme ${themeName}`,
url
);
}
} catch (err) {
if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to update theme ${themeName}: ${err}`
);
}
}
}
}

View File

@ -1,321 +0,0 @@
import {
ApiResponse,
LibreCcmApiClient,
ListView,
} from "@libreccm/ccm-apiclient-commons";
import {
ThemeInfo,
ThemeManifest,
ThemeFileInfo,
buildThemeFileInfoFromRecord,
buildThemeInfoFromRecord,
} from "../entities/themes";
export class ThemesApiClient {
#apiClient: LibreCcmApiClient;
readonly #THEMES_API_PREFIX = "/api/themes";
constructor(apiClient: LibreCcmApiClient) {
this.#apiClient = apiClient;
}
async getThemeProviders(): Promise<string[]> {
try {
const response: ApiResponse = await this.#apiClient.get(
`${this.#THEMES_API_PREFIX}/providers`
);
if (response.ok) {
const result: unknown = await response.json();
return result as string[];
} else {
throw `Failed to get theme providers:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to get theme providers: ${err}`;
}
}
async getAvailableThemes(): Promise<ThemeInfo[]> {
try {
const response: ApiResponse = await this.#apiClient.get(
`${this.#THEMES_API_PREFIX}/themes`
);
if (response.ok) {
const list: Record<
string,
unknown
>[] = (await response.json()) as Record<string, unknown>[];
return list.map((record) => buildThemeInfoFromRecord(record));
} else {
throw `Failed to get avaiable themes:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to get avaiable themes: ${err}`;
}
}
async getTheme(themeName: string): Promise<ThemeInfo> {
try {
const response: ApiResponse = await this.#apiClient.get(
`${this.#THEMES_API_PREFIX}/themes/${themeName}`
);
if (response.ok) {
const record: Record<
string,
unknown
> = (await response.json()) as Record<string, unknown>;
return buildThemeInfoFromRecord(record);
} else {
throw `Failed to get theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to get theme ${themeName}: ${err}`;
}
}
async createTheme(
themeName: string,
providerName: string
): Promise<ThemeInfo> {
try {
const response: ApiResponse = await this.#apiClient.put(
`${this.#THEMES_API_PREFIX}/themes/${themeName}`,
{
provider: providerName,
}
);
if (response.ok) {
const record: Record<
string,
unknown
> = (await response.json()) as Record<string, unknown>;
return buildThemeInfoFromRecord(record);
} else {
throw `Failed to create theme ${themeName}
using provider ${providerName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to create theme ${themeName}
using provider ${providerName}: ${err}`;
}
}
async deleteTheme(themeName: string): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.delete(
`${this.#THEMES_API_PREFIX}/themes/${themeName}`
);
if (response.ok) {
return;
} else {
throw `Failed to delete theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to delete theme ${themeName}: ${err}`;
}
}
async publishTheme(themeName: string): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.post(
`${this.#THEMES_API_PREFIX}/themes/${themeName}/live`
);
if (response.ok) {
return;
} else {
throw `Failed to publish theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to publish theme ${themeName}: ${err}`;
}
}
async unpublishTheme(themeName: string): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.delete(
`${this.#THEMES_API_PREFIX}/themes/${themeName}/live`
);
if (response.ok) {
return;
} else {
throw `Failed to unpublish theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to unpublish theme ${themeName}: ${err}`;
}
}
async getThemeFileInfo(
themeName: string,
path = ""
): Promise<ThemeFileInfo> {
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<string, unknown>;
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<ThemeFileInfo[]> {
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<ArrayBuffer> {
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: string | Record<string, unknown> | ArrayBuffer
): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.put(
`${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`,
data
);
if (response.ok) {
return;
}
} catch (err) {
throw `Failed to create or update file ${path} in theme ${themeName}: ${err}`;
}
}
async deleteThemeFile(
themeName: string,
path: string,
recursive: boolean
): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.delete(
`${this.#THEMES_API_PREFIX}/${themeName}/files/${path}`,
{
recursive: recursive.toString(),
}
);
if (response.ok) {
return;
} else {
throw `Failed to delete file ${path} in theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to delete file ${path} in theme ${themeName}: ${err}`;
}
}
async downloadTheme(themeName: string): Promise<ArrayBuffer> {
try {
const response: ApiResponse = await this.#apiClient.get(
`${this.#THEMES_API_PREFIX}/${themeName}/@download`
);
if (response.ok) {
return response.arrayBuffer();
} else {
throw `Failed to download theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to download theme ${themeName}: ${err}`;
}
}
async updateTheme(
themeName: string,
updateTheme: ArrayBuffer
): Promise<void> {
try {
const response: ApiResponse = await this.#apiClient.post(
`${this.#THEMES_API_PREFIX}/${themeName}/@update`,
updateTheme
);
if (response.ok) {
return;
} else {
throw `Failed to update theme ${themeName}:
${response.status} ${response.statusText}`;
}
} catch (err) {
throw `Failed to update theme ${themeName}: ${err}`;
}
}
}