UNPKG

globalping

Version:

The official TS/JS client for the Globalping API

441 lines (428 loc) 20.9 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.globalping = {})); })(this, (function (exports) { 'use strict'; 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; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=bundle.js.map