You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.4 KiB

import type { StandardSchemaV1 } from '$libs/standard-schema';
import { HTTP_CONTENT_TYPE_JSON, HTTP_HEADER_CONTENT_TYPE, HTTP_METHOD_POST } from '$libs/http';
import {
PERMISSION_ERROR_MSG_REQUEST_FAILED_PREFIX,
PERMISSION_ERROR_MSG_RESPONSE_NOT_JSON_PREFIX,
PERMISSION_HTTP_CREDENTIALS_INCLUDE
} from './consts.ts';
import { PermRemoteRequestError } from './errors.ts';
import type { PermissionClientOptions } from './types.ts';
const PERMISSION_JSON_PASSTHROUGH_SCHEMA: StandardSchemaV1<unknown, unknown> = {
'~standard': {
version: 1,
vendor: 'active-perm',
validate(value) {
return { value };
}
}
};
function joinUrl(base: string, path: string): string {
return `${base.replace(/\/$/, '')}/${path.replace(/^\//, '')}`;
}
export async function postPermissionJson<T>(
options: PermissionClientOptions,
path: string,
body: unknown
): Promise<T> {
const url = joinUrl(options.endpoint, path);
if (options.http) {
const response = await options.http.post(url, {
body: body as Record<string, unknown>,
schema: PERMISSION_JSON_PASSTHROUGH_SCHEMA
});
if (response.ok) return response.value as T;
const status = 'status' in response ? response.status : undefined;
throw new PermRemoteRequestError(
`${PERMISSION_ERROR_MSG_REQUEST_FAILED_PREFIX}${status ?? url}`,
url,
status
);
}
const fetcher = options.fetcher ?? fetch.bind(globalThis);
const response = await fetcher(url, {
method: HTTP_METHOD_POST,
headers: { [HTTP_HEADER_CONTENT_TYPE]: HTTP_CONTENT_TYPE_JSON },
credentials: PERMISSION_HTTP_CREDENTIALS_INCLUDE,
body: JSON.stringify(body)
});
if (!response.ok) {
throw new PermRemoteRequestError(
`${PERMISSION_ERROR_MSG_REQUEST_FAILED_PREFIX}${response.status} ${response.statusText}`,
url,
response.status
);
}
return readPermissionJson<T>(response, url);
}
async function readPermissionJson<T>(response: Response, url: string): Promise<T> {
const contentType = response.headers.get(HTTP_HEADER_CONTENT_TYPE);
if (contentType && !contentType.toLowerCase().includes(HTTP_CONTENT_TYPE_JSON)) {
throw new PermRemoteRequestError(
`${PERMISSION_ERROR_MSG_RESPONSE_NOT_JSON_PREFIX}${url}`,
url,
response.status
);
}
try {
return (await response.json()) as T;
} catch (_error) {
throw new PermRemoteRequestError(
`${PERMISSION_ERROR_MSG_RESPONSE_NOT_JSON_PREFIX}${url}`,
url,
response.status
);
}
}

Powered by TurnKey Linux.