@shopvirge/shopvirge-client 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -0
- package/package.json +48 -0
- package/src/api/generated/core/ApiError.ts +25 -0
- package/src/api/generated/core/ApiRequestOptions.ts +20 -0
- package/src/api/generated/core/ApiResult.ts +7 -0
- package/src/api/generated/core/CancelablePromise.ts +130 -0
- package/src/api/generated/core/OpenAPI.ts +59 -0
- package/src/api/generated/core/request.ts +398 -0
- package/src/api/generated/index.ts +7 -0
- package/src/api/generated/schemas.gen.ts +4836 -0
- package/src/api/generated/services.gen.ts +3324 -0
- package/src/api/generated/types.gen.ts +3714 -0
- package/src/api/openapi.json +7114 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @shopvirge/shopvirge-client
|
|
2
|
+
|
|
3
|
+
Auto-generated TypeScript API client for the [ShopVirge](https://api.shopvirge.com) API, built from the OpenAPI spec using [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @shopvirge/shopvirge-client
|
|
9
|
+
# or
|
|
10
|
+
yarn add @shopvirge/shopvirge-client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Configure the API URL
|
|
16
|
+
|
|
17
|
+
Before making any API calls, set the `BASE` URL on the exported `OpenAPI` config object:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { OpenAPI } from '@shopvirge/shopvirge-client';
|
|
21
|
+
|
|
22
|
+
OpenAPI.BASE = 'https://api.shopvirge.com';
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Authentication
|
|
26
|
+
|
|
27
|
+
You can configure authentication by setting `TOKEN` or `HEADERS`:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { OpenAPI } from '@shopvirge/shopvirge-client';
|
|
31
|
+
|
|
32
|
+
// Bearer token
|
|
33
|
+
OpenAPI.TOKEN = 'your-access-token';
|
|
34
|
+
|
|
35
|
+
// Or use custom headers
|
|
36
|
+
OpenAPI.HEADERS = {
|
|
37
|
+
Authorization: 'Bearer your-access-token',
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Making API calls
|
|
42
|
+
|
|
43
|
+
Once configured, use the generated service functions to interact with the API:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { OpenAPI, ShopsService } from '@shopvirge/shopvirge-client';
|
|
47
|
+
|
|
48
|
+
OpenAPI.BASE = 'https://api.shopvirge.com';
|
|
49
|
+
|
|
50
|
+
const shops = await ShopsService.getShops();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Full configuration reference
|
|
54
|
+
|
|
55
|
+
All properties on the `OpenAPI` config object can be overridden:
|
|
56
|
+
|
|
57
|
+
| Property | Type | Default | Description |
|
|
58
|
+
| ------------------ | -------------------------------------- | ----------- | -------------------------------- |
|
|
59
|
+
| `BASE` | `string` | `''` | Base URL for all API requests |
|
|
60
|
+
| `TOKEN` | `string \| Resolver` | `undefined` | Bearer token or async resolver |
|
|
61
|
+
| `HEADERS` | `Record<string, string> \| Resolver` | `undefined` | Custom headers or async resolver |
|
|
62
|
+
| `CREDENTIALS` | `'include' \| 'omit' \| 'same-origin'` | `'include'` | Fetch credentials mode |
|
|
63
|
+
| `WITH_CREDENTIALS` | `boolean` | `false` | XHR withCredentials flag |
|
|
64
|
+
| `ENCODE_PATH` | `(path: string) => string` | `undefined` | Custom path encoder |
|
|
65
|
+
| `USERNAME` | `string \| Resolver` | `undefined` | Basic auth username |
|
|
66
|
+
| `PASSWORD` | `string \| Resolver` | `undefined` | Basic auth password |
|
|
67
|
+
|
|
68
|
+
### Request/Response interceptors
|
|
69
|
+
|
|
70
|
+
You can add interceptors to modify requests or responses:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { OpenAPI } from '@shopvirge/shopvirge-client';
|
|
74
|
+
|
|
75
|
+
OpenAPI.interceptors.request.use((request) => {
|
|
76
|
+
console.log('Request:', request);
|
|
77
|
+
return request;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
OpenAPI.interceptors.response.use((response) => {
|
|
81
|
+
console.log('Response:', response);
|
|
82
|
+
return response;
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
### Regenerate the client
|
|
89
|
+
|
|
90
|
+
From the `packages/shopvirge-client/` directory:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# From a local openapi.json file
|
|
94
|
+
yarn openapi-ts
|
|
95
|
+
|
|
96
|
+
# From the live API
|
|
97
|
+
yarn openapi-ts-live
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Sync package version
|
|
101
|
+
|
|
102
|
+
After regenerating, sync the package version from the OpenAPI spec:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
yarn sync-version
|
|
106
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shopvirge/shopvirge-client",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "jest --passWithNoTests",
|
|
12
|
+
"build": "tsup src/index.ts --format esm --dts --tsconfig tsconfig.json",
|
|
13
|
+
"tsc": "tsc --noEmit",
|
|
14
|
+
"lint": "eslint \"src/**/*.ts*\"",
|
|
15
|
+
"dev": "yarn build -- --watch",
|
|
16
|
+
"openapi-ts": "openapi-ts -i src/api/openapi.json -o src/api/generated",
|
|
17
|
+
"openapi-ts-live": "openapi-ts -i https://api.shopvirge.com/openapi.json -o src/api/generated",
|
|
18
|
+
"sync-version": "node -e \"const pkg=require('./package.json');const api=require('./src/api/openapi.json');pkg.version=api.info.version;require('fs').writeFileSync('package.json',JSON.stringify(pkg,null,4)+'\\n');\""
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@graphql-typed-document-node/core": "3.2.0",
|
|
22
|
+
"moment": "2.29.4",
|
|
23
|
+
"use-query-params": "2.2.1"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"graphql-request": "5.2.0",
|
|
27
|
+
"next": "^13.4.1",
|
|
28
|
+
"next-query-params": "4.2.2",
|
|
29
|
+
"react": "^18.2.0",
|
|
30
|
+
"react-query": "3.39.3",
|
|
31
|
+
"stripe": "^13.7.0",
|
|
32
|
+
"typescript": "^4.9.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@hey-api/openapi-ts": "^0.46.3",
|
|
36
|
+
"@testing-library/jest-dom": "^5.16.1",
|
|
37
|
+
"@testing-library/react": "^14.0.0",
|
|
38
|
+
"@testing-library/react-hooks": "^8.0.1",
|
|
39
|
+
"@testing-library/user-event": "^14.4.3",
|
|
40
|
+
"@types/jest": "^27.4.0",
|
|
41
|
+
"esbuild": "^0.14.10",
|
|
42
|
+
"esbuild-jest": "^0.5.0",
|
|
43
|
+
"jest": "^27.4.7",
|
|
44
|
+
"jest-watch-typeahead": "^1.0.0",
|
|
45
|
+
"react": "^18.2.0",
|
|
46
|
+
"react-dom": "^18.2.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ApiRequestOptions } from './ApiRequestOptions';
|
|
2
|
+
import type { ApiResult } from './ApiResult';
|
|
3
|
+
|
|
4
|
+
export class ApiError extends Error {
|
|
5
|
+
public readonly url: string;
|
|
6
|
+
public readonly status: number;
|
|
7
|
+
public readonly statusText: string;
|
|
8
|
+
public readonly body: unknown;
|
|
9
|
+
public readonly request: ApiRequestOptions;
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
request: ApiRequestOptions,
|
|
13
|
+
response: ApiResult,
|
|
14
|
+
message: string,
|
|
15
|
+
) {
|
|
16
|
+
super(message);
|
|
17
|
+
|
|
18
|
+
this.name = 'ApiError';
|
|
19
|
+
this.url = response.url;
|
|
20
|
+
this.status = response.status;
|
|
21
|
+
this.statusText = response.statusText;
|
|
22
|
+
this.body = response.body;
|
|
23
|
+
this.request = request;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ApiRequestOptions = {
|
|
2
|
+
readonly method:
|
|
3
|
+
| 'GET'
|
|
4
|
+
| 'PUT'
|
|
5
|
+
| 'POST'
|
|
6
|
+
| 'DELETE'
|
|
7
|
+
| 'OPTIONS'
|
|
8
|
+
| 'HEAD'
|
|
9
|
+
| 'PATCH';
|
|
10
|
+
readonly url: string;
|
|
11
|
+
readonly path?: Record<string, unknown>;
|
|
12
|
+
readonly cookies?: Record<string, unknown>;
|
|
13
|
+
readonly headers?: Record<string, unknown>;
|
|
14
|
+
readonly query?: Record<string, unknown>;
|
|
15
|
+
readonly formData?: Record<string, unknown>;
|
|
16
|
+
readonly body?: any;
|
|
17
|
+
readonly mediaType?: string;
|
|
18
|
+
readonly responseHeader?: string;
|
|
19
|
+
readonly errors?: Record<number | string, string>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export class CancelError extends Error {
|
|
2
|
+
constructor(message: string) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'CancelError';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
public get isCancelled(): boolean {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface OnCancel {
|
|
13
|
+
readonly isResolved: boolean;
|
|
14
|
+
readonly isRejected: boolean;
|
|
15
|
+
readonly isCancelled: boolean;
|
|
16
|
+
|
|
17
|
+
(cancelHandler: () => void): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class CancelablePromise<T> implements Promise<T> {
|
|
21
|
+
private _isResolved: boolean;
|
|
22
|
+
private _isRejected: boolean;
|
|
23
|
+
private _isCancelled: boolean;
|
|
24
|
+
readonly cancelHandlers: (() => void)[];
|
|
25
|
+
readonly promise: Promise<T>;
|
|
26
|
+
private _resolve?: (value: T | PromiseLike<T>) => void;
|
|
27
|
+
private _reject?: (reason?: unknown) => void;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
executor: (
|
|
31
|
+
resolve: (value: T | PromiseLike<T>) => void,
|
|
32
|
+
reject: (reason?: unknown) => void,
|
|
33
|
+
onCancel: OnCancel,
|
|
34
|
+
) => void,
|
|
35
|
+
) {
|
|
36
|
+
this._isResolved = false;
|
|
37
|
+
this._isRejected = false;
|
|
38
|
+
this._isCancelled = false;
|
|
39
|
+
this.cancelHandlers = [];
|
|
40
|
+
this.promise = new Promise<T>((resolve, reject) => {
|
|
41
|
+
this._resolve = resolve;
|
|
42
|
+
this._reject = reject;
|
|
43
|
+
|
|
44
|
+
const onResolve = (value: T | PromiseLike<T>): void => {
|
|
45
|
+
if (this._isResolved || this._isRejected || this._isCancelled) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this._isResolved = true;
|
|
49
|
+
if (this._resolve) this._resolve(value);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const onReject = (reason?: unknown): void => {
|
|
53
|
+
if (this._isResolved || this._isRejected || this._isCancelled) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this._isRejected = true;
|
|
57
|
+
if (this._reject) this._reject(reason);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const onCancel = (cancelHandler: () => void): void => {
|
|
61
|
+
if (this._isResolved || this._isRejected || this._isCancelled) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.cancelHandlers.push(cancelHandler);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
Object.defineProperty(onCancel, 'isResolved', {
|
|
68
|
+
get: (): boolean => this._isResolved,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
Object.defineProperty(onCancel, 'isRejected', {
|
|
72
|
+
get: (): boolean => this._isRejected,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
Object.defineProperty(onCancel, 'isCancelled', {
|
|
76
|
+
get: (): boolean => this._isCancelled,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return executor(onResolve, onReject, onCancel as OnCancel);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get [Symbol.toStringTag]() {
|
|
84
|
+
return 'Cancellable Promise';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public then<TResult1 = T, TResult2 = never>(
|
|
88
|
+
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
|
89
|
+
onRejected?:
|
|
90
|
+
| ((reason: unknown) => TResult2 | PromiseLike<TResult2>)
|
|
91
|
+
| null,
|
|
92
|
+
): Promise<TResult1 | TResult2> {
|
|
93
|
+
return this.promise.then(onFulfilled, onRejected);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public catch<TResult = never>(
|
|
97
|
+
onRejected?:
|
|
98
|
+
| ((reason: unknown) => TResult | PromiseLike<TResult>)
|
|
99
|
+
| null,
|
|
100
|
+
): Promise<T | TResult> {
|
|
101
|
+
return this.promise.catch(onRejected);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public finally(onFinally?: (() => void) | null): Promise<T> {
|
|
105
|
+
return this.promise.finally(onFinally);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public cancel(): void {
|
|
109
|
+
if (this._isResolved || this._isRejected || this._isCancelled) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this._isCancelled = true;
|
|
113
|
+
if (this.cancelHandlers.length) {
|
|
114
|
+
try {
|
|
115
|
+
for (const cancelHandler of this.cancelHandlers) {
|
|
116
|
+
cancelHandler();
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.warn('Cancellation threw an error', error);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.cancelHandlers.length = 0;
|
|
124
|
+
if (this._reject) this._reject(new CancelError('Request aborted'));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public get isCancelled(): boolean {
|
|
128
|
+
return this._isCancelled;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ApiRequestOptions } from './ApiRequestOptions';
|
|
2
|
+
|
|
3
|
+
type Headers = Record<string, string>;
|
|
4
|
+
type Middleware<T> = (value: T) => T | Promise<T>;
|
|
5
|
+
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
|
6
|
+
|
|
7
|
+
export class Interceptors<T> {
|
|
8
|
+
_fns: Middleware<T>[];
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this._fns = [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
eject(fn: Middleware<T>): void {
|
|
15
|
+
const index = this._fns.indexOf(fn);
|
|
16
|
+
if (index !== -1) {
|
|
17
|
+
this._fns = [
|
|
18
|
+
...this._fns.slice(0, index),
|
|
19
|
+
...this._fns.slice(index + 1),
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
use(fn: Middleware<T>): void {
|
|
25
|
+
this._fns = [...this._fns, fn];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type OpenAPIConfig = {
|
|
30
|
+
BASE: string;
|
|
31
|
+
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
|
32
|
+
ENCODE_PATH?: ((path: string) => string) | undefined;
|
|
33
|
+
HEADERS?: Headers | Resolver<Headers> | undefined;
|
|
34
|
+
PASSWORD?: string | Resolver<string> | undefined;
|
|
35
|
+
TOKEN?: string | Resolver<string> | undefined;
|
|
36
|
+
USERNAME?: string | Resolver<string> | undefined;
|
|
37
|
+
VERSION: string;
|
|
38
|
+
WITH_CREDENTIALS: boolean;
|
|
39
|
+
interceptors: {
|
|
40
|
+
request: Interceptors<RequestInit>;
|
|
41
|
+
response: Interceptors<Response>;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const OpenAPI: OpenAPIConfig = {
|
|
46
|
+
BASE: '',
|
|
47
|
+
CREDENTIALS: 'include',
|
|
48
|
+
ENCODE_PATH: undefined,
|
|
49
|
+
HEADERS: undefined,
|
|
50
|
+
PASSWORD: undefined,
|
|
51
|
+
TOKEN: undefined,
|
|
52
|
+
USERNAME: undefined,
|
|
53
|
+
VERSION: '0.2.2',
|
|
54
|
+
WITH_CREDENTIALS: false,
|
|
55
|
+
interceptors: {
|
|
56
|
+
request: new Interceptors(),
|
|
57
|
+
response: new Interceptors(),
|
|
58
|
+
},
|
|
59
|
+
};
|