@smapiot/piral-cloud-browser
Version:
Piral Cloud: Browser-usable API Client for the Piral Feed Service.
651 lines (647 loc) • 22.4 kB
JavaScript
// ../feed-client/src/fetch.ts
function fetchWithoutToken(client, url, init = {}) {
const headers = new client.Headers(init.headers);
if (init.body instanceof client.FormData) {
} else if (!headers.has("content-type")) {
headers.append("content-type", "application/json");
}
return client.fetch(url, {
...client.defaults,
...init,
headers
});
}
function fetchWithToken(client, url, init = {}) {
return client.getAuthorizationHeader().then((header) => {
if (header && typeof header === "string") {
return fetchWithoutToken(client, url, {
...client.defaults,
...init,
headers: {
...init.headers || {},
authorization: header
}
});
}
return fetchWithoutToken(client, url, init);
});
}
// ../feed-client/src/http.ts
function getJsonResponse(res) {
const json = res.json();
if (!res.ok) {
return json.then((err) => {
throw new Error(err?.message ?? res.statusText);
});
}
return json;
}
function toQueryValue(value) {
if (typeof value === "string") {
return value;
} else if (value instanceof Date) {
return value.toISOString();
} else {
return `${value}`;
}
}
function makeQueryString(query) {
return Object.keys(query).filter((n) => query[n] !== void 0).map((n) => `${n}=${toQueryValue(query[n])}`).join("&");
}
function getDefaultHost() {
if (typeof document !== "undefined") {
return document.location.origin;
}
return "";
}
function mac() {
return new AbortController();
}
function mri(ac) {
return { signal: ac.signal };
}
var FeedServiceApiClient = class {
constructor(http, host = getDefaultHost()) {
this.http = http;
this.host = host;
this._listeners = {};
}
on(name, handler) {
const handlers = this._listeners[name] || (this._listeners[name] = []);
handlers.push(handler);
}
off(name, handler) {
const handlers = this._listeners[name] || (this._listeners[name] = []);
const index = handlers.indexOf(handler);
index >= 0 && handlers.splice(index, 1);
}
once(name, handler) {
const wrappedHandler = (ev) => {
this.off(name, wrappedHandler);
handler(ev);
};
this.on(name, wrappedHandler);
}
emit(name, ev) {
const handlers = this._listeners[name];
handlers?.forEach((handler) => handler(ev));
}
getUrl(path) {
const host = this.host;
return `${host}/api/v1/${path}`;
}
getEvents() {
const url = this.getUrl("events");
return url.replace("http", "ws");
}
doAny(path, init) {
const url = this.getUrl(path);
return fetchWithToken(this.http, url, init).then((res) => {
if (res.status === 401) {
const delays = [];
this.emit("unauthorized", {
res,
retry(delay) {
delays.push(delay);
}
});
if (delays.length > 0) {
return Promise.all(delays).then(
() => {
return fetchWithToken(this.http, url, init);
},
() => {
return res;
}
);
}
} else if (res.status >= 500 && res.status < 600) {
throw new Error(`HTTP call failed with status ${res.status}: ${res.statusText}`);
}
return res;
}).then(getJsonResponse);
}
doGet(path, init = {}) {
return this.doAny(path, { ...init, method: "GET" });
}
doPost(path, content, init = {}) {
const { FormData: FormData2 } = this.http;
const body = content instanceof FormData2 ? content : JSON.stringify(content);
return this.doAny(path, { ...init, method: "POST", body });
}
doPut(path, content, init = {}) {
const { FormData: FormData2 } = this.http;
const body = content instanceof FormData2 ? content : JSON.stringify(content);
return this.doAny(path, { ...init, method: "PUT", body });
}
doDelete(path, init = {}) {
return this.doAny(path, { ...init, method: "DELETE" });
}
getPilets(ac = mac()) {
return this.doQueryCurrentPilets("cloud", ac);
}
doQueryFeeds(ac = mac()) {
return this.doGet(`feed`, mri(ac));
}
doQueryFeed(feed, ac = mac()) {
return this.doGet(`feed/${feed}`, mri(ac));
}
doQueryValidEnvSourceTags(feed, eid, offset, count, ac = mac()) {
const queryString = makeQueryString({
eid,
offset,
count
});
return this.doGet(`feed/${feed}/tags?${queryString}`, mri(ac));
}
doQueryEnvironments(feed, ac = mac()) {
return this.doGet(`feed/${feed}/environments`, mri(ac));
}
doQueryEnvironment(feed, eid, ac = mac()) {
return this.doGet(`feed/${feed}/environments/${eid}`, mri(ac));
}
doAddEnvironment(feed, content, ac = mac()) {
return this.doPost(`feed/${feed}/environments`, content, mri(ac));
}
doUpdateEnvironment(feed, eid, content, ac = mac()) {
return this.doPut(`feed/${feed}/environments/${eid}`, content, mri(ac));
}
doDeleteEnvironment(feed, eid, ac = mac()) {
return this.doDelete(`feed/${feed}/environments/${eid}`, mri(ac));
}
doQueryEnvironmentElevationReviews(feed, eid, ac = mac()) {
return this.doGet(`feed/${feed}/environments/${eid}/elevations`, mri(ac));
}
doQueryFeedElevationReviews(feed, ac = mac()) {
return this.doGet(`feed/${feed}/elevations`, mri(ac));
}
doQueryEnvironmentElevationReview(feed, eid, ac = mac()) {
return this.doGet(`feed/${feed}/environments/${eid}/elevations/${eid}`, mri(ac));
}
doAddElevationReview(feed, eid, content, ac = mac()) {
return this.doPost(`feed/${feed}/environments/${eid}/elevations`, content, mri(ac));
}
doUpdateElevationReview(feed, eid, id, content, ac = mac()) {
return this.doPut(`feed/${feed}/environments/${eid}/elevations/${id}`, content, mri(ac));
}
doQueryElevationReviewComments(feed, eid, ac = mac()) {
return this.doGet(`feed/${feed}/elevations/${eid}/comments`, mri(ac));
}
doAddElevationReviewComment(feed, eid, content, ac = mac()) {
return this.doPost(`feed/${feed}/elevations/${eid}/comments`, content, mri(ac));
}
doQueryPages(feed, tag = "latest", ac = mac()) {
return this.doGet(`feed/${feed}/page?tag=${tag}`, mri(ac));
}
doUpdatePageSettings(feed, content, ac = mac()) {
return this.doPut(`feed/${feed}/page`, content, mri(ac));
}
doUpdatePage(feed, version, content, tag = "latest", ac = mac()) {
return this.doPut(`feed/${feed}/page/${version}?tag=${tag}`, content, mri(ac));
}
doPublishPage(feed, content, ac = mac()) {
const { FormData: FormData2 } = this.http;
const form = new FormData2();
form.append("version", content.version);
form.append("type", content.type);
form.append("embed", content.embed);
if (content.tag) {
form.append("tag", content.tag);
}
if (content.options) {
form.append("options", JSON.stringify(content.options));
}
if (content.files) {
for (const [path, file] of content.files) {
form.append(path, file);
}
}
return this.doPost(`feed/${feed}/page`, form, mri(ac));
}
doQueryAllPilets(feed, tag = "latest", view = "all", ac = mac()) {
const queryString = makeQueryString({ tag, view });
return this.doGet(`feed/${feed}/pilets?${queryString}`, mri(ac));
}
doQueryUploadedPilets(feed, name, offset = "", count = "20", ac = mac()) {
const queryString = makeQueryString({ offset, count });
return this.doGet(`feed/${feed}/pilets/${name}/versions?${queryString}`, mri(ac));
}
doPublishPilet(feed, tag, file, ac = mac()) {
const { FormData: FormData2 } = this.http;
const form = new FormData2();
form.append("file", file);
form.append("tag", tag);
return this.doPost(`pilet/${feed}`, form, mri(ac));
}
doQueryCurrentPilets(feed, ac = mac()) {
return this.doGet(`pilet/${feed}`, mri(ac)).then((res) => res.items);
}
doQueryPiletDetails(feed, pilet, tag = "latest", ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}?tag=${tag}`, mri(ac));
}
doQueryPiletReadme(feed, pilet, ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}/readme`, mri(ac));
}
doQueryFeedExists(feed, ac = mac()) {
return this.doGet(`feed/${feed}/check`, mri(ac));
}
doQueryApiKeyScopes(ac = mac()) {
return this.doGet(`api-key-scope`, mri(ac));
}
doQueryApiKeys(feed, ac = mac()) {
if (feed === "*") {
return this.doQueryGeneralApiKeys(ac);
} else {
return this.doQueryFeedApiKeys(feed, ac);
}
}
doQueryFeedApiKeys(feed, ac = mac()) {
return this.doGet(`feed/${feed}/api-keys`, mri(ac));
}
doQueryGeneralApiKeys(ac = mac()) {
return this.doGet(`api-key`, mri(ac));
}
doQueryFeatures(feed, ac = mac()) {
return this.doGet(`feed/${feed}/features`, mri(ac));
}
doQueryRules(feed, ac = mac()) {
return this.doGet(`feed/${feed}/rules`, mri(ac));
}
doCreateFeed(content, ac = mac()) {
return this.doPost(`feed`, content, mri(ac));
}
doAddFeature(feed, content, ac = mac()) {
return this.doPost(`feed/${feed}/features`, content, mri(ac));
}
doAddRule(feed, content, ac = mac()) {
return this.doPost(`feed/${feed}/rules`, content, mri(ac));
}
doGenerateApiKey(feed, content, ac = mac()) {
if (feed === "*") {
return this.doGenerateGeneralApiKey(content, ac);
} else {
return this.doGenerateFeedApiKey(feed, content, ac);
}
}
doGenerateFeedApiKey(feed, content, ac = mac()) {
return this.doPost(`feed/${feed}/api-keys`, content, mri(ac));
}
doGenerateGeneralApiKey(content, ac = mac()) {
return this.doPost(`api-key`, content, mri(ac));
}
doDeleteFeed(feed, ac = mac()) {
return this.doDelete(`feed/${feed}`, mri(ac));
}
doRevokeGeneralApiKey(id, ac = mac()) {
return this.doDelete(`api-key/${id}`, mri(ac));
}
doRevokeApiKey(feed, id, ac = mac()) {
if (feed === "*") {
return this.doRevokeGeneralApiKey(id, ac);
} else {
return this.doRevokeFeedApiKey(feed, id, ac);
}
}
doRevokeFeedApiKey(feed, id, ac = mac()) {
return this.doDelete(`feed/${feed}/api-keys/${id}`, mri(ac));
}
doDeletePilet(feed, id, all = false, ac = mac()) {
return this.doDelete(`feed/${feed}/pilets/${id}?all=${all}`, mri(ac));
}
doDeleteFeature(feed, id, ac = mac()) {
return this.doDelete(`feed/${feed}/features/${id}`, mri(ac));
}
doDeleteRule(feed, id, ac = mac()) {
return this.doDelete(`feed/${feed}/rules/${id}`, mri(ac));
}
doUpdateFeature(feed, id, content, ac = mac()) {
return this.doPut(`feed/${feed}/features/${id}`, content, mri(ac));
}
doUpdateRule(feed, id, content, ac = mac()) {
return this.doPut(`feed/${feed}/rules/${id}`, content, mri(ac));
}
doUpdatePilet(feed, id, content, tag = "latest", ac = mac()) {
return this.doPut(`feed/${feed}/pilets/${id}?tag=${tag}`, content, mri(ac));
}
doUpdateFeed(feed, content, ac = mac()) {
return this.doPut(`feed/${feed}`, content, mri(ac));
}
doUpdateApiKey(feed, id, content, ac = mac()) {
if (feed === "*") {
return this.doUpdateGeneralApiKey(id, content, ac);
} else {
return this.doUpdateFeedApiKey(feed, id, content, ac);
}
}
doUpdateFeedApiKey(feed, id, content, ac = mac()) {
return this.doPut(`feed/${feed}/api-keys/${id}`, content, mri(ac));
}
doUpdateGeneralApiKey(id, content, ac = mac()) {
return this.doPut(`api-key/${id}`, content, mri(ac));
}
doQueryAudits(offset = "", count = "20", areaName = "", areaId = "", objectId = "", userId = "", q, ac = mac(), start, end) {
const queryString = makeQueryString({
offset,
count,
areaName,
areaId,
objectId,
userId,
q,
start,
end
});
return this.doGet(`audit?${queryString}`, mri(ac));
}
doQueryAudit(id, ac = mac()) {
return this.doGet(`audit/${id}`, mri(ac));
}
doQueryAllUsers(q, offset, count, ac = mac()) {
const queryString = makeQueryString({
q,
offset,
count
});
return this.doGet(`query-users?${queryString}`, mri(ac));
}
doQueryFeedContributors(feed, ac = mac()) {
return this.doGet(`feed/${feed}/contributors`, mri(ac));
}
doPutFeedContributors(feed, content, ac = mac()) {
return this.doPut(`feed/${feed}/contributors`, content, mri(ac));
}
doQueryFeedTags(feed, ac = mac()) {
return this.doGet(`feed/${feed}/tags`, mri(ac));
}
doDeleteFeedTag(feed, tag, ac = mac()) {
return this.doDelete(`feed/${feed}/tags/${tag}`, mri(ac));
}
doQueryConfigs(feed, pilet, ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}/configs`, mri(ac));
}
doQueryConfig(feed, pilet, config, ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}/configs/${config}`, mri(ac));
}
doAddConfig(feed, pilet, content, ac = mac()) {
return this.doPost(`feed/${feed}/pilets/${pilet}/configs`, content, mri(ac));
}
doDeleteConfig(feed, pilet, config, ac = mac()) {
return this.doDelete(`feed/${feed}/pilets/${pilet}/configs/${config}`, mri(ac));
}
doUpdateConfig(feed, pilet, config, content, ac = mac()) {
return this.doPut(`feed/${feed}/pilets/${pilet}/configs/${config}`, content, mri(ac));
}
doQueryAllFeedConfigs(feed, ac = mac()) {
return this.doGet(`feed/${feed}/configs`, mri(ac));
}
doQueryFeedConfigs(feed, configId, ac = mac()) {
return this.doGet(`feed/${feed}/configs/${configId}`, mri(ac));
}
doQueryFeedConfig(feed, configId, config, ac = mac()) {
return this.doGet(`feed/${feed}/configs/${configId}/${config}`, mri(ac));
}
doAddFeedConfig(feed, configId, content, ac = mac()) {
return this.doPost(`feed/${feed}/configs/${configId}`, content, mri(ac));
}
doDeleteFeedConfig(feed, configId, config, ac = mac()) {
return this.doDelete(`feed/${feed}/configs/${configId}/${config}`, mri(ac));
}
doUpdateFeedConfig(feed, configId, config, content, ac = mac()) {
return this.doPut(`feed/${feed}/configs/${configId}/${config}`, content, mri(ac));
}
doQueryEntities(feed, ac = mac()) {
return this.doGet(`feed/${feed}/entities`, mri(ac));
}
doQueryEntity(feed, id, ac = mac()) {
return this.doGet(`feed/${feed}/entities/${id}`, mri(ac));
}
doAddEntity(feed, content, ac = mac()) {
return this.doPost(`feed/${feed}/entities`, content, mri(ac));
}
doDeleteEntity(feed, id, ac = mac()) {
return this.doDelete(`feed/${feed}/entities/${id}`, mri(ac));
}
doUpdateEntity(feed, id, content, ac = mac()) {
return this.doPut(`feed/${feed}/entities/${id}`, content, mri(ac));
}
doQueryExternalUsers(q, offset, count, ac = mac()) {
const queryString = makeQueryString({
q,
offset,
count
});
return this.doGet(`external-users?${queryString}`, mri(ac));
}
doQueryUsers(ac = mac()) {
return this.doGet(`user`, mri(ac));
}
doQueryUser(id, ac = mac()) {
return this.doGet(`user/${id}`, mri(ac));
}
doAddUser(content, ac = mac()) {
return this.doPost(`user`, content, mri(ac));
}
doDeleteUser(id, ac = mac()) {
return this.doDelete(`user/${id}`, mri(ac));
}
doUpdateUser(id, content, ac = mac()) {
return this.doPut(`user/${id}`, content, mri(ac));
}
doQueryCustomRules(ac = mac()) {
return this.doGet(`customrule`, mri(ac));
}
doQueryGroups(ac = mac()) {
return this.doGet(`group`, mri(ac));
}
doQueryGroup(id, ac = mac()) {
return this.doGet(`group/${id}`, mri(ac));
}
doAddGroup(content, ac = mac()) {
return this.doPost(`group`, content, mri(ac));
}
doUpdateGroup(id, content, ac = mac()) {
return this.doPut(`group/${id}`, content, mri(ac));
}
doDeleteGroup(id, ac = mac()) {
return this.doDelete(`group/${id}`, mri(ac));
}
doAddCustomRules(file, content, ac = mac()) {
return this.doPost(`customrule`, { file, content }, mri(ac));
}
doDeleteCustomRule(file, ac = mac()) {
return this.doDelete(`customrule/${file}`, mri(ac));
}
doQueryCustomRuleDetails(file, ac = mac()) {
return this.doGet(`customrule/${file}`, mri(ac));
}
doTestRule(feed, rule, content, ac = mac()) {
return this.doPost(`feed/${feed}/rules/${rule}/test`, content, mri(ac));
}
doQueryCurrentUser(ac = mac()) {
return this.doGet(`current-user`, mri(ac));
}
doUpdateCurrentUser(content, ac = mac()) {
return this.doPut(`current-user`, content, mri(ac));
}
doQueryStatus(ac = mac()) {
return fetchWithoutToken(this.http, this.getUrl("status"), mri(ac)).then((res) => res.json());
}
doQueryStatistics(ac = mac()) {
return fetchWithoutToken(this.http, this.getUrl("statistics"), mri(ac)).then((res) => res.json());
}
doQueryRulesSchema(ac = mac()) {
return fetchWithoutToken(this.http, this.getUrl("schema/rule"), mri(ac)).then((res) => res.json());
}
doQueryFeedAnalysis(feed, ac = mac()) {
return this.doGet(`feed/${feed}/analysis`, mri(ac));
}
doQueryPiletAnalysis(feed, id, ac = mac()) {
return this.doGet(`feed/${feed}/analysis/${id}`, mri(ac));
}
doQueryFeedVulnerabiltiyAnalysis(feed, ac = mac()) {
return this.doGet(`feed/${feed}/vulnerabilities`, mri(ac));
}
doTriggerVulnerabilityAnalysis(feed, ac = mac()) {
return this.doPost(`feed/${feed}/vulnerabilities`, {}, mri(ac));
}
doRecheckDomains(feed, domains, ac = mac()) {
return this.doPut(`feed/${feed}/domains`, { domains }, mri(ac));
}
doQueryFeedStatistics(feed, from, to, ac = mac()) {
const queryString = makeQueryString({ from, to });
return this.doGet(`feed/${feed}/statistics?${queryString}`, mri(ac));
}
doQueryAdminFeedStatistics(offset = "", count = "40", ac = mac()) {
const queryString = makeQueryString({ offset, count });
return this.doGet(`statistics/feed?${queryString}`, mri(ac));
}
doQueryAdminFeedStatisticsDetails(feed, from, to, ac = mac()) {
const queryString = makeQueryString({ from, to });
return this.doGet(`statistics/feed/${feed}?${queryString}`, mri(ac));
}
doQueryNpmRegistry(feed, ac = mac()) {
return this.doGet(`registry/${feed}`, mri(ac));
}
doQueryNpmPackage(feed, name, ac = mac()) {
return this.doGet(`registry/${feed}/${name}`, mri(ac));
}
doUploadNpmPackage(feed, name, body, ac = mac()) {
return this.doPut(`registry/${feed}/${name}`, body, mri(ac));
}
doDownloadFile(fileUrl, ac = mac()) {
return fetchWithToken(this.http, fileUrl, mri(ac)).then((res) => res.blob());
}
doGetLicenseInfo(ac = mac()) {
return this.doGet("license", mri(ac));
}
doQueryPiletStorageEntries(feed, pilet, ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}/storage`, mri(ac));
}
doAddPiletStorageEntry(feed, pilet, name, content, ac = mac()) {
return this.doPost(`feed/${feed}/pilets/${pilet}/storage`, { name, content }, mri(ac));
}
doQueryPiletStorageEntry(feed, pilet, name, ac = mac()) {
return this.doGet(`feed/${feed}/pilets/${pilet}/storage/${name}`, mri(ac));
}
doUpdatePiletStorageEntry(feed, pilet, name, details, ac = mac()) {
return this.doPut(`feed/${feed}/pilets/${pilet}/storage/${name}`, details, mri(ac));
}
doDeletePiletStorageEntry(feed, pilet, name, ac = mac()) {
return this.doDelete(`feed/${feed}/pilets/${pilet}/storage/${name}`, mri(ac));
}
doQueryGenerators(feed, ac = mac()) {
return this.doGet(`feed/${feed}/generator`, mri(ac));
}
doQueryGeneratorSteps(feed, generator, ac = mac()) {
return this.doGet(`feed/${feed}/generator/${generator}`, mri(ac));
}
doGeneratePilet(feed, generator, details, ac = mac()) {
return this.doPost(`feed/${feed}/generator/${generator}`, details, mri(ac));
}
doQueryAllGenerators(ac = mac()) {
return this.doGet(`generator`, mri(ac));
}
doCreateGenerator(details, ac = mac()) {
return this.doPost(`generator`, details, mri(ac));
}
doQueryGeneratorDetails(generatorId, ac = mac()) {
return this.doGet(`generator/${generatorId}`, mri(ac));
}
doDeleteGenerator(generatorId, ac = mac()) {
return this.doDelete(`generator/${generatorId}`, mri(ac));
}
doQueryDashboard(ac = mac()) {
return this.doGet("dashboard", mri(ac));
}
doQueryDashboardFeeds(offset = "", count = "40", ac = mac()) {
const queryString = makeQueryString({ offset, count });
return this.doGet(`dashboard/feeds?${queryString}`, mri(ac));
}
doSendNotification(details, ac = mac()) {
return this.doPost(`dashboard/notifications`, details, mri(ac));
}
doQueryIssues(ac = mac()) {
return this.doGet("issue", mri(ac));
}
doCreateIssue(details, ac = mac()) {
return this.doPost("issue", details, mri(ac));
}
};
// src/utils.ts
function createKeyHandler(apiKeyType) {
switch (apiKeyType) {
case "basic":
return (apiKey) => `Basic ${apiKey}`;
case "bearer":
return (apiKey) => `Bearer ${apiKey}`;
default:
return (apiKey) => apiKey;
}
}
function createAuthHead(options) {
if ("apiKey" in options) {
const { apiKey } = options;
if (typeof apiKey !== "string") {
throw new Error('The field "apiKey" has to be of type string.');
}
return () => Promise.resolve(`Basic ${apiKey}`);
} else if ("resolveApiKey" in options) {
const { resolveApiKey, apiKeyType = "basic" } = options;
if (typeof options.resolveApiKey !== "function") {
throw new Error('The field "resolveApiKey" has to be of type function.');
}
if (typeof apiKeyType !== "string") {
throw new Error('The field "apiKeyType" has to be of type string.');
}
const makeKey = createKeyHandler(apiKeyType);
return () => resolveApiKey().then(makeKey);
} else {
throw new Error('You must either specify "apikey" or "resolveApiKey".');
}
}
// src/index.ts
function createServiceClient(options) {
if (typeof options === "undefined") {
throw new Error('No "options" provided to create the service client.');
}
if (typeof options !== "object") {
throw new Error('The "options" have to be an object containing an "apiKey" field.');
}
const { host = "https://feed.piral.cloud", defaults = {} } = options;
if (typeof host !== "string") {
throw new Error('The field "host" has to be of type string.');
}
const getAuthorizationHeader = createAuthHead(options);
const fetch = window.fetch.bind(window);
const http = {
fetch,
FormData,
Headers,
getAuthorizationHeader,
defaults
};
return new FeedServiceApiClient(http, host);
}
export {
createServiceClient
};