globalping
Version:
The official TS/JS client for the Globalping API
435 lines (423 loc) • 20.2 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var A=async(t,r)=>{let e=typeof r=="function"?await r(t):r;if(e)return t.scheme==="bearer"?`Bearer ${e}`:t.scheme==="basic"?`Basic ${btoa(e)}`:e},R={bodySerializer:t=>JSON.stringify(t,(r,e)=>typeof e=="bigint"?e.toString():e)},U=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},_=t=>{switch(t){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},D=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},O=({allowReserved:t,explode:r,name:e,style:a,value:i})=>{if(!r){let s=(t?i:i.map(l=>encodeURIComponent(l))).join(_(a));switch(a){case "label":return `.${s}`;case "matrix":return `;${e}=${s}`;case "simple":return s;default:return `${e}=${s}`}}let o=U(a),n=i.map(s=>a==="label"||a==="simple"?t?s:encodeURIComponent(s):y({allowReserved:t,name:e,value:s})).join(o);return a==="label"||a==="matrix"?o+n:n},y=({allowReserved:t,name:r,value:e})=>{if(e==null)return "";if(typeof e=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return `${r}=${t?e:encodeURIComponent(e)}`},q=({allowReserved:t,explode:r,name:e,style:a,value:i})=>{if(i instanceof Date)return `${e}=${i.toISOString()}`;if(a!=="deepObject"&&!r){let s=[];Object.entries(i).forEach(([f,u])=>{s=[...s,f,t?u:encodeURIComponent(u)];});let l=s.join(",");switch(a){case "form":return `${e}=${l}`;case "label":return `.${l}`;case "matrix":return `;${e}=${l}`;default:return l}}let o=D(a),n=Object.entries(i).map(([s,l])=>y({allowReserved:t,name:a==="deepObject"?`${e}[${s}]`:s,value:l})).join(o);return a==="label"||a==="matrix"?o+n:n};var H=/\{[^{}]+\}/g,B=({path:t,url:r})=>{let e=r,a=r.match(H);if(a)for(let i of a){let o=false,n=i.substring(1,i.length-1),s="simple";n.endsWith("*")&&(o=true,n=n.substring(0,n.length-1)),n.startsWith(".")?(n=n.substring(1),s="label"):n.startsWith(";")&&(n=n.substring(1),s="matrix");let l=t[n];if(l==null)continue;if(Array.isArray(l)){e=e.replace(i,O({explode:o,name:n,style:s,value:l}));continue}if(typeof l=="object"){e=e.replace(i,q({explode:o,name:n,style:s,value:l}));continue}if(s==="matrix"){e=e.replace(i,`;${y({name:n,value:l})}`);continue}let f=encodeURIComponent(s==="label"?`.${l}`:l);e=e.replace(i,f);}return e},E=({allowReserved:t,array:r,object:e}={})=>i=>{let o=[];if(i&&typeof i=="object")for(let n in i){let s=i[n];if(s!=null){if(Array.isArray(s)){o=[...o,O({allowReserved:t,explode:true,name:n,style:"form",value:s,...r})];continue}if(typeof s=="object"){o=[...o,q({allowReserved:t,explode:true,name:n,style:"deepObject",value:s,...e})];continue}o=[...o,y({allowReserved:t,name:n,value:s})];}}return o.join("&")},P=t=>{if(!t)return "stream";let r=t.split(";")[0]?.trim();if(r){if(r.startsWith("application/json")||r.endsWith("+json"))return "json";if(r==="multipart/form-data")return "formData";if(["application/","audio/","image/","video/"].some(e=>r.startsWith(e)))return "blob";if(r.startsWith("text/"))return "text"}},I=async({security:t,...r})=>{for(let e of t){let a=await A(e,r.auth);if(!a)continue;let i=e.name??"Authorization";switch(e.in){case "query":r.query||(r.query={}),r.query[i]=a;break;case "cookie":r.headers.append("Cookie",`${i}=${a}`);break;case "header":default:r.headers.set(i,a);break}return}},S=t=>W({baseUrl:t.baseUrl,path:t.path,query:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:E(t.querySerializer),url:t.url}),W=({baseUrl:t,path:r,query:e,querySerializer:a,url:i})=>{let o=i.startsWith("/")?i:`/${i}`,n=(t??"")+o;r&&(n=B({path:r,url:n}));let s=e?a(e):"";return s.startsWith("?")&&(s=s.substring(1)),s&&(n+=`?${s}`),n},C=(t,r)=>{let e={...t,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=x(t.headers,r.headers),e},x=(...t)=>{let r=new Headers;for(let e of t){if(!e||typeof e!="object")continue;let a=e instanceof Headers?e.entries():Object.entries(e);for(let[i,o]of a)if(o===null)r.delete(i);else if(Array.isArray(o))for(let n of o)r.append(i,n);else o!==undefined&&r.set(i,typeof o=="object"?JSON.stringify(o):o);}return r},h=class{_fns;constructor(){this._fns=[];}clear(){this._fns=[];}exists(r){return this._fns.indexOf(r)!==-1}eject(r){let e=this._fns.indexOf(r);e!==-1&&(this._fns=[...this._fns.slice(0,e),...this._fns.slice(e+1)]);}use(r){this._fns=[...this._fns,r];}},T=()=>({error:new h,request:new h,response:new h}),N=E({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),Q={"Content-Type":"application/json"},w=(t={})=>({...R,headers:Q,parseAs:"auto",querySerializer:N,...t});var J=(t={})=>{let r=C(w(),t),e=()=>({...r}),a=n=>(r=C(r,n),e()),i=T(),o=async n=>{let s={...r,...n,fetch:n.fetch??r.fetch??globalThis.fetch,headers:x(r.headers,n.headers)};s.security&&await I({...s,security:s.security}),s.body&&s.bodySerializer&&(s.body=s.bodySerializer(s.body)),(s.body===undefined||s.body==="")&&s.headers.delete("Content-Type");let l=S(s),f={redirect:"follow",...s},u=new Request(l,f);for(let p of i.request._fns)u=await p(u,s);let k=s.fetch,c=await k(u);for(let p of i.response._fns)c=await p(c,u,s);let m={request:u,response:c};if(c.ok){if(c.status===204||c.headers.get("Content-Length")==="0")return {data:{},...m};let p=(s.parseAs==="auto"?P(c.headers.get("Content-Type")):s.parseAs)??"json";if(p==="stream")return {data:c.body,...m};let b=await c[p]();return p==="json"&&(s.responseValidator&&await s.responseValidator(b),s.responseTransformer&&(b=await s.responseTransformer(b))),{data:b,...m}}let g=await c.text();try{g=JSON.parse(g);}catch{}let d=g;for(let p of i.error._fns)d=await p(g,c,u,s);if(d=d||{},s.throwOnError)throw d;return {error:d,...m}};return {buildUrl:S,connect:n=>o({...n,method:"CONNECT"}),delete:n=>o({...n,method:"DELETE"}),get:n=>o({...n,method:"GET"}),getConfig:e,head:n=>o({...n,method:"HEAD"}),interceptors:i,options:n=>o({...n,method:"OPTIONS"}),patch:n=>o({...n,method:"PATCH"}),post:n=>o({...n,method:"POST"}),put:n=>o({...n,method:"PUT"}),request:o,setConfig:a,trace:n=>o({...n,method:"TRACE"})}};
var version = "0.1.2";
var pkg = {
version: version};
class HttpError extends Error {
constructor(request, response) {
super(`HTTP ${response.status} ${response.statusText}`);
this.request = request;
this.response = response;
Object.defineProperty(this, 'request', { enumerable: false });
Object.defineProperty(this, 'response', { enumerable: false });
}
}
class ApiError extends HttpError {
constructor(request, response, data) {
super(request, response);
this.data = data;
}
}
// This file is auto-generated by @hey-api/openapi-ts
const client = J(w({
baseUrl: 'https://api.globalping.io',
}));
// This file is auto-generated by @hey-api/openapi-ts
/**
* Create a measurement
* Creates a new measurement with parameters set in the request body.
* The measurement runs asynchronously and you can retrieve its current state at the URL returned in the `Location` header.
*
* ### Client guidelines
*
* - If the application is running in interactive mode, set the `inProgressUpdates` option to `true` to have the API
* return partial results as soon as they are available. This allows the user to see the measurement progress in real time.
* - If the application is interactive by default but also implements a "CI" mode for scripting, do not set the flag in the CI mode.
* - To perform multiple measurements using exactly the same probes, create a single measurement first, then pass its `id` in the `locations` field for the other measurements.
* - When you receive a `429` response, inform the user about their current rate limit status based on the response headers. Depending on the exact situation and on what your application supports, you may also suggest:
* - Signing in or using an access token.
* - Learning more about how to get additional credits at https://globalping.io/credits.
* - Repeating the measurement with fewer probes.
*
*/
const createMeasurement = (options) => {
var _a;
return ((_a = options === null || options === void 0 ? void 0 : options.client) !== null && _a !== void 0 ? _a : client).post({
security: [
{
scheme: 'bearer',
type: 'http',
},
{
scheme: 'bearer',
type: 'http',
},
],
url: '/v1/measurements',
...options,
headers: {
'Content-Type': 'application/json',
...options === null || options === void 0 ? void 0 : options.headers,
},
});
};
/**
* Get a measurement by ID
* Returns the status and results of an existing measurement.
* Measurements are typically available for up to 7 days after creation.
*
* > **Tip**: A link to this endpoint is returned in the `Location` response header when creating the measurement.
*
* ### Client guidelines
*
* As it can take a few seconds for a measurement to complete, you should use the following process for retrieving the results:
* 1. Request the measurement to retrieve its status.
* 2. If the status is `in-progress`, wait 500 milliseconds and start again at step 1. Note that it's important to wait 500 ms *after* receiving the response rather than using an "every 500ms" interval as for large measurements, the request itself may take a few hundred milliseconds to complete.
* 3. If the status is anything **other** than `in-progress`, stop. The measurement is no longer running, and its results are final.
*
* > **Important**: Do not query the results of a single measurement more often than every 500 milliseconds. Sending more than two
* requests per second may trigger a rate limit and prevent you from accessing the results for a few seconds.
*
*/
const getMeasurement = (options) => {
var _a;
return ((_a = options.client) !== null && _a !== void 0 ? _a : client).get({
url: '/v1/measurements/{id}',
...options,
});
};
/**
* List probes currently online
* Returns a list of all probes currently online and their metadata, such as location and assigned tags.
*
* > **Note**: Probes don't expose unique IDs that would allow you to explicitly select them.
* Instead, specify the requested location or an ID of an existing measurement when creating new measurements.
*
*/
const listProbes = (options) => {
var _a;
return ((_a = options === null || options === void 0 ? void 0 : options.client) !== null && _a !== void 0 ? _a : client).get({
url: '/v1/probes',
...options,
});
};
/**
* Get current rate limits
* Returns rate limits for the current user (if authenticated) or IP address (if not authenticated).
*
*/
const getLimits = (options) => {
var _a;
return ((_a = options === null || options === void 0 ? void 0 : options.client) !== null && _a !== void 0 ? _a : client).get({
security: [
{
scheme: 'bearer',
type: 'http',
},
{
scheme: 'bearer',
type: 'http',
},
],
url: '/v1/limits',
...options,
});
};
// This file is auto-generated by @hey-api/openapi-ts
/**
* The transport protocol to use.
*/
/**
* EXPERIMENTAL: The IP version to use. Only allowed if the target is a hostname.
*
*/
const IpVersion = {
4: 4,
6: 6,
};
/**
* The transport protocol to use.
*/
const TracerouteProtocol = {
ICMP: 'ICMP',
TCP: 'TCP',
UDP: 'UDP',
};
/**
* The type of DNS query.
*/
const DnsQueryType = {
A: 'A',
AAAA: 'AAAA',
ANY: 'ANY',
CNAME: 'CNAME',
DNSKEY: 'DNSKEY',
DS: 'DS',
HTTPS: 'HTTPS',
MX: 'MX',
NS: 'NS',
NSEC: 'NSEC',
PTR: 'PTR',
RRSIG: 'RRSIG',
SOA: 'SOA',
TXT: 'TXT',
SRV: 'SRV',
SVCB: 'SVCB',
};
/**
* The protocol to use for the DNS query.
*/
const DnsProtocol = {
TCP: 'TCP',
UDP: 'UDP',
};
/**
* The transport protocol to use.
*/
const MtrProtocol = {
ICMP: 'ICMP',
TCP: 'TCP',
UDP: 'UDP',
};
/**
* The HTTP method to use.
*/
const HttpRequestMethod = {
HEAD: 'HEAD',
GET: 'GET',
OPTIONS: 'OPTIONS',
};
const HttpProtocol = {
HTTP: 'HTTP',
HTTPS: 'HTTPS',
HTTP2: 'HTTP2',
};
/**
* The measurement type.
*/
const MeasurementType = {
PING: 'ping',
TRACEROUTE: 'traceroute',
DNS: 'dns',
MTR: 'mtr',
HTTP: 'http',
};
/**
* A two-letter continent code.
*/
const ContinentCode = {
AF: 'AF',
AN: 'AN',
AS: 'AS',
EU: 'EU',
NA: 'NA',
OC: 'OC',
SA: 'SA',
};
/**
* A geographic region name based on UN [Standard Country or Area Codes for Statistical Use (M49)](https://unstats.un.org/unsd/methodology/m49/).
*
*/
const RegionName = {
NORTHERN_AFRICA: 'Northern Africa',
EASTERN_AFRICA: 'Eastern Africa',
MIDDLE_AFRICA: 'Middle Africa',
SOUTHERN_AFRICA: 'Southern Africa',
WESTERN_AFRICA: 'Western Africa',
CARIBBEAN: 'Caribbean',
CENTRAL_AMERICA: 'Central America',
SOUTH_AMERICA: 'South America',
NORTHERN_AMERICA: 'Northern America',
CENTRAL_ASIA: 'Central Asia',
EASTERN_ASIA: 'Eastern Asia',
SOUTH_EASTERN_ASIA: 'South-eastern Asia',
SOUTHERN_ASIA: 'Southern Asia',
WESTERN_ASIA: 'Western Asia',
EASTERN_EUROPE: 'Eastern Europe',
NORTHERN_EUROPE: 'Northern Europe',
SOUTHERN_EUROPE: 'Southern Europe',
WESTERN_EUROPE: 'Western Europe',
AUSTRALIA_AND_NEW_ZEALAND: 'Australia and New Zealand',
MELANESIA: 'Melanesia',
MICRONESIA: 'Micronesia',
POLYNESIA: 'Polynesia',
};
/**
* The type of the used key, or `null` for unrecognized types.
*/
const TlsKeyType = {
RSA: 'RSA',
EC: 'EC',
NULL: 'null',
};
/**
* The current measurement status. Any value other than `in-progress` is final.
*/
const MeasurementStatus = {
IN_PROGRESS: 'in-progress',
FINISHED: 'finished',
};
/**
* Type of the rate limit.
*/
const RateLimitType = {
IP: 'ip',
USER: 'user',
};
const wait = async (ms) => {
await new Promise(resolve => setTimeout(resolve, ms));
};
class Globalping {
constructor({ auth, userAgent, throwApiErrors, timeout } = {}) {
this.userAgent = userAgent !== null && userAgent !== void 0 ? userAgent : `globalping-typescript/${pkg.version} (https://github.com/jsdelivr/globalping-typescript)`;
this.throwApiErrors = throwApiErrors !== null && throwApiErrors !== void 0 ? throwApiErrors : false;
this.timeout = timeout !== null && timeout !== void 0 ? timeout : 30000;
this.auth = auth;
this.client = J(w({
baseUrl: 'https://api.globalping.io',
}));
}
/**
* @see {@link sdk.createMeasurement} for the API docs
*/
createMeasurement(measurement) {
return this.transformResult(this.request(createMeasurement, { body: measurement }));
}
/**
* @see {@link sdk.getMeasurement} for the API docs
*/
async getMeasurement(id) {
const result = await this.transformResult(this.request(getMeasurement, { path: { id } }));
if (!result.ok) {
return result;
}
return result;
}
/**
* @see {@link sdk.getMeasurement} for the API docs
*/
async awaitMeasurement(id) {
const getMeasurement$1 = (eTag) => {
return this.request(getMeasurement, {
path: { id },
headers: eTag ? {
'If-None-Match': eTag,
} : {},
});
};
const start = Date.now();
let internalResult = await getMeasurement$1();
while (internalResult.data && internalResult.data.status === MeasurementStatus.IN_PROGRESS) {
if (Date.now() - start > 60000) {
throw new Error(`Timed out waiting for measurement ${id} to finish.`);
}
await wait(500);
const newInternalResult = await getMeasurement$1(internalResult.response.headers.get('ETag'));
if (newInternalResult.response.status !== 304) {
internalResult = newInternalResult;
}
}
const result = await this.transformResult(internalResult);
if (!result.ok) {
return result;
}
const data = result.data;
Globalping.assertMeasurementFinished(data);
return { ...result, data };
}
/**
* @see {@link sdk.listProbes} for the API docs
*/
async listProbes() {
return this.transformResult(this.request(listProbes));
}
/**
* @see {@link sdk.getLimits} for the API docs
*/
async getLimits() {
return this.transformResult(this.request(getLimits));
}
request(fn, options) {
const optionsWithDefaults = {
auth: this.auth,
timeout: this.timeout,
userAgent: this.userAgent,
...(options || {}),
};
return fn({
client: this.client,
fetch: (request) => {
var _a;
const headers = new Headers(request.headers);
headers.set('User-Agent', optionsWithDefaults.userAgent);
if (optionsWithDefaults.auth) {
headers.set('Authorization', `Bearer ${optionsWithDefaults.auth}`);
}
return fetch(new Request(request, {
headers,
signal: (_a = optionsWithDefaults.signal) !== null && _a !== void 0 ? _a : AbortSignal.timeout(optionsWithDefaults.timeout),
}));
},
...optionsWithDefaults,
});
}
async transformResult(requestResult) {
const { data, error, request, response } = await requestResult;
if (error != null) {
if (typeof error !== 'object' || !('error' in error)) {
throw new HttpError(request, response);
}
if (this.throwApiErrors) {
throw new ApiError(request, response, error);
}
return { ok: false, data: error, request, response };
}
if (data == null) {
throw new Error('Unexpected undefined data');
}
return { ok: true, data, request, response };
}
static assertHttpStatus(status, result) {
if (!Globalping.isHttpStatus(status, result)) {
throw new Error(`Expected HTTP status ${status}, got ${result.response.status}`);
}
}
static assertMeasurementFinished(measurement) {
if (!Globalping.isMeasurementFinished(measurement)) {
throw new Error(`Expected measurement status ${MeasurementStatus.FINISHED}, got ${measurement.status}`);
}
}
static assertMeasurementType(type, measurement) {
if (!Globalping.isMeasurementType(type, measurement)) {
throw new Error(`Expected measurement type ${type}, got ${measurement.type}`);
}
}
static isHttpStatus(status, result) {
return result.response.status === status;
}
static isMeasurementFinished(measurement) {
return measurement.status === MeasurementStatus.FINISHED;
}
static isMeasurementType(type, measurement) {
return measurement.type === type;
}
}
exports.ApiError = ApiError;
exports.ContinentCode = ContinentCode;
exports.DnsProtocol = DnsProtocol;
exports.DnsQueryType = DnsQueryType;
exports.Globalping = Globalping;
exports.HttpError = HttpError;
exports.HttpProtocol = HttpProtocol;
exports.HttpRequestMethod = HttpRequestMethod;
exports.IpVersion = IpVersion;
exports.MeasurementStatus = MeasurementStatus;
exports.MeasurementType = MeasurementType;
exports.MtrProtocol = MtrProtocol;
exports.RateLimitType = RateLimitType;
exports.RegionName = RegionName;
exports.TlsKeyType = TlsKeyType;
exports.TracerouteProtocol = TracerouteProtocol;
exports.default = Globalping;
//# sourceMappingURL=bundle.cjs.map