@nvisy/sdk 0.1.0 → 0.2.0
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/CHANGELOG.md +23 -4
- package/LICENSE.txt +1 -1
- package/README.md +20 -61
- package/dist/client-D6GtLRbO.d.ts +823 -0
- package/dist/datatypes/index.d.ts +8 -0
- package/dist/datatypes/index.js +3 -0
- package/dist/datatypes/index.js.map +1 -0
- package/dist/index.d.ts +254 -2
- package/dist/index.js +1244 -361
- package/dist/index.js.map +1 -1
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +956 -0
- package/dist/services/index.js.map +1 -0
- package/dist/workspace-3RLqaMcj.d.ts +7055 -0
- package/package.json +33 -33
- package/dist/builder-BEUIGfoZ.d.ts +0 -138
- package/dist/builder.d.ts +0 -2
- package/dist/builder.js +0 -424
- package/dist/builder.js.map +0 -1
- package/dist/client.d.ts +0 -2
- package/dist/client.js +0 -424
- package/dist/client.js.map +0 -1
- package/dist/errors.d.ts +0 -124
- package/dist/errors.js +0 -201
- package/dist/errors.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,48 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nvisy/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Official TypeScript SDK for Nvisy document
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Official TypeScript SDK for Nvisy document processing platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
5
7
|
"keywords": [
|
|
6
8
|
"nvisy",
|
|
7
9
|
"document",
|
|
8
|
-
"
|
|
10
|
+
"privacy",
|
|
9
11
|
"sdk",
|
|
10
12
|
"api",
|
|
11
13
|
"typescript",
|
|
12
14
|
"client"
|
|
13
15
|
],
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
},
|
|
16
|
+
"author": "Nvisy <support@nvisy.com>",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"homepage": "https://github.com/nvisycom/sdk-ts#readme",
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/nvisycom/sdk.git"
|
|
21
|
+
"url": "git+https://github.com/nvisycom/sdk-ts.git"
|
|
21
22
|
},
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/nvisycom/sdk-ts/issues"
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
25
29
|
"exports": {
|
|
26
30
|
".": {
|
|
27
31
|
"types": "./dist/index.d.ts",
|
|
28
32
|
"import": "./dist/index.js"
|
|
29
33
|
},
|
|
30
|
-
"./
|
|
31
|
-
"types": "./dist/
|
|
32
|
-
"import": "./dist/
|
|
34
|
+
"./services": {
|
|
35
|
+
"types": "./dist/services/index.d.ts",
|
|
36
|
+
"import": "./dist/services/index.js"
|
|
33
37
|
},
|
|
34
|
-
"./
|
|
35
|
-
"types": "./dist/
|
|
36
|
-
"import": "./dist/
|
|
37
|
-
},
|
|
38
|
-
"./errors": {
|
|
39
|
-
"types": "./dist/errors.d.ts",
|
|
40
|
-
"import": "./dist/errors.js"
|
|
38
|
+
"./datatypes": {
|
|
39
|
+
"types": "./dist/datatypes/index.d.ts",
|
|
40
|
+
"import": "./dist/datatypes/index.js"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
-
"main": "./dist/index.js",
|
|
44
|
-
"module": "./dist/index.js",
|
|
45
|
-
"types": "./dist/index.d.ts",
|
|
46
43
|
"files": [
|
|
47
44
|
"dist",
|
|
48
45
|
"README.md",
|
|
@@ -67,21 +64,24 @@
|
|
|
67
64
|
"typecheck": "tsc --noEmit",
|
|
68
65
|
"clean": "rimraf dist",
|
|
69
66
|
"prepublishOnly": "npm run clean && npm run build && npm run test",
|
|
70
|
-
"release": "npm run prepublishOnly && npm publish"
|
|
67
|
+
"release": "npm run prepublishOnly && npm publish",
|
|
68
|
+
"generate": "openapi-typescript https://api.nvisy.com/openapi.json -o ./src/schema/api.d.ts",
|
|
69
|
+
"generate:local": "openapi-typescript http://127.0.0.1:8080/api/openapi.json -o ./src/schema/api.d.ts",
|
|
70
|
+
"generate:clean": "rimraf ./src/schema/api.d.ts"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"openapi-fetch": "^0.15.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@biomejs/biome": "^2.
|
|
77
|
-
"@types/node": "^
|
|
78
|
-
"@vitest/coverage-v8": "^
|
|
79
|
-
"@vitest/ui": "^
|
|
80
|
-
"openapi-typescript": "^7.
|
|
81
|
-
"rimraf": "^6.
|
|
82
|
-
"tsup": "^8.
|
|
76
|
+
"@biomejs/biome": "^2.3.10",
|
|
77
|
+
"@types/node": "^25.0.3",
|
|
78
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
79
|
+
"@vitest/ui": "^4.0.16",
|
|
80
|
+
"openapi-typescript": "^7.10.1",
|
|
81
|
+
"rimraf": "^6.1.2",
|
|
82
|
+
"tsup": "^8.5.1",
|
|
83
83
|
"typescript": "^5.9.3",
|
|
84
|
-
"vitest": "^
|
|
84
|
+
"vitest": "^4.0.16"
|
|
85
85
|
},
|
|
86
86
|
"engines": {
|
|
87
87
|
"node": ">=20.0.0"
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import createClient from 'openapi-fetch';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Configuration options for the Nvisy client
|
|
5
|
-
*/
|
|
6
|
-
interface ClientConfig {
|
|
7
|
-
/**
|
|
8
|
-
* API key for authentication
|
|
9
|
-
*/
|
|
10
|
-
apiKey: string;
|
|
11
|
-
/**
|
|
12
|
-
* Base URL for the Nvisy API
|
|
13
|
-
* @default "https://api.nvisy.com"
|
|
14
|
-
*/
|
|
15
|
-
baseUrl?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Request timeout in milliseconds
|
|
18
|
-
* @default 30000
|
|
19
|
-
*/
|
|
20
|
-
timeout?: number;
|
|
21
|
-
/**
|
|
22
|
-
* Maximum number of retry attempts for failed requests
|
|
23
|
-
* @default 3
|
|
24
|
-
*/
|
|
25
|
-
maxRetries?: number;
|
|
26
|
-
/**
|
|
27
|
-
* Custom headers to include with requests
|
|
28
|
-
*/
|
|
29
|
-
headers?: Record<string, string>;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Internal fully-resolved configuration
|
|
33
|
-
*/
|
|
34
|
-
type ResolvedClientConfig = Required<ClientConfig>;
|
|
35
|
-
/**
|
|
36
|
-
* Load configuration from environment variables
|
|
37
|
-
*/
|
|
38
|
-
declare function loadConfigFromEnv(): Partial<ClientConfig>;
|
|
39
|
-
/**
|
|
40
|
-
* Resolve configuration with defaults
|
|
41
|
-
*/
|
|
42
|
-
declare function resolveConfig(userConfig: ClientConfig): ResolvedClientConfig;
|
|
43
|
-
/**
|
|
44
|
-
* Get available environment variable names
|
|
45
|
-
*/
|
|
46
|
-
declare function getEnvironmentVariables(): Record<string, string>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Main client class for interacting with the Nvisy document redaction API
|
|
50
|
-
*/
|
|
51
|
-
declare class Client {
|
|
52
|
-
#private;
|
|
53
|
-
/**
|
|
54
|
-
* Create a new Nvisy client instance
|
|
55
|
-
*/
|
|
56
|
-
constructor(userConfig: ClientConfig);
|
|
57
|
-
/**
|
|
58
|
-
* Create a new ClientBuilder for fluent configuration
|
|
59
|
-
*/
|
|
60
|
-
static builder(): ClientBuilder;
|
|
61
|
-
/**
|
|
62
|
-
* Create a client from environment variables
|
|
63
|
-
*/
|
|
64
|
-
static fromEnvironment(): Client;
|
|
65
|
-
/**
|
|
66
|
-
* Get the current configuration (readonly copy)
|
|
67
|
-
*/
|
|
68
|
-
getConfig(): Readonly<ResolvedClientConfig>;
|
|
69
|
-
/**
|
|
70
|
-
* Get the underlying openapi-fetch client for advanced usage
|
|
71
|
-
*/
|
|
72
|
-
getOpenApiClient(): ReturnType<typeof createClient>;
|
|
73
|
-
/**
|
|
74
|
-
* Create a new client with modified configuration
|
|
75
|
-
*/
|
|
76
|
-
withConfig(configChanges: Partial<ClientConfig>): Client;
|
|
77
|
-
/**
|
|
78
|
-
* Create a new client with additional headers
|
|
79
|
-
*/
|
|
80
|
-
withHeaders(additionalHeaders: Record<string, string>): Client;
|
|
81
|
-
/**
|
|
82
|
-
* Create a new client with a different timeout
|
|
83
|
-
*/
|
|
84
|
-
withTimeout(timeoutMs: number): Client;
|
|
85
|
-
/**
|
|
86
|
-
* Create a new client with different retry settings
|
|
87
|
-
*/
|
|
88
|
-
withMaxRetries(maxRetries: number): Client;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Builder class for constructing client instances with a fluent API
|
|
93
|
-
*/
|
|
94
|
-
declare class ClientBuilder {
|
|
95
|
-
#private;
|
|
96
|
-
/**
|
|
97
|
-
* Create a ClientBuilder instance with an API key
|
|
98
|
-
*/
|
|
99
|
-
static fromApiKey(apiKey: string): ClientBuilder;
|
|
100
|
-
/**
|
|
101
|
-
* Create a ClientBuilder instance from environment variables
|
|
102
|
-
*/
|
|
103
|
-
static fromEnvironment(): ClientBuilder;
|
|
104
|
-
/**
|
|
105
|
-
* Set the API key for authentication
|
|
106
|
-
*/
|
|
107
|
-
withApiKey(apiKey: string): this;
|
|
108
|
-
/**
|
|
109
|
-
* Set the base URL for the API
|
|
110
|
-
*/
|
|
111
|
-
withBaseUrl(baseUrl: string): this;
|
|
112
|
-
/**
|
|
113
|
-
* Set the request timeout in milliseconds
|
|
114
|
-
*/
|
|
115
|
-
withTimeout(timeoutMs: number): this;
|
|
116
|
-
/**
|
|
117
|
-
* Set the maximum number of retry attempts
|
|
118
|
-
*/
|
|
119
|
-
withMaxRetries(maxRetries: number): this;
|
|
120
|
-
/**
|
|
121
|
-
* Add a single custom header (merges with existing headers)
|
|
122
|
-
*/
|
|
123
|
-
withHeader(name: string, value: string): this;
|
|
124
|
-
/**
|
|
125
|
-
* Set custom headers (merges with existing headers)
|
|
126
|
-
*/
|
|
127
|
-
withHeaders(headers: Record<string, string>): this;
|
|
128
|
-
/**
|
|
129
|
-
* Build and return the configured client instance
|
|
130
|
-
*/
|
|
131
|
-
build(): Client;
|
|
132
|
-
/**
|
|
133
|
-
* Get the current configuration (for debugging/testing)
|
|
134
|
-
*/
|
|
135
|
-
getConfig(): Readonly<Partial<ClientConfig>>;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export { ClientBuilder as C, type ResolvedClientConfig as R, Client as a, type ClientConfig as b, getEnvironmentVariables as g, loadConfigFromEnv as l, resolveConfig as r };
|
package/dist/builder.d.ts
DELETED
package/dist/builder.js
DELETED
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
import createClient from 'openapi-fetch';
|
|
2
|
-
|
|
3
|
-
// src/client.ts
|
|
4
|
-
|
|
5
|
-
// src/config.ts
|
|
6
|
-
var ENV_VARS = {
|
|
7
|
-
API_KEY: "NVISY_API_KEY",
|
|
8
|
-
BASE_URL: "NVISY_BASE_URL",
|
|
9
|
-
TIMEOUT: "NVISY_TIMEOUT",
|
|
10
|
-
MAX_RETRIES: "NVISY_MAX_RETRIES"
|
|
11
|
-
};
|
|
12
|
-
var DEFAULTS = {
|
|
13
|
-
baseUrl: "https://api.nvisy.com",
|
|
14
|
-
timeout: 3e4,
|
|
15
|
-
maxRetries: 3,
|
|
16
|
-
headers: {}
|
|
17
|
-
};
|
|
18
|
-
function loadConfigFromEnv() {
|
|
19
|
-
const config = {};
|
|
20
|
-
const apiKey = process.env[ENV_VARS.API_KEY];
|
|
21
|
-
if (apiKey) {
|
|
22
|
-
config.apiKey = apiKey;
|
|
23
|
-
}
|
|
24
|
-
const baseUrl = process.env[ENV_VARS.BASE_URL];
|
|
25
|
-
if (baseUrl) {
|
|
26
|
-
config.baseUrl = baseUrl;
|
|
27
|
-
}
|
|
28
|
-
const timeout = process.env[ENV_VARS.TIMEOUT];
|
|
29
|
-
if (timeout) {
|
|
30
|
-
const timeoutMs = parseInt(timeout, 10);
|
|
31
|
-
if (!Number.isNaN(timeoutMs)) {
|
|
32
|
-
config.timeout = timeoutMs;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const maxRetries = process.env[ENV_VARS.MAX_RETRIES];
|
|
36
|
-
if (maxRetries) {
|
|
37
|
-
const retries = parseInt(maxRetries, 10);
|
|
38
|
-
if (!Number.isNaN(retries)) {
|
|
39
|
-
config.maxRetries = retries;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return config;
|
|
43
|
-
}
|
|
44
|
-
function resolveConfig(userConfig) {
|
|
45
|
-
const envConfig = loadConfigFromEnv();
|
|
46
|
-
const mergedConfig = { ...envConfig, ...userConfig };
|
|
47
|
-
return {
|
|
48
|
-
apiKey: mergedConfig.apiKey || "",
|
|
49
|
-
baseUrl: mergedConfig.baseUrl || DEFAULTS.baseUrl,
|
|
50
|
-
timeout: mergedConfig.timeout ?? DEFAULTS.timeout,
|
|
51
|
-
maxRetries: mergedConfig.maxRetries ?? DEFAULTS.maxRetries,
|
|
52
|
-
headers: { ...DEFAULTS.headers, ...mergedConfig.headers }
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// src/errors.ts
|
|
57
|
-
var ClientError = class extends Error {
|
|
58
|
-
name;
|
|
59
|
-
constructor(message) {
|
|
60
|
-
super(message);
|
|
61
|
-
this.name = this.constructor.name;
|
|
62
|
-
if (Error.captureStackTrace) {
|
|
63
|
-
Error.captureStackTrace(this, this.constructor);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Convert error to JSON representation
|
|
68
|
-
*/
|
|
69
|
-
toJSON() {
|
|
70
|
-
return {
|
|
71
|
-
name: this.name,
|
|
72
|
-
message: this.message,
|
|
73
|
-
context: ""
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
var ConfigError = class _ConfigError extends ClientError {
|
|
78
|
-
/** Field that caused the error (for validation errors) */
|
|
79
|
-
field;
|
|
80
|
-
/** Reason why the configuration is invalid */
|
|
81
|
-
reason;
|
|
82
|
-
constructor(message, options) {
|
|
83
|
-
super(message);
|
|
84
|
-
this.field = options?.field;
|
|
85
|
-
this.reason = options?.reason;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Create error for missing API key
|
|
89
|
-
*/
|
|
90
|
-
static missingApiKey() {
|
|
91
|
-
return new _ConfigError("API key is required", {
|
|
92
|
-
field: "apiKey",
|
|
93
|
-
reason: "API key must be provided in configuration"
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Create error for invalid configuration field
|
|
98
|
-
*/
|
|
99
|
-
static invalidField(field, reason) {
|
|
100
|
-
return new _ConfigError(`Invalid configuration for ${field}: ${reason}`, {
|
|
101
|
-
field,
|
|
102
|
-
reason
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Create error for missing required field
|
|
107
|
-
*/
|
|
108
|
-
static missingField(field) {
|
|
109
|
-
return new _ConfigError(`Missing required configuration field: ${field}`, {
|
|
110
|
-
field,
|
|
111
|
-
reason: "This field is required"
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Convert error to JSON representation
|
|
116
|
-
*/
|
|
117
|
-
toJSON() {
|
|
118
|
-
return {
|
|
119
|
-
name: this.name,
|
|
120
|
-
message: this.message,
|
|
121
|
-
context: this.field || this.reason ? `field: ${this.field}, reason: ${this.reason}` : ""
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// src/client.ts
|
|
127
|
-
var Client = class _Client {
|
|
128
|
-
#config;
|
|
129
|
-
#openApiClient;
|
|
130
|
-
/**
|
|
131
|
-
* Create a new Nvisy client instance
|
|
132
|
-
*/
|
|
133
|
-
constructor(userConfig) {
|
|
134
|
-
try {
|
|
135
|
-
this.#validateConfig(userConfig);
|
|
136
|
-
this.#config = resolveConfig(userConfig);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
if (error instanceof ConfigError) {
|
|
139
|
-
throw error;
|
|
140
|
-
}
|
|
141
|
-
throw ConfigError.invalidField(
|
|
142
|
-
"config",
|
|
143
|
-
`Configuration error: ${String(error)}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
this.#openApiClient = createClient({
|
|
147
|
-
baseUrl: this.#config.baseUrl,
|
|
148
|
-
headers: {
|
|
149
|
-
Authorization: `Bearer ${this.#config.apiKey}`,
|
|
150
|
-
"Content-Type": "application/json",
|
|
151
|
-
"User-Agent": this.#buildUserAgent(),
|
|
152
|
-
...this.#config.headers
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Create a new ClientBuilder for fluent configuration
|
|
158
|
-
*/
|
|
159
|
-
static builder() {
|
|
160
|
-
return new ClientBuilder();
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Create a client from environment variables
|
|
164
|
-
*/
|
|
165
|
-
static fromEnvironment() {
|
|
166
|
-
return ClientBuilder.fromEnvironment().build();
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Get the current configuration (readonly copy)
|
|
170
|
-
*/
|
|
171
|
-
getConfig() {
|
|
172
|
-
return Object.freeze({ ...this.#config });
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Get the underlying openapi-fetch client for advanced usage
|
|
176
|
-
*/
|
|
177
|
-
getOpenApiClient() {
|
|
178
|
-
return this.#openApiClient;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Validate configuration by reusing ClientBuilder validation
|
|
182
|
-
*/
|
|
183
|
-
#validateConfig(config) {
|
|
184
|
-
const builder = new ClientBuilder().withApiKey(config.apiKey);
|
|
185
|
-
if (config.baseUrl !== void 0) {
|
|
186
|
-
builder.withBaseUrl(config.baseUrl);
|
|
187
|
-
}
|
|
188
|
-
if (config.timeout !== void 0) {
|
|
189
|
-
builder.withTimeout(config.timeout);
|
|
190
|
-
}
|
|
191
|
-
if (config.maxRetries !== void 0) {
|
|
192
|
-
builder.withMaxRetries(config.maxRetries);
|
|
193
|
-
}
|
|
194
|
-
if (config.headers !== void 0) {
|
|
195
|
-
builder.withHeaders(config.headers);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Build user agent string
|
|
200
|
-
*/
|
|
201
|
-
#buildUserAgent() {
|
|
202
|
-
const sdkVersion = "1.0.0";
|
|
203
|
-
const nodeVersion = process.version;
|
|
204
|
-
const platform = process.platform;
|
|
205
|
-
return `@nvisy/sdk/${sdkVersion} (${platform}; Node.js ${nodeVersion})`;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Create a new client with modified configuration
|
|
209
|
-
*/
|
|
210
|
-
withConfig(configChanges) {
|
|
211
|
-
const newConfig = {
|
|
212
|
-
apiKey: this.#config.apiKey,
|
|
213
|
-
baseUrl: this.#config.baseUrl,
|
|
214
|
-
timeout: this.#config.timeout,
|
|
215
|
-
maxRetries: this.#config.maxRetries,
|
|
216
|
-
headers: this.#config.headers,
|
|
217
|
-
...configChanges
|
|
218
|
-
};
|
|
219
|
-
return new _Client(newConfig);
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Create a new client with additional headers
|
|
223
|
-
*/
|
|
224
|
-
withHeaders(additionalHeaders) {
|
|
225
|
-
return this.withConfig({
|
|
226
|
-
headers: { ...this.#config.headers, ...additionalHeaders }
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Create a new client with a different timeout
|
|
231
|
-
*/
|
|
232
|
-
withTimeout(timeoutMs) {
|
|
233
|
-
return this.withConfig({ timeout: timeoutMs });
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Create a new client with different retry settings
|
|
237
|
-
*/
|
|
238
|
-
withMaxRetries(maxRetries) {
|
|
239
|
-
return this.withConfig({ maxRetries });
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
// src/builder.ts
|
|
244
|
-
var RESERVED_HEADERS = ["authorization", "content-type", "user-agent"];
|
|
245
|
-
var ClientBuilder = class _ClientBuilder {
|
|
246
|
-
#config = {};
|
|
247
|
-
/**
|
|
248
|
-
* Create a ClientBuilder instance with an API key
|
|
249
|
-
*/
|
|
250
|
-
static fromApiKey(apiKey) {
|
|
251
|
-
return new _ClientBuilder().withApiKey(apiKey);
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Create a ClientBuilder instance from environment variables
|
|
255
|
-
*/
|
|
256
|
-
static fromEnvironment() {
|
|
257
|
-
const envConfig = loadConfigFromEnv();
|
|
258
|
-
if (!envConfig.apiKey) {
|
|
259
|
-
throw ConfigError.missingApiKey();
|
|
260
|
-
}
|
|
261
|
-
const builder = new _ClientBuilder().withApiKey(envConfig.apiKey);
|
|
262
|
-
if (envConfig.baseUrl) {
|
|
263
|
-
builder.withBaseUrl(envConfig.baseUrl);
|
|
264
|
-
}
|
|
265
|
-
if (envConfig.timeout) {
|
|
266
|
-
builder.withTimeout(envConfig.timeout);
|
|
267
|
-
}
|
|
268
|
-
if (envConfig.maxRetries !== void 0) {
|
|
269
|
-
builder.withMaxRetries(envConfig.maxRetries);
|
|
270
|
-
}
|
|
271
|
-
if (envConfig.headers) {
|
|
272
|
-
builder.withHeaders(envConfig.headers);
|
|
273
|
-
}
|
|
274
|
-
return builder;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Set the API key for authentication
|
|
278
|
-
*/
|
|
279
|
-
withApiKey(apiKey) {
|
|
280
|
-
this.#validateString("apiKey", apiKey);
|
|
281
|
-
const trimmedKey = apiKey.trim();
|
|
282
|
-
if (trimmedKey.length < 10) {
|
|
283
|
-
throw ConfigError.invalidField(
|
|
284
|
-
"apiKey",
|
|
285
|
-
"must be at least 10 characters"
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(trimmedKey)) {
|
|
289
|
-
throw ConfigError.invalidField("apiKey", "contains invalid characters");
|
|
290
|
-
}
|
|
291
|
-
this.#config.apiKey = trimmedKey;
|
|
292
|
-
return this;
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Set the base URL for the API
|
|
296
|
-
*/
|
|
297
|
-
withBaseUrl(baseUrl) {
|
|
298
|
-
this.#validateString("baseUrl", baseUrl);
|
|
299
|
-
this.#validateUrl(baseUrl);
|
|
300
|
-
this.#config.baseUrl = baseUrl;
|
|
301
|
-
return this;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Set the request timeout in milliseconds
|
|
305
|
-
*/
|
|
306
|
-
withTimeout(timeoutMs) {
|
|
307
|
-
this.#validateInteger("timeout", timeoutMs, 1e3, 3e5);
|
|
308
|
-
this.#config.timeout = timeoutMs;
|
|
309
|
-
return this;
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Set the maximum number of retry attempts
|
|
313
|
-
*/
|
|
314
|
-
withMaxRetries(maxRetries) {
|
|
315
|
-
this.#validateInteger("maxRetries", maxRetries, 0, 5);
|
|
316
|
-
this.#config.maxRetries = maxRetries;
|
|
317
|
-
return this;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Add a single custom header (merges with existing headers)
|
|
321
|
-
*/
|
|
322
|
-
withHeader(name, value) {
|
|
323
|
-
this.#validateSingleHeader(name, value);
|
|
324
|
-
if (!this.#config.headers) {
|
|
325
|
-
this.#config.headers = {};
|
|
326
|
-
}
|
|
327
|
-
this.#config.headers[name] = value;
|
|
328
|
-
return this;
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Set custom headers (merges with existing headers)
|
|
332
|
-
*/
|
|
333
|
-
withHeaders(headers) {
|
|
334
|
-
if (!headers || typeof headers !== "object" || Array.isArray(headers)) {
|
|
335
|
-
throw ConfigError.invalidField("headers", "must be a valid object");
|
|
336
|
-
}
|
|
337
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
338
|
-
this.withHeader(name, value);
|
|
339
|
-
}
|
|
340
|
-
return this;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Build and return the configured client instance
|
|
344
|
-
*/
|
|
345
|
-
build() {
|
|
346
|
-
if (!this.#config.apiKey) {
|
|
347
|
-
throw ConfigError.missingApiKey();
|
|
348
|
-
}
|
|
349
|
-
return new Client(this.#config);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Get the current configuration (for debugging/testing)
|
|
353
|
-
*/
|
|
354
|
-
getConfig() {
|
|
355
|
-
return { ...this.#config };
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Validate string field
|
|
359
|
-
*/
|
|
360
|
-
#validateString(fieldName, value) {
|
|
361
|
-
if (!value || typeof value !== "string" || value.trim().length === 0) {
|
|
362
|
-
throw ConfigError.invalidField(fieldName, "must be a non-empty string");
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Validate integer field with range
|
|
367
|
-
*/
|
|
368
|
-
#validateInteger(fieldName, value, min, max) {
|
|
369
|
-
if (!Number.isInteger(value) || value < min) {
|
|
370
|
-
throw ConfigError.invalidField(fieldName, `must be an integer >= ${min}`);
|
|
371
|
-
}
|
|
372
|
-
if (value > max) {
|
|
373
|
-
throw ConfigError.invalidField(fieldName, `must not exceed ${max}`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Validate URL format
|
|
378
|
-
*/
|
|
379
|
-
#validateUrl(baseUrl) {
|
|
380
|
-
let url;
|
|
381
|
-
try {
|
|
382
|
-
url = new URL(baseUrl);
|
|
383
|
-
} catch {
|
|
384
|
-
throw ConfigError.invalidField("baseUrl", "must be a valid URL");
|
|
385
|
-
}
|
|
386
|
-
const allowedProtocols = ["https:", "http:"];
|
|
387
|
-
if (!allowedProtocols.includes(url.protocol)) {
|
|
388
|
-
throw ConfigError.invalidField(
|
|
389
|
-
"baseUrl",
|
|
390
|
-
`protocol must be one of: ${allowedProtocols.join(", ")}`
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Validate single header name and value
|
|
396
|
-
*/
|
|
397
|
-
#validateSingleHeader(name, value) {
|
|
398
|
-
if (!name || typeof name !== "string" || name.trim().length === 0) {
|
|
399
|
-
throw ConfigError.invalidField(
|
|
400
|
-
"header name",
|
|
401
|
-
"must be a non-empty string"
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
if (typeof value !== "string") {
|
|
405
|
-
throw ConfigError.invalidField("header value", "must be a string");
|
|
406
|
-
}
|
|
407
|
-
if (!/^[a-zA-Z0-9!#$%&'*+\-.^_`|~]+$/.test(name)) {
|
|
408
|
-
throw ConfigError.invalidField(
|
|
409
|
-
"header name",
|
|
410
|
-
`invalid header name: ${name}`
|
|
411
|
-
);
|
|
412
|
-
}
|
|
413
|
-
if (RESERVED_HEADERS.includes(name.toLowerCase())) {
|
|
414
|
-
throw ConfigError.invalidField(
|
|
415
|
-
"header name",
|
|
416
|
-
`header "${name}" is reserved and cannot be overridden`
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
export { ClientBuilder };
|
|
423
|
-
//# sourceMappingURL=builder.js.map
|
|
424
|
-
//# sourceMappingURL=builder.js.map
|