Skip to content

Commit 8c07929

Browse files
committed
Upgrade typings for v0.4.0-unstable.3 release, misc. fixes
1 parent 9708e83 commit 8c07929

File tree

11 files changed

+1520
-96
lines changed

11 files changed

+1520
-96
lines changed

.api-server-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.0-unstable.2
1+
0.4.0-unstable.3

.sdk-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.0-unstable
1+
0.2.0-unstable

packages/sdk/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
"defu": "6.1.2"
2929
},
3030
"devDependencies": {
31-
"@types/node": "18.16.14"
31+
"@types/node": "18.16.14",
32+
"testcontainers": "9.8.0",
33+
"vitest": "0.31.2"
3234
}
3335
}

packages/sdk/src/client.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@ import type {
2525
responses
2626
} from '@ncharts/types';
2727

28+
import { hasOwnProperty, isBrowser, isObject, type Ctor } from '@noelware/utils';
2829
import { DEFAULT_API_VERSION, DEFAULT_BASE_URL } from './constants';
29-
import { hasOwnProperty, isBrowser, isObject } from '@noelware/utils';
30-
import { transformJSON, transformYaml } from './internal';
30+
import { transformJSON, transformYaml, assert } from './internal';
3131
import type { AbstractAuthStrategy } from './auth';
3232
import { OrganizationContainer } from './containers/organizations';
3333
import { ApiKeysContainer } from './containers/apikeys';
3434
import { UserContainer } from './containers/users';
3535
import { HTTPError } from './errors/HTTPError';
36-
import assert from 'assert';
3736
import defu from 'defu';
3837

3938
export type HTTPMethod = 'get' | 'put' | 'head' | 'post' | 'patch' | 'delete';
@@ -42,7 +41,7 @@ export const Methods: readonly HTTPMethod[] = ['get', 'put', 'head', 'post', 'pa
4241
/**
4342
* Fetch implementation blue-print.
4443
*/
45-
export type Fetch = (input: RequestInit | URL, init?: RequestInit) => Promise<Response>;
44+
export type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
4645

4746
/**
4847
* FormData implementation blue-print
@@ -80,7 +79,7 @@ export interface ClientOptions {
8079
* To avoid any errors when requesting data, you will need to install the [form-data](https://npm.im/form-data)
8180
* Node.js package to send form data.
8281
*/
83-
FormData?: { new (...args: any[]): FormData };
82+
FormData?: Ctor<FormData>;
8483

8584
/**
8685
* Base URL to send requests to
@@ -158,7 +157,9 @@ export interface RequestOptions<R extends Route, Method extends HTTPMethod, Body
158157
const kClientOptions = {
159158
apiVersion: DEFAULT_API_VERSION,
160159
baseURL: DEFAULT_BASE_URL,
161-
headers: {}
160+
headers: {
161+
'User-Agent': 'Noelware/charted-sdk-js (+https://github.com/charted-dev/js-sdk)'
162+
}
162163
} satisfies ClientOptions;
163164

164165
export class Client {
@@ -570,7 +571,7 @@ export class Client {
570571

571572
if (url.match(/{([\w\.]+)}/g) && options !== undefined && hasOwnProperty(options, 'pathParameters')) {
572573
const params = options.pathParameters as Record<string, unknown>;
573-
formedUrl = formedUrl.replaceAll(/([\w\.]+)}/g, (_, key) => {
574+
formedUrl = formedUrl.replaceAll(/{([\w\.]+)}/g, (_, key) => {
574575
if (hasOwnProperty(params, key)) {
575576
return String(params[key]);
576577
}
@@ -596,6 +597,6 @@ export class Client {
596597
}
597598
}
598599

599-
return formedUrl;
600+
return formedUrl.replace(/\/+$/, '');
600601
}
601602
}

packages/sdk/src/containers/repositories.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export class RepositoryContainer {
2828
) {}
2929

3030
/**
31-
* Retrives a list of all the repositories available
31+
* Fetch all the available user or organization repositories
32+
* @param options Request options object to override.
3233
*/
3334
all(
3435
options?: RequestOptions<'/users/{idOrName}/repositories', 'get', unknown>
@@ -55,6 +56,12 @@ export class RepositoryContainer {
5556
);
5657
}
5758

59+
/**
60+
* Returns a single repository from a user or organization.
61+
* @param idOrName The snowflake or the name of the repository to fetch from
62+
* @param options Request options
63+
* @returns A single repository, if it was found.
64+
*/
5865
get(
5966
idOrName: NameOrSnowflake,
6067
options?: RequestOptions<'/users/{idOrName}/repositories/{repoIdOrName}', 'get', unknown>
@@ -86,6 +93,10 @@ export class RepositoryContainer {
8693
payload: payloads.repositories.CreateRepositoryPayload,
8794
options?: RequestOptions<'/users/{idOrName}/repositories', 'put', unknown>
8895
): Promise<ApiResponse<responses.repositories.Create>> {
96+
if (this.type === 'user' && this.owner !== '@me') {
97+
throw new Error('You must use <client>.me.repositories.create() to create a repository on your account.');
98+
}
99+
89100
return new Promise((resolve, reject) =>
90101
this.client
91102
.put(

packages/sdk/src/errors/HTTPError.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,33 @@
1515
* limitations under the License.
1616
*/
1717

18+
import { hasOwnProperty, isObject } from '@noelware/utils';
19+
import { STATUS_CODES } from 'http';
1820
import { ApiError } from '@ncharts/types';
19-
import { isObject } from '@noelware/utils';
21+
22+
const isFatalError = (value: unknown) => isObject<Record<string, unknown>>(value) && hasOwnProperty(value, 'class');
2023

2124
/**
2225
* {@link Error} that represents an HTTP error.
2326
*/
2427
export class HTTPError extends Error {
2528
constructor(public readonly statusCode: number, errors: ApiError<unknown>[] = []) {
26-
super(`Received status code [${statusCode}] with errors\n${HTTPError._formatErrors(errors)}`.trim());
29+
super(
30+
`Received status code ${statusCode} (${
31+
STATUS_CODES[statusCode] || 'Unknown'
32+
}) with errors\n${HTTPError._formatErrors(errors)}`.trim()
33+
);
2734
}
2835

2936
private static _formatErrors(errors: ApiError<unknown>[]) {
3037
let buf = '';
3138
for (let i = 0; i < errors.length; i++) {
3239
const error = errors[i];
40+
if (isFatalError(error)) {
41+
const details = error.detail as Record<string, unknown>;
42+
console.log(details);
43+
}
44+
3345
buf += `[${error.code}]: ${error.message}${
3446
error.detail !== undefined
3547
? `\n${

packages/sdk/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { Client, type ClientOptions } from './client';
2020
export * as constants from './constants';
2121
export type * from './client';
2222
export * from './errors';
23+
export * from './auth';
2324

2425
/**
2526
* Creates a new {@link Client} instance.

packages/sdk/src/internal.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,28 @@ interface YAML {
2222
load(text: string, ...args: any[]): unknown;
2323
}
2424

25+
export const assert = (condition: boolean, message: string) => {
26+
if (!condition) {
27+
throw new Error(message);
28+
}
29+
};
30+
2531
export const transformJSON = async <T>(resp: Response) => {
2632
if (!resp.ok) {
27-
const data = await resp.json().catch(() => ({}));
33+
const data = await resp.json().catch((ex) => ({
34+
success: false,
35+
errors: [
36+
{
37+
code: 'SDK_ERROR',
38+
message: ex instanceof Error ? ex.message : 'Unknown error',
39+
details: {
40+
sdk: true,
41+
error: ex
42+
}
43+
}
44+
]
45+
}));
46+
2847
throw new HTTPError(resp.status, hasOwnProperty(data, 'errors') ? data.errors : []);
2948
}
3049

packages/sdk/tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"removeComments": false,
66
"types": ["node"],
77
"baseUrl": ".",
8-
"noEmit": true // tsup does this for us=
8+
"noEmit": true
99
},
1010
"exclude": ["node_modules"],
11-
"include": ["**/*.ts"]
11+
"include": ["**/*.ts", "vite.config.ts"]
1212
}

0 commit comments

Comments
 (0)