parent
f1adb7f0ae
commit
901375c4cc
|
|
@ -1,6 +1,4 @@
|
||||||
import * as http from "http";
|
import * as http from "http";
|
||||||
import { rejects } from "assert";
|
|
||||||
import { timeStamp } from "console";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface of a client for the LibreCcm RESTful API.
|
* The interface of a client for the LibreCcm RESTful API.
|
||||||
|
|
@ -133,7 +131,7 @@ export interface ApiError {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper function for building an URL. Because it might be useful for implementing
|
* A helper function for building an URL. Because it might be useful for implementing
|
||||||
* client for specific APIs in the exported from this module.
|
* clients for specific APIs in the exported from this module.
|
||||||
*
|
*
|
||||||
* @param base The base URL pointing the an LibreCCM installation.
|
* @param base The base URL pointing the an LibreCCM installation.
|
||||||
* @param endpoint The endpoint to address.
|
* @param endpoint The endpoint to address.
|
||||||
|
|
@ -157,6 +155,14 @@ export function buildUrl(
|
||||||
return url.href;
|
return url.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFetchAvailable(): boolean {
|
||||||
|
if (!fetch) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the {@link ApiResponse} for the Fetch-API supported
|
* An implementation of the {@link ApiResponse} for the Fetch-API supported
|
||||||
* by browsers.
|
* by browsers.
|
||||||
|
|
@ -524,7 +530,7 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
|
||||||
|
|
||||||
post(
|
post(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: unknown,
|
body: ArrayBuffer,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -556,31 +562,165 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
|
||||||
|
|
||||||
request.on("error", (error) => reject(error));
|
request.on("error", (error) => reject(error));
|
||||||
|
|
||||||
|
request.write(body);
|
||||||
|
|
||||||
request.end();
|
request.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
put(
|
put(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: unknown,
|
body: ArrayBuffer,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
return new Promise((resolve, reject) => {
|
||||||
|
const url = buildUrl(this.#baseUrl, endpoint, searchParams);
|
||||||
|
const request: http.ClientRequest = http.request(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: this.#jwt,
|
||||||
|
},
|
||||||
|
method: "PUT",
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("response", (response) => {
|
||||||
|
const status: number = response.statusCode
|
||||||
|
? response.statusCode
|
||||||
|
: -1;
|
||||||
|
const statusText: string = response.statusMessage
|
||||||
|
? response.statusMessage
|
||||||
|
: "";
|
||||||
|
|
||||||
|
response.on("end", () => {
|
||||||
|
const apiResponse: ApiResponse = new NodeResponse(
|
||||||
|
status,
|
||||||
|
statusText,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
resolve(apiResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("error", (error) => reject(error));
|
||||||
|
|
||||||
|
request.write(body);
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(
|
delete(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
return new Promise((resolve, reject) => {
|
||||||
|
const url = buildUrl(this.#baseUrl, endpoint, searchParams);
|
||||||
|
const request: http.ClientRequest = http.request(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: this.#jwt,
|
||||||
|
},
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("response", (response) => {
|
||||||
|
const status: number = response.statusCode
|
||||||
|
? response.statusCode
|
||||||
|
: -1;
|
||||||
|
const statusText: string = response.statusMessage
|
||||||
|
? response.statusMessage
|
||||||
|
: "";
|
||||||
|
|
||||||
|
response.on("end", () => {
|
||||||
|
const apiResponse: ApiResponse = new NodeResponse(
|
||||||
|
status,
|
||||||
|
statusText,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
resolve(apiResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("error", (error) => reject(error));
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
head(endpoint: string): Promise<ApiResponse> {
|
head(endpoint: string): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
return new Promise((resolve, reject) => {
|
||||||
|
const url = buildUrl(this.#baseUrl, endpoint);
|
||||||
|
const request: http.ClientRequest = http.request(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: this.#jwt,
|
||||||
|
},
|
||||||
|
method: "HEAD",
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("response", (response) => {
|
||||||
|
const status: number = response.statusCode
|
||||||
|
? response.statusCode
|
||||||
|
: -1;
|
||||||
|
const statusText: string = response.statusMessage
|
||||||
|
? response.statusMessage
|
||||||
|
: "";
|
||||||
|
|
||||||
|
const data: Array<Buffer> = [];
|
||||||
|
|
||||||
|
response.on("data", (chunk: Buffer) => {
|
||||||
|
data.push(chunk);
|
||||||
|
});
|
||||||
|
response.on("end", () => {
|
||||||
|
const buffer: Buffer = Buffer.concat(data);
|
||||||
|
const apiResponse: ApiResponse = new NodeResponse(
|
||||||
|
status,
|
||||||
|
statusText,
|
||||||
|
buffer
|
||||||
|
);
|
||||||
|
resolve(apiResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
request.on("error", (error) => reject(error));
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
options(endpoint: string): Promise<ApiResponse> {
|
options(endpoint: string): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
return new Promise((resolve, reject) => {
|
||||||
|
const url = buildUrl(this.#baseUrl, endpoint);
|
||||||
|
const request: http.ClientRequest = http.request(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: this.#jwt,
|
||||||
|
},
|
||||||
|
method: "OPTIONS",
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on("response", (response) => {
|
||||||
|
const status: number = response.statusCode
|
||||||
|
? response.statusCode
|
||||||
|
: -1;
|
||||||
|
const statusText: string = response.statusMessage
|
||||||
|
? response.statusMessage
|
||||||
|
: "";
|
||||||
|
|
||||||
|
const data: Array<Buffer> = [];
|
||||||
|
|
||||||
|
response.on("data", (chunk: Buffer) => {
|
||||||
|
data.push(chunk);
|
||||||
|
});
|
||||||
|
response.on("end", () => {
|
||||||
|
const buffer: Buffer = Buffer.concat(data);
|
||||||
|
const apiResponse: ApiResponse = new NodeResponse(
|
||||||
|
status,
|
||||||
|
statusText,
|
||||||
|
buffer
|
||||||
|
);
|
||||||
|
resolve(apiResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
request.on("error", (error) => reject(error));
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,41 +730,73 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
|
||||||
* and used either the {@link ApiClientFetchImpl} or the {@link ApiClientNodeImpl}.
|
* and used either the {@link ApiClientFetchImpl} or the {@link ApiClientNodeImpl}.
|
||||||
*/
|
*/
|
||||||
export class IsomorphicClientImpl implements LibreCcmApiClient {
|
export class IsomorphicClientImpl implements LibreCcmApiClient {
|
||||||
|
readonly #fetchClient: LibreCcmApiClient;
|
||||||
|
readonly #nodeClient: LibreCcmApiClient;
|
||||||
|
|
||||||
|
constructor(fetchClient: LibreCcmApiClient, nodeClient: LibreCcmApiClient) {
|
||||||
|
this.#fetchClient = fetchClient;
|
||||||
|
this.#nodeClient = nodeClient;
|
||||||
|
}
|
||||||
|
|
||||||
get(
|
get(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.get(endpoint, searchParams);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.get(endpoint, searchParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
post(
|
post(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: unknown,
|
body: ArrayBuffer,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.post(endpoint, body, searchParams);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.post(endpoint, body, searchParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
put(
|
put(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: unknown,
|
body: ArrayBuffer,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.put(endpoint, body, searchParams);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.put(endpoint, body, searchParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(
|
delete(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
searchParams?: Record<string, string>
|
searchParams?: Record<string, string>
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.delete(endpoint, searchParams);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.delete(endpoint, searchParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
head(endpoint: string): Promise<ApiResponse> {
|
head(endpoint: string): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.head(endpoint);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.head(endpoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
options(endpoint: string): Promise<ApiResponse> {
|
options(endpoint: string): Promise<ApiResponse> {
|
||||||
throw "Not implemented yet.";
|
if (isFetchAvailable()) {
|
||||||
|
return this.#fetchClient.options(endpoint);
|
||||||
|
} else {
|
||||||
|
return this.#nodeClient.options(endpoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import {
|
||||||
buildUrl,
|
buildUrl,
|
||||||
ApiClientFetchImpl,
|
ApiClientFetchImpl,
|
||||||
ApiClientNodeImpl,
|
ApiClientNodeImpl,
|
||||||
|
isFetchAvailable,
|
||||||
IsomorphicClientImpl,
|
IsomorphicClientImpl,
|
||||||
} from "./ApiClient";
|
} from "./ApiClient";
|
||||||
|
|
||||||
|
|
@ -20,7 +21,7 @@ export { LibreCcmApiClient, ApiResponse, ApiError, buildUrl };
|
||||||
* use the credentials stored in the browser (cookies) to authenticate itself.
|
* use the credentials stored in the browser (cookies) to authenticate itself.
|
||||||
*/
|
*/
|
||||||
export function buildEmbeddedApiClient(): LibreCcmApiClient {
|
export function buildEmbeddedApiClient(): LibreCcmApiClient {
|
||||||
if (!fetch) {
|
if (!isFetchAvailable()) {
|
||||||
throw "Fetch API is not available. Please use buildIsomorpicApiClient.";
|
throw "Fetch API is not available. Please use buildIsomorpicApiClient.";
|
||||||
}
|
}
|
||||||
const baseUrl = new URL(document.documentURI);
|
const baseUrl = new URL(document.documentURI);
|
||||||
|
|
@ -46,7 +47,7 @@ export function buildRemoteApiClient(
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
jwt: string
|
jwt: string
|
||||||
): LibreCcmApiClient {
|
): LibreCcmApiClient {
|
||||||
if (!fetch) {
|
if (!isFetchAvailable()) {
|
||||||
throw "Fetch API is not available. Please use buildIsomorpicApiClient.";
|
throw "Fetch API is not available. Please use buildIsomorpicApiClient.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,5 +84,7 @@ export function buildIsomorpicApiClient(
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
jwt: string
|
jwt: string
|
||||||
): LibreCcmApiClient {
|
): LibreCcmApiClient {
|
||||||
return new IsomorphicClientImpl();
|
const fetchClient: LibreCcmApiClient = buildRemoteApiClient(baseUrl, jwt);
|
||||||
|
const nodeClient: LibreCcmApiClient = buildNodeApiClient(baseUrl, jwt);
|
||||||
|
return new IsomorphicClientImpl(fetchClient, nodeClient);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
||||||
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ=="
|
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ=="
|
||||||
},
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "12.12.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.50.tgz",
|
||||||
|
"integrity": "sha512-5ImO01Fb8YsEOYpV+aeyGYztcYcjGsBvN4D7G5r1ef2cuQOpymjWNQi5V0rKHE6PC2ru3HkoUr/Br2/8GUA84w=="
|
||||||
|
},
|
||||||
"@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",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue