Current status of ccm-apiclient-commons. Trying to figure best way for zero dependencies and supporting browsers and node environments
parent
01444aa09e
commit
cdde8ce67a
|
|
@ -61,6 +61,12 @@
|
||||||
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
|
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "12.12.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.50.tgz",
|
||||||
|
"integrity": "sha512-5ImO01Fb8YsEOYpV+aeyGYztcYcjGsBvN4D7G5r1ef2cuQOpymjWNQi5V0rKHE6PC2ru3HkoUr/Br2/8GUA84w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^12.12.50",
|
||||||
"@typescript-eslint/eslint-plugin": "^3.6.0",
|
"@typescript-eslint/eslint-plugin": "^3.6.0",
|
||||||
"@typescript-eslint/parser": "^3.6.0",
|
"@typescript-eslint/parser": "^3.6.0",
|
||||||
"eslint": "^7.4.0",
|
"eslint": "^7.4.0",
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,155 @@
|
||||||
|
import http from "http";
|
||||||
|
import { AnyARecord } from "dns";
|
||||||
|
|
||||||
export * from "./entities";
|
export * from "./entities";
|
||||||
export * from "./RequestInitProvider";
|
export * from "./RequestInitProvider";
|
||||||
|
|
||||||
|
export interface LibreCcmApiClient {
|
||||||
|
get(
|
||||||
|
endpoint: string,
|
||||||
|
searchParams: Record<string, string>
|
||||||
|
): Promise<ApiResponse>;
|
||||||
|
post(
|
||||||
|
endpoint: string,
|
||||||
|
searchParams: Record<string, string>,
|
||||||
|
body: unknown
|
||||||
|
): Promise<Response>;
|
||||||
|
put(endpoint: string, body: Record<string, unknown>): Promise<Response>;
|
||||||
|
delete(endpoint: string): Promise<Response>;
|
||||||
|
head(endpoint: string): Promise<Response>;
|
||||||
|
options(endpoint: string): Promise<Response>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiResponse {
|
||||||
|
status: number;
|
||||||
|
statusText: string;
|
||||||
|
json(): Promise<Record<string, unknown>>;
|
||||||
|
blob(): Promise<Blob>;
|
||||||
|
text(): Promise<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiError {
|
||||||
|
status: number;
|
||||||
|
statusText: string;
|
||||||
|
method: "get" | "post" | "put" | "delete" | "head" | "option";
|
||||||
|
message: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildUrl(base: string, endpoint: string, searchParams?: Record<string, string>): string {
|
||||||
|
const url = new URL(base);
|
||||||
|
url.pathname = endpoint;
|
||||||
|
if (searchParams) {
|
||||||
|
const urlSearchParams: URLSearchParams = new URLSearchParams();
|
||||||
|
for (const key in searchParams) {
|
||||||
|
urlSearchParams.append(key, searchParams[key]);
|
||||||
|
}
|
||||||
|
url.search = urlSearchParams.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildEmbeddedApiClient(): LibreCcmApiClient {
|
||||||
|
if (!document) {
|
||||||
|
throw "document global variable is not available. Please use the buildRemoteApiClient.";
|
||||||
|
}
|
||||||
|
const baseUrl = new URL(document.documentURI);
|
||||||
|
baseUrl.hash = "";
|
||||||
|
baseUrl.password = "";
|
||||||
|
baseUrl.pathname = "";
|
||||||
|
baseUrl.search = "";
|
||||||
|
baseUrl.username = "";
|
||||||
|
|
||||||
|
return new EmbeddedApiClient(baseUrl.href, {
|
||||||
|
credentials: "include",
|
||||||
|
mode: "same-origin",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class FetchResponse implements ApiResponse {
|
||||||
|
readonly status: number;
|
||||||
|
readonly statusText: string;
|
||||||
|
#response: Response;
|
||||||
|
|
||||||
|
constructor(response: Response) {
|
||||||
|
this.status = response.status;
|
||||||
|
this.statusText = response.statusText;
|
||||||
|
this.#response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
json(): Promise<Record<string, unknown>> {
|
||||||
|
return this.#response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
blob(): Promise<Blob> {
|
||||||
|
return this.#response.blob();
|
||||||
|
}
|
||||||
|
|
||||||
|
text(): Promise<string> {
|
||||||
|
return this.#response.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmbeddedApiClient implements LibreCcmApiClient {
|
||||||
|
#baseUrl: string;
|
||||||
|
#fetchOptions: RequestInit;
|
||||||
|
|
||||||
|
constructor(baseUrl: string, fetchOptions: RequestInit) {
|
||||||
|
this.#baseUrl = baseUrl;
|
||||||
|
this.#fetchOptions = fetchOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(
|
||||||
|
endpoint: string,
|
||||||
|
searchParams?: Record<string, string>
|
||||||
|
): Promise<ApiResponse> {
|
||||||
|
const fetchOptions: RequestInit = {};
|
||||||
|
Object.assign(fetchOptions, this.#fetchOptions);
|
||||||
|
fetchOptions.method = "get";
|
||||||
|
|
||||||
|
const url = buildUrl(this.#baseUrl, endpoint, searchParams);
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, this.#fetchOptions);
|
||||||
|
if (response.ok) {
|
||||||
|
return new FetchResponse(response);
|
||||||
|
} else {
|
||||||
|
throw {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
method: "get",
|
||||||
|
message: "Received an error from the API endpoint. ",
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
throw `Failed to execute GET on ${url}: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async post(
|
||||||
|
endpoint: string,
|
||||||
|
searchParams: Record<string, string>,
|
||||||
|
body: unknown
|
||||||
|
): Promise<Response> {
|
||||||
|
throw "Not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
put(endpoint: string, body: Record<string, unknown>): Promise<Response> {
|
||||||
|
throw "Not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(endpoint: string): Promise<Response> {
|
||||||
|
throw "Not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
head(endpoint: string): Promise<Response> {
|
||||||
|
throw "Not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
options(endpoint: string): Promise<Response> {
|
||||||
|
throw "Not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue