parent
2415f4942f
commit
34b682bab5
@ -0,0 +1,83 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue