@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/package.json CHANGED
@@ -1,48 +1,45 @@
1
1
  {
2
2
  "name": "@nvisy/sdk",
3
- "version": "0.1.0",
4
- "description": "Official TypeScript SDK for Nvisy document redaction platform",
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
- "redaction",
10
+ "privacy",
9
11
  "sdk",
10
12
  "api",
11
13
  "typescript",
12
14
  "client"
13
15
  ],
14
- "homepage": "https://github.com/nvisycom/sdk#readme",
15
- "bugs": {
16
- "url": "https://github.com/nvisycom/sdk/issues"
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
- "license": "MIT",
23
- "author": "Nvisy <support@nvisy.com>",
24
- "type": "module",
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
- "./client": {
31
- "types": "./dist/client.d.ts",
32
- "import": "./dist/client.js"
34
+ "./services": {
35
+ "types": "./dist/services/index.d.ts",
36
+ "import": "./dist/services/index.js"
33
37
  },
34
- "./builder": {
35
- "types": "./dist/builder.d.ts",
36
- "import": "./dist/builder.js"
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.2.6",
77
- "@types/node": "^24.7.2",
78
- "@vitest/coverage-v8": "^3.2.4",
79
- "@vitest/ui": "^3.2.4",
80
- "openapi-typescript": "^7.9.1",
81
- "rimraf": "^6.0.1",
82
- "tsup": "^8.0.1",
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": "^3.2.4"
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
@@ -1,2 +0,0 @@
1
- export { C as ClientBuilder } from './builder-BEUIGfoZ.js';
2
- import 'openapi-fetch';
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