Skip to content

Commit abd0b11

Browse files
committed
Initial commit
1 parent 6c3f6a6 commit abd0b11

29 files changed

+8185
-1
lines changed

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = tab
9+
10+
[*.md]
11+
indent_style = space
12+
13+
[*.{yaml,yml}]
14+
indent_style = space
15+
indent_size = 2

.eslintrc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"extends": "@martin-kolarik/eslint-config/typescript",
3+
"ignorePatterns": [
4+
"coverage/**",
5+
"data/**",
6+
"dist/**"
7+
],
8+
"overrides": [
9+
{
10+
"files": [
11+
"src/**/*.ts"
12+
],
13+
"extends": "@martin-kolarik/eslint-config/typescript-type-checking",
14+
"parserOptions": {
15+
"project": true
16+
},
17+
"rules": {
18+
"@typescript-eslint/no-redundant-type-constituents": "off"
19+
}
20+
},
21+
{
22+
"files": [
23+
"test/**"
24+
],
25+
"rules": {
26+
"@typescript-eslint/no-explicit-any": "off",
27+
"@typescript-eslint/no-non-null-assertion": "off",
28+
"no-restricted-properties": [
29+
"error",
30+
{
31+
"object": "sinon",
32+
"property": "spy"
33+
},
34+
{
35+
"object": "sinon",
36+
"property": "stub"
37+
},
38+
{
39+
"object": "sinon",
40+
"property": "mock"
41+
},
42+
{
43+
"object": "sinon",
44+
"property": "fake"
45+
},
46+
{
47+
"object": "sinon",
48+
"property": "restore"
49+
},
50+
{
51+
"object": "sinon",
52+
"property": "reset"
53+
},
54+
{
55+
"object": "sinon",
56+
"property": "resetHistory"
57+
},
58+
{
59+
"object": "sinon",
60+
"property": "resetBehavior"
61+
}
62+
]
63+
}
64+
}
65+
]
66+
}

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.github/FUNDING.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# These are supported funding model platforms
2+
github: jsdelivr
3+
open_collective: jsdelivr
4+
custom: ['https://www.jsdelivr.com/sponsors']

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ "*" ]
6+
pull_request:
7+
branches: [ "*" ]
8+
9+
jobs:
10+
build:
11+
name: Run tests
12+
runs-on: ubuntu-latest
13+
14+
env:
15+
NODE_ENV: test
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: 20.x
22+
- name: Build
23+
run: |
24+
npm ci
25+
npm run build
26+
- name: Test
27+
run: |
28+
npm test
29+
- name: Test Dist
30+
run: |
31+
rm -rf node_modules
32+
npm ci --omit=dev
33+
npm run test:dist

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.idea/
2+
.vscode/
3+
.nyc_output/
4+
node_modules/
5+
coverage/
6+
dist/
7+
tmp/
8+
config/local*
9+
.eslintcache

.mocharc.cjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
'exit': true,
3+
'timeout': 10000,
4+
// 'file': [
5+
// 'test/setup.ts',
6+
// ],
7+
'spec': [
8+
'test/tests/integration/**/*.ts',
9+
],
10+
'node-option': [
11+
'enable-source-maps',
12+
'experimental-specifier-resolution=node',
13+
'loader=ts-node/esm',
14+
],
15+
};

.mocharc.e2e.cjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
'exit': true,
3+
'timeout': 10000,
4+
// 'file': [
5+
// 'test/setup.ts',
6+
// ],
7+
'spec': [
8+
'test/tests/e2e/**/*.ts',
9+
],
10+
'node-option': [
11+
'enable-source-maps',
12+
'experimental-specifier-resolution=node',
13+
'loader=ts-node/esm',
14+
],
15+
};

CONTRIBUTING.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Setting up the environment
2+
3+
```sh
4+
npm i
5+
```
6+
7+
## Modifying/Adding code
8+
9+
The contents of `src/openapi-ts` is generated from the [OpenAPI specification](https://api.globalping.io/v1/spec.yaml). Run `npm run openapi:generate` to update it.
10+
11+
The rest of the code is handwritten and can be modified as needed.
12+
13+
## Running tests
14+
15+
`npm run test:integration`
16+
17+
Runs integration tests with mocked data. These tests are part of the CI process.
18+
19+
`npm run test:e2e`
20+
21+
Runs live tests that hit the API. These tests are NOT run as a part of the CI.
22+
23+
`npm run test:dist`
24+
25+
Verifies the final builds and `package.json` configuration are correct and the package loads without errors.
26+
27+
## Linting and formatting
28+
29+
This repository uses [eslint](https://www.npmjs.com/package/eslint) to format the code.
30+
31+
`npm run lint`
32+
33+
`npm run lint:fix`
34+
35+
## Publishing and releases
36+
37+
TODO

README.md

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,173 @@
1-
# globalping-typescript
1+
# Globalping Typescript API Client
2+
3+
The official TypeScript client for the [Globalping API](https://globalping.io/docs/api.globalping.io).
4+
Works both in the browser and in node.js.
5+
6+
If you are not familiar with Globalping yet, check out the main [Globalping repository](https://github.com/jsdelivr/globalping) first.
7+
8+
## Installation
9+
10+
```sh
11+
npm i globalping
12+
```
13+
14+
In client-side applications, you can also import the library directly via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/globalping).
15+
16+
## Usage
17+
18+
The library provides methods for all API operations, as well as types for all parameters.
19+
It also exports values for all `enum` parameters as JS objects, which can be used for client-side validation.
20+
21+
### Quick start
22+
23+
```ts
24+
import { Globalping } from 'globalping';
25+
26+
const globalping = new Globalping({
27+
auth: 'your-globalping-api-token', // Optional.
28+
// See the Advanced configuration section below for more options.
29+
});
30+
```
31+
32+
### Create a measurement
33+
34+
Creates a new measurement with the set parameters. The measurement runs asynchronously, and you can retrieve its current state using `getMeasurement()` or wait for its final state using `awaitMeasurement()`.
35+
36+
```ts
37+
const result = await globalping.createMeasurement({
38+
type: 'ping',
39+
target: 'example.com',
40+
});
41+
42+
if (!result.ok) {
43+
// See the Error handling section below.
44+
}
45+
46+
console.log(result); // => { data: { id: string, probesCount: number }, ... }
47+
```
48+
49+
### Get a measurement
50+
51+
Returns the current state of the measurement.
52+
53+
```ts
54+
const result = await globalping.getMeasurement(id);
55+
console.log(result); // => { data: { id: string, status: string, ... }, ... }
56+
```
57+
58+
### Await a measurement
59+
60+
Similar to `getMeasurement()`, but keeps pooling the API until the measurement is finished, and returns its final state.
61+
62+
```ts
63+
const result = await globalping.awaitMeasurement(id);
64+
console.log(result); // => { data: { id: string, status: 'finished', ... }, ... }
65+
```
66+
67+
### List probes
68+
69+
Returns a list of all probes currently online and their metadata, such as location and assigned tags.
70+
71+
```ts
72+
const result = await globalping.listProbes();
73+
console.log(result); // => { data: [ { version: string, ... }, ... ], ... }
74+
```
75+
76+
### Get rate limits
77+
78+
Returns rate limits for the current user (if authenticated) or IP address (if not authenticated).
79+
80+
```ts
81+
const result = await globalping.getLimits();
82+
console.log(result); // => { data: { rateLimit: { ... }, ... }, ... }
83+
```
84+
85+
### TypeScript convenience methods
86+
87+
There are a few convenience methods for determining more specific response types.
88+
89+
#### `assertHttpStatus()` / `isHttpStatus()`
90+
91+
```ts
92+
const result = await globalping.createMeasurement(id);
93+
94+
if (Globalping.isHttpStatus(400, result)) {
95+
// You can now access parameter validation error details.
96+
}
97+
```
98+
99+
#### `assertMeasurementType()` / `isMeasurementType()`
100+
101+
```ts
102+
const result = await globalping.awaitMeasurement(id);
103+
Globalping.assertMeasurementType('ping', result); // You can now access ping-specific properties on result.data
104+
```
105+
106+
### Error handling
107+
108+
The library offers two ways of handling errors.
109+
110+
#### `throwApiErrors: false` (default)
111+
112+
Known API errors, such as parameter validation errors, rate limit errors, etc., are not thrown as exceptions. This allows the library to return precise error types for each method, which means you can access all error details in a type-safe way. You need to check each `result` before accessing its data.
113+
114+
```ts
115+
const result = await globalping.createMeasurement();
116+
117+
// This is sufficient if you only care about success/failure.
118+
if (result.ok) {
119+
// result.data is the success response, e.g., { id: string, probesCount: number }
120+
} else {
121+
// result.data can be any of the possible error responses
122+
123+
if (Globalping.isHttpStatus(400, result)) {
124+
// You can also access result.data.error.params here which is specific to this status code.
125+
}
126+
}
127+
```
128+
129+
Any unexpected errors, such as timeouts, networking errors, etc., are still thrown as exceptions.
130+
131+
#### `throwApiErrors: true`
132+
133+
All errors, including known API errors, are thrown as exceptions. You don't have to check `result.ok` before accessing the data, but the thrown errors only have generic types.
134+
135+
```ts
136+
import { ApiError, HttpError } from 'globalping';
137+
138+
try {
139+
const result = await globalping.createMeasurement();
140+
console.log(result.data) // => { id: string, probesCount: number }
141+
} catch (e) {
142+
if (e instanceof ApiError) {
143+
// Any error with a valid JSON response body.
144+
} else if (e instanceof HttpError) {
145+
// Any HTTP error with an invalid response body.
146+
} else {
147+
// Any other error.
148+
}
149+
}
150+
```
151+
152+
### Advanced configuration
153+
154+
There are a few config options available, but all of them are optional:
155+
156+
`auth: string`
157+
158+
A user authentication token obtained from https://dash.globalping.io or via OAuth (currently available only to official Globalping apps).
159+
160+
`userAgent: string`
161+
162+
Refers to this library by default. If you build another open-source project based on this library, you should override this value to point to your project instead.
163+
164+
`throwApiErrors: boolean`
165+
166+
If `false` (default), known API errors are not thrown as exceptions. See the Error handling section.
167+
168+
`timeout: number`
169+
170+
A timeout in ms for every HTTP request made by the library. The default value is 30 seconds, and you shouldn't need to change this.
171+
172+
## Development
173+
Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more information.

0 commit comments

Comments
 (0)