@clevercloud/client
Advanced tools
Comparing version
# Clever Client changelog | ||
## Unreleased (????-??-??) | ||
... | ||
## 7.3.0 (2021-03-05) | ||
* Add `execWarpscript()` function for browsers with fetch | ||
* Add new Warp10 requests around access logs | ||
* `getStatusCodesFromWarp10()` | ||
* `getRequestsFromWarp10()` | ||
* `getAccessLogsHeatmapFromWarp10()` | ||
* `getAccessLogsDotmapFromWarp10()` | ||
* Add `withCache()` helper function | ||
* Add `withOptions()` helper function | ||
* Add timeout support for browser based request (API and Warp10) | ||
## 7.2.0 (2021-01-26) | ||
@@ -4,0 +20,0 @@ |
@@ -8,2 +8,6 @@ "use strict"; | ||
exports.getContinuousAccessLogsFromWarp10 = getContinuousAccessLogsFromWarp10; | ||
exports.getStatusCodesFromWarp10 = getStatusCodesFromWarp10; | ||
exports.getRequestsFromWarp10 = getRequestsFromWarp10; | ||
exports.getAccessLogsHeatmapFromWarp10 = getAccessLogsHeatmapFromWarp10; | ||
exports.getAccessLogsDotmapFromWarp10 = getAccessLogsDotmapFromWarp10; | ||
@@ -109,2 +113,132 @@ var _componentEmitter = _interopRequireDefault(require("component-emitter")); | ||
return emitter; | ||
} | ||
function getStatusCodesFromWarp10({ | ||
warpToken, | ||
ownerId, | ||
appId | ||
}) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' NOW 24 h @clevercloud/accessLogs_status_code_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { | ||
__: getSlug('statuscodes', ownerId, appId) | ||
}, | ||
responseHandler([results]) { | ||
// Remove status codes "-1" YOLO | ||
delete results['-1']; | ||
return results; | ||
} | ||
}); | ||
} | ||
function getRequestsFromWarp10({ | ||
warpToken, | ||
ownerId, | ||
appId | ||
}) { | ||
const ONE_HOUR = 1000 * 60 * 60; | ||
const now = new Date(); | ||
const nowTs = now.getTime(); | ||
const nowRoundedTs = nowTs - nowTs % ONE_HOUR; | ||
const endDateMicroSecs = new Date(nowRoundedTs).getTime() * 1000; | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' ${endDateMicroSecs} 24 h 1 h @clevercloud/accessLogs_request_count_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { | ||
__: getSlug('requests', ownerId, appId) | ||
}, | ||
responseHandler([results]) { | ||
// Convert timestamps in ms | ||
return results.map(([from, to, count]) => [Math.floor(from / 1000), Math.floor(to / 1000), count]); | ||
} | ||
}); | ||
} | ||
function getAccessLogsHeatmapFromWarp10({ | ||
warpToken, | ||
ownerId, | ||
appId | ||
}) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' 24 @clevercloud/logs_heatmap_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { | ||
__: getSlug('heatmap', ownerId, appId) | ||
}, | ||
responseHandler([results]) { | ||
return Object.entries(results).filter(([jsonData]) => jsonData !== '[NaN,NaN]').map(([jsonData, count]) => { | ||
const [lat, lon] = JSON.parse(jsonData); | ||
return { | ||
lat, | ||
lon, | ||
count | ||
}; | ||
}); | ||
} | ||
}); | ||
} // "from" and "to" are timestamps in microseconds | ||
function getAccessLogsDotmapFromWarp10({ | ||
warpToken, | ||
ownerId, | ||
appId, | ||
from, | ||
to | ||
}) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const fromDate = (0, _date.toMicroIsoString)(from); | ||
const toDate = (0, _date.toMicroIsoString)(to); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' '${fromDate}' '${toDate}' @clevercloud/logs_dotmap_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { | ||
__: getSlug('dotmap', ownerId, appId) | ||
}, | ||
responseHandler([results]) { | ||
return Object.entries(results).map(([jsonData, count]) => { | ||
const [lat, lon, country, city] = JSON.parse(jsonData); | ||
return { | ||
lat, | ||
lon, | ||
country, | ||
city, | ||
count | ||
}; | ||
}); | ||
} | ||
}); | ||
} | ||
function getGranularity(ownerId, appId) { | ||
return appId != null ? ['app_id', appId] : ['owner_id', ownerId]; | ||
} | ||
function getSlug(prefix, ...items) { | ||
const shortItems = items.filter(a => a != null).map(a => a.slice(0, 10)); | ||
return [prefix, ...shortItems].join('__'); | ||
} |
@@ -126,6 +126,7 @@ "use strict"; | ||
* @param {String} params.email | ||
* @param {Object} body | ||
*/ | ||
function todo_addEmailAddress(params) { | ||
function todo_addEmailAddress(params, body) { | ||
// no multipath for /self or /organisations/{id} | ||
@@ -136,6 +137,7 @@ return Promise.resolve({ | ||
headers: { | ||
Accept: 'application/json' | ||
} // no query params | ||
// no body | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
// no query params | ||
body | ||
}); | ||
@@ -142,0 +144,0 @@ } |
@@ -7,2 +7,5 @@ "use strict"; | ||
exports.request = request; | ||
var _requestFetchWithTimeout = require("./request.fetch-with-timeout.js"); | ||
const JSON_TYPE = 'application/json'; | ||
@@ -54,6 +57,6 @@ const FORM_TYPE = 'application/x-www-form-urlencoded'; | ||
const body = formatBody(requestParams); | ||
const response = await window.fetch(url.toString(), { ...requestParams, | ||
const response = await (0, _requestFetchWithTimeout.fetchWithTimeout)(url.toString(), { ...requestParams, | ||
body, | ||
mode: 'cors' | ||
}); | ||
}, requestParams.timeout); | ||
@@ -60,0 +63,0 @@ if (response.status >= 400) { |
@@ -89,1 +89,104 @@ import Emitter from 'component-emitter'; | ||
} | ||
export function getStatusCodesFromWarp10 ({ warpToken, ownerId, appId }) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' NOW 24 h @clevercloud/accessLogs_status_code_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { __: getSlug('statuscodes', ownerId, appId) }, | ||
responseHandler ([results]) { | ||
// Remove status codes "-1" YOLO | ||
delete results['-1']; | ||
return results; | ||
}, | ||
}); | ||
} | ||
export function getRequestsFromWarp10 ({ warpToken, ownerId, appId }) { | ||
const ONE_HOUR = 1000 * 60 * 60; | ||
const now = new Date(); | ||
const nowTs = now.getTime(); | ||
const nowRoundedTs = nowTs - nowTs % ONE_HOUR; | ||
const endDateMicroSecs = new Date(nowRoundedTs).getTime() * 1000; | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' ${endDateMicroSecs} 24 h 1 h @clevercloud/accessLogs_request_count_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { __: getSlug('requests', ownerId, appId) }, | ||
responseHandler ([results]) { | ||
// Convert timestamps in ms | ||
return results | ||
.map(([from, to, count]) => [Math.floor(from / 1000), Math.floor(to / 1000), count]); | ||
}, | ||
}); | ||
} | ||
export function getAccessLogsHeatmapFromWarp10 ({ warpToken, ownerId, appId }) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' 24 @clevercloud/logs_heatmap_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { __: getSlug('heatmap', ownerId, appId) }, | ||
responseHandler ([results]) { | ||
return Object.entries(results) | ||
.filter(([jsonData]) => jsonData !== '[NaN,NaN]') | ||
.map(([jsonData, count]) => { | ||
const [lat, lon] = JSON.parse(jsonData); | ||
return { lat, lon, count }; | ||
}); | ||
}, | ||
}); | ||
} | ||
// "from" and "to" are timestamps in microseconds | ||
export function getAccessLogsDotmapFromWarp10 ({ warpToken, ownerId, appId, from, to }) { | ||
const [granularity, id] = getGranularity(ownerId, appId); | ||
const fromDate = toMicroIsoString(from); | ||
const toDate = toMicroIsoString(to); | ||
const warpscript = `'${warpToken}' '${granularity}' '${id}' '${fromDate}' '${toDate}' @clevercloud/logs_dotmap_v1`; | ||
return Promise.resolve({ | ||
method: 'post', | ||
url: '/api/v0/exec', | ||
body: warpscript, | ||
// This is ignored by Warp10, it's here to help identify HTTP calls in browser devtools | ||
queryParams: { __: getSlug('dotmap', ownerId, appId) }, | ||
responseHandler ([results]) { | ||
return Object.entries(results).map(([jsonData, count]) => { | ||
const [lat, lon, country, city] = JSON.parse(jsonData); | ||
return { lat, lon, country, city, count }; | ||
}); | ||
}, | ||
}); | ||
} | ||
function getGranularity (ownerId, appId) { | ||
return (appId != null) | ||
? ['app_id', appId] | ||
: ['owner_id', ownerId]; | ||
} | ||
function getSlug (prefix, ...items) { | ||
const shortItems = items | ||
.filter((a) => a != null) | ||
.map((a) => a.slice(0, 10)); | ||
return [prefix, ...shortItems].join('__'); | ||
} |
@@ -85,4 +85,5 @@ import { pickNonNull } from '../../pick-non-null.js'; | ||
* @param {String} params.email | ||
* @param {Object} body | ||
*/ | ||
export function todo_addEmailAddress(params) { | ||
export function todo_addEmailAddress(params, body) { | ||
// no multipath for /self or /organisations/{id} | ||
@@ -92,5 +93,5 @@ return Promise.resolve({ | ||
url: `/v2/self/emails/${params.email}`, | ||
headers: { Accept: 'application/json' }, | ||
headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, | ||
// no query params | ||
// no body | ||
body, | ||
}); | ||
@@ -97,0 +98,0 @@ } |
@@ -0,1 +1,3 @@ | ||
import { fetchWithTimeout } from './request.fetch-with-timeout.js'; | ||
const JSON_TYPE = 'application/json'; | ||
@@ -62,7 +64,3 @@ const FORM_TYPE = 'application/x-www-form-urlencoded'; | ||
const response = await window.fetch(url.toString(), { | ||
...requestParams, | ||
body, | ||
mode: 'cors', | ||
}); | ||
const response = await fetchWithTimeout(url.toString(), { ...requestParams, body, mode: 'cors' }, requestParams.timeout); | ||
@@ -69,0 +67,0 @@ if (response.status >= 400) { |
{ | ||
"name": "@clevercloud/client", | ||
"version": "7.2.0", | ||
"version": "7.3.0", | ||
"description": "JavaScript REST client and utils for Clever Cloud's API", | ||
@@ -59,3 +59,7 @@ "homepage": "https://github.com/CleverCloud/clever-client.js", | ||
"superagent": "^5.2.2" | ||
}, | ||
"volta": { | ||
"node": "14.16.0", | ||
"npm": "7.6.1" | ||
} | ||
} |
442396
3.3%94
9.3%13378
2.88%