Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aabd66933d | ||
|
|
528081bb88 | ||
|
|
6b0e8b8f77 | ||
|
|
a63c360539 | ||
|
|
89bdd6e3b8 | ||
|
|
909691328e |
No files matched your search
@@ -0,0 +1,15 @@
|
||||
# Contributing
|
||||
|
||||
## Opening a pull request on git.zacharyzhang.com
|
||||
|
||||
Forking is disabled on this server. Open pull requests with AGit instead:
|
||||
|
||||
1. Register an account at https://git.zacharyzhang.com
|
||||
2. Clone, commit your changes, then push to a `refs/for/<target-branch>` ref:
|
||||
|
||||
```bash
|
||||
git clone https://git.zacharyzhang.com/Elydora-Infrastructure/Elydora-Node-SDK.git
|
||||
git push origin HEAD:refs/for/main -o topic=<short-name> -o title="<PR title>" -o description="<PR body>"
|
||||
```
|
||||
|
||||
3. To update the pull request, push again with the same `topic`.
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@elydora/sdk",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@elydora/sdk",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@decimalturn/toml-patch": "^2.0.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@elydora/sdk",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"description": "Node.js/TypeScript SDK for the Elydora tamper-evident audit platform",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
+14
-2
@@ -285,9 +285,13 @@ export class ElydoraClient {
|
||||
return handleResponse<HealthResponse>(res);
|
||||
}
|
||||
|
||||
/** 503 carries the degraded report, not an error. */
|
||||
async deepHealth(): Promise<DeepHealthResponse> {
|
||||
const url = `${this.baseUrl}/v1/health/deep`;
|
||||
const res = await fetch(url, { method: 'GET', headers: { 'Accept': 'application/json' } });
|
||||
if (res.status === 503) {
|
||||
return (await res.json()) as DeepHealthResponse;
|
||||
}
|
||||
return handleResponse<DeepHealthResponse>(res);
|
||||
}
|
||||
|
||||
@@ -340,7 +344,7 @@ export class ElydoraClient {
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
|
||||
if (attempt < this.maxRetries && (res.status === 429 || res.status >= 500)) {
|
||||
if (attempt < this.maxRetries && isIdempotent(method) && (res.status === 429 || res.status >= 500)) {
|
||||
const retryAfter = res.headers.get('Retry-After');
|
||||
const delayMs = retryAfter
|
||||
? parseInt(retryAfter, 10) * 1000
|
||||
@@ -357,10 +361,11 @@ export class ElydoraClient {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (attempt < this.maxRetries) {
|
||||
if (attempt < this.maxRetries && isIdempotent(method)) {
|
||||
await sleep(Math.min(1000 * 2 ** attempt, 10_000));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +373,13 @@ export class ElydoraClient {
|
||||
}
|
||||
}
|
||||
|
||||
const IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE']);
|
||||
|
||||
/** A lost response to a non-idempotent request must not be replayed. */
|
||||
function isIdempotent(method: string): boolean {
|
||||
return IDEMPOTENT_METHODS.has(method.toUpperCase());
|
||||
}
|
||||
|
||||
async function handleResponse<T>(res: Response): Promise<T> {
|
||||
if (res.ok) {
|
||||
if (res.status === 204) {
|
||||
|
||||
@@ -384,6 +384,7 @@ export interface RotateApiTokenResponse {
|
||||
readonly token: string;
|
||||
readonly expires_at: number | null;
|
||||
readonly token_id: string;
|
||||
readonly previous_token_grace_until: number;
|
||||
}
|
||||
|
||||
export interface HealthResponse {
|
||||
|
||||
Reference in new issue
Block a user