docwal-sdk 1.0.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 +47 -0
- package/LICENSE +21 -0
- package/README.md +409 -0
- package/dist/index.d.ts +250 -0
- package/dist/index.js +314 -0
- package/package.json +41 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the DocWal Node.js SDK will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2024-01-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of DocWal Node.js/TypeScript SDK
|
|
12
|
+
- Full TypeScript support with complete type definitions
|
|
13
|
+
- Credentials resource with full CRUD operations
|
|
14
|
+
- Template management (create, list, update, delete)
|
|
15
|
+
- Team member management (invite, list, update roles, deactivate, remove)
|
|
16
|
+
- API key management (generate, regenerate, revoke, info)
|
|
17
|
+
- Batch credential issuance (JSON array and ZIP upload)
|
|
18
|
+
- File upload support for PDF documents using FormData
|
|
19
|
+
- Comprehensive error handling with custom error classes
|
|
20
|
+
- Full documentation with TypeScript examples
|
|
21
|
+
- Express.js integration example
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
- Issue single credentials with optional PDF attachments
|
|
25
|
+
- Batch issue up to 1000 credentials at once
|
|
26
|
+
- Batch upload with ZIP files (CSV/JSON + PDFs)
|
|
27
|
+
- List and filter credentials with pagination
|
|
28
|
+
- Revoke credentials with audit trail
|
|
29
|
+
- Resend claim links with configurable expiration
|
|
30
|
+
- Download credential files as Buffer
|
|
31
|
+
- Manage credential templates with schema validation
|
|
32
|
+
- Team collaboration with role-based permissions
|
|
33
|
+
- Secure API key authentication
|
|
34
|
+
- Async/await pattern throughout
|
|
35
|
+
- Axios-based HTTP client with interceptors
|
|
36
|
+
|
|
37
|
+
### TypeScript
|
|
38
|
+
- Full type definitions included
|
|
39
|
+
- Interfaces for all request/response types
|
|
40
|
+
- Generic error types with proper inheritance
|
|
41
|
+
- IDE autocomplete support
|
|
42
|
+
|
|
43
|
+
### Security
|
|
44
|
+
- API key-based authentication
|
|
45
|
+
- HTTPS-only communication
|
|
46
|
+
- Input validation for all requests
|
|
47
|
+
- Proper error handling without leaking sensitive data
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 DocWal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# DocWal Node.js SDK
|
|
2
|
+
|
|
3
|
+
Official Node.js/TypeScript SDK for DocWal API - Issue and manage verifiable digital credentials.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install docwal-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { DocWalClient } from 'docwal-sdk';
|
|
15
|
+
|
|
16
|
+
// Initialize client
|
|
17
|
+
const client = new DocWalClient({
|
|
18
|
+
apiKey: 'docwal_live_xxxxx'
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Issue a credential
|
|
22
|
+
const result = await client.credentials.issue({
|
|
23
|
+
templateId: 'template-123',
|
|
24
|
+
individualEmail: 'student@example.com',
|
|
25
|
+
credentialData: {
|
|
26
|
+
student_name: 'John Doe',
|
|
27
|
+
degree: 'Bachelor of Science',
|
|
28
|
+
major: 'Computer Science',
|
|
29
|
+
graduation_date: '2024-05-15',
|
|
30
|
+
gpa: '3.8'
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
console.log(`Credential issued! Doc ID: ${result.doc_id}`);
|
|
35
|
+
console.log(`Claim token: ${result.claim_token}`);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Authentication
|
|
39
|
+
|
|
40
|
+
Get your API key from your DocWal dashboard:
|
|
41
|
+
1. Login to https://docwal.com
|
|
42
|
+
2. Navigate to Settings → API Keys
|
|
43
|
+
3. Click "Generate API Key"
|
|
44
|
+
4. Copy and store securely
|
|
45
|
+
|
|
46
|
+
**Requirements:**
|
|
47
|
+
- Pilot tier or above
|
|
48
|
+
- Owner or Admin role
|
|
49
|
+
|
|
50
|
+
## Environment Configuration
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// Production (default)
|
|
54
|
+
const client = new DocWalClient({
|
|
55
|
+
apiKey: 'docwal_live_xxxxx'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Staging
|
|
59
|
+
const client = new DocWalClient({
|
|
60
|
+
apiKey: 'docwal_test_xxxxx',
|
|
61
|
+
baseUrl: 'https://sandbox.docwal.com/api'
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Custom timeout
|
|
65
|
+
const client = new DocWalClient({
|
|
66
|
+
apiKey: 'docwal_live_xxxxx',
|
|
67
|
+
timeout: 60000 // milliseconds
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## TypeScript Support
|
|
72
|
+
|
|
73
|
+
Full TypeScript support with type definitions included:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import {
|
|
77
|
+
DocWalClient,
|
|
78
|
+
IssueCredentialParams,
|
|
79
|
+
IssueCredentialResponse,
|
|
80
|
+
Credential,
|
|
81
|
+
Template
|
|
82
|
+
} from 'docwal-sdk';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage Examples
|
|
86
|
+
|
|
87
|
+
### Issue Single Credential
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Basic credential
|
|
91
|
+
const result = await client.credentials.issue({
|
|
92
|
+
templateId: 'template-123',
|
|
93
|
+
individualEmail: 'student@example.com',
|
|
94
|
+
credentialData: {
|
|
95
|
+
student_name: 'John Doe',
|
|
96
|
+
degree: 'Bachelor of Science',
|
|
97
|
+
graduation_date: '2024-05-15'
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// With PDF attachment
|
|
102
|
+
import fs from 'fs';
|
|
103
|
+
|
|
104
|
+
const pdfBuffer = fs.readFileSync('certificate.pdf');
|
|
105
|
+
const result = await client.credentials.issue({
|
|
106
|
+
templateId: 'template-123',
|
|
107
|
+
individualEmail: 'student@example.com',
|
|
108
|
+
credentialData: { student_name: 'John Doe' },
|
|
109
|
+
documentFile: pdfBuffer,
|
|
110
|
+
claimTokenExpiresHours: 168 // 7 days
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Batch Issue Credentials
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const credentialsList = [
|
|
118
|
+
{
|
|
119
|
+
individual_email: 'student1@example.com',
|
|
120
|
+
credential_data: {
|
|
121
|
+
student_name: 'Alice Smith',
|
|
122
|
+
degree: 'Bachelor of Arts',
|
|
123
|
+
graduation_date: '2024-05-15'
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
individual_email: 'student2@example.com',
|
|
128
|
+
credential_data: {
|
|
129
|
+
student_name: 'Bob Johnson',
|
|
130
|
+
degree: 'Bachelor of Science',
|
|
131
|
+
graduation_date: '2024-05-15'
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const result = await client.credentials.batchIssue(
|
|
137
|
+
'template-123',
|
|
138
|
+
credentialsList,
|
|
139
|
+
true // send notifications
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
console.log(`Success: ${result.success_count}/${result.total_rows}`);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Batch Upload with ZIP
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import fs from 'fs';
|
|
149
|
+
|
|
150
|
+
// ZIP structure:
|
|
151
|
+
// batch_credentials.zip
|
|
152
|
+
// ├── credentials.csv
|
|
153
|
+
// └── documents/
|
|
154
|
+
// ├── student001.pdf
|
|
155
|
+
// ├── student002.pdf
|
|
156
|
+
// └── student003.pdf
|
|
157
|
+
|
|
158
|
+
const zipBuffer = fs.readFileSync('batch_credentials.zip');
|
|
159
|
+
|
|
160
|
+
const result = await client.credentials.batchUpload(
|
|
161
|
+
'template-123',
|
|
162
|
+
zipBuffer,
|
|
163
|
+
true // send notifications
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
console.log(`Processed: ${result.total_rows}`);
|
|
167
|
+
console.log(`Success: ${result.success_count}`);
|
|
168
|
+
console.log(`Failed: ${result.failure_count}`);
|
|
169
|
+
|
|
170
|
+
for (const item of result.results) {
|
|
171
|
+
if (item.status === 'success') {
|
|
172
|
+
console.log(`Row ${item.row}: ${item.doc_id}`);
|
|
173
|
+
} else {
|
|
174
|
+
console.log(`Row ${item.row}: ${item.error}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### List and Get Credentials
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// List all credentials
|
|
183
|
+
const credentials = await client.credentials.list(50, 0);
|
|
184
|
+
|
|
185
|
+
for (const cred of credentials) {
|
|
186
|
+
console.log(`${cred.doc_id}: ${cred.template_name}`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Get specific credential
|
|
190
|
+
const credential = await client.credentials.get('DOC123456');
|
|
191
|
+
console.log(`Issued to: ${credential.ownership?.individual_email}`);
|
|
192
|
+
console.log(`Status: ${credential.ownership?.is_claimed ? 'Claimed' : 'Pending'}`);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Revoke Credential
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const result = await client.credentials.revoke(
|
|
199
|
+
'DOC123456',
|
|
200
|
+
'Student expelled for academic misconduct'
|
|
201
|
+
);
|
|
202
|
+
console.log(result.message);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Resend Claim Link
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const result = await client.credentials.resendClaimLink(
|
|
209
|
+
'DOC123456',
|
|
210
|
+
168 // 7 days
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
console.log(`Sent to: ${result.recipient_email}`);
|
|
214
|
+
console.log(`Expires: ${result.claim_token_expires}`);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Download Credential File
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import fs from 'fs';
|
|
221
|
+
|
|
222
|
+
// Download PDF file
|
|
223
|
+
const pdfBuffer = await client.credentials.download('DOC123456');
|
|
224
|
+
fs.writeFileSync('credential.pdf', pdfBuffer);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Template Management
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// List templates
|
|
231
|
+
const templates = await client.templates.list();
|
|
232
|
+
|
|
233
|
+
// Get template
|
|
234
|
+
const template = await client.templates.get('template-123');
|
|
235
|
+
|
|
236
|
+
// Create template
|
|
237
|
+
const template = await client.templates.create({
|
|
238
|
+
name: 'Bachelor Degree Certificate',
|
|
239
|
+
description: 'Template for bachelor degree graduation certificates',
|
|
240
|
+
credentialType: 'certificate',
|
|
241
|
+
schema: {
|
|
242
|
+
student_name: {
|
|
243
|
+
type: 'string',
|
|
244
|
+
required: true,
|
|
245
|
+
label: 'Student Name'
|
|
246
|
+
},
|
|
247
|
+
degree: {
|
|
248
|
+
type: 'string',
|
|
249
|
+
required: true,
|
|
250
|
+
label: 'Degree Program'
|
|
251
|
+
},
|
|
252
|
+
graduation_date: {
|
|
253
|
+
type: 'date',
|
|
254
|
+
required: true,
|
|
255
|
+
label: 'Graduation Date'
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
version: '1.0'
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Update template
|
|
262
|
+
await client.templates.update('template-123', {
|
|
263
|
+
description: 'Updated description'
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Delete template (soft delete)
|
|
267
|
+
await client.templates.delete('template-123');
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## API Key Management
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Generate new API key (Owner/Admin only)
|
|
274
|
+
const result = await client.apiKeys.generate();
|
|
275
|
+
console.log(`New API key: ${result.api_key}`);
|
|
276
|
+
console.log('⚠️ Store securely - shown only once!');
|
|
277
|
+
|
|
278
|
+
// Get API key info
|
|
279
|
+
const info = await client.apiKeys.info();
|
|
280
|
+
console.log(`Masked key: ${info.api_key_masked}`);
|
|
281
|
+
console.log(`Created: ${info.created_at}`);
|
|
282
|
+
console.log(`Last used: ${info.last_used_at}`);
|
|
283
|
+
|
|
284
|
+
// Regenerate API key
|
|
285
|
+
const result = await client.apiKeys.regenerate();
|
|
286
|
+
console.log(`New API key: ${result.api_key}`);
|
|
287
|
+
|
|
288
|
+
// Revoke API key
|
|
289
|
+
await client.apiKeys.revoke();
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Team Management
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// List team members
|
|
296
|
+
const team = await client.team.list();
|
|
297
|
+
console.log(`Active members: ${team.stats.active_members}`);
|
|
298
|
+
console.log(`Pending invitations: ${team.stats.pending_invitations}`);
|
|
299
|
+
|
|
300
|
+
// Check email before inviting
|
|
301
|
+
const check = await client.team.checkEmail('newmember@university.edu');
|
|
302
|
+
if (check.recommendation === 'add_directly') {
|
|
303
|
+
console.log('User exists - can add directly');
|
|
304
|
+
} else if (check.recommendation === 'send_invitation') {
|
|
305
|
+
console.log("User doesn't exist - must send invitation");
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Invite team member
|
|
309
|
+
const result = await client.team.invite({
|
|
310
|
+
email: 'newmember@university.edu',
|
|
311
|
+
role: 'issuer',
|
|
312
|
+
sendEmail: true
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// Update member role
|
|
316
|
+
await client.team.updateRole('member-123', 'admin');
|
|
317
|
+
|
|
318
|
+
// Deactivate member
|
|
319
|
+
await client.team.deactivate('member-123', 'Employee on leave');
|
|
320
|
+
|
|
321
|
+
// Reactivate member
|
|
322
|
+
await client.team.reactivate('member-123');
|
|
323
|
+
|
|
324
|
+
// Remove member permanently
|
|
325
|
+
await client.team.remove('member-123');
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Error Handling
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import {
|
|
332
|
+
DocWalClient,
|
|
333
|
+
AuthenticationError,
|
|
334
|
+
ValidationError,
|
|
335
|
+
NotFoundError,
|
|
336
|
+
RateLimitError
|
|
337
|
+
} from 'docwal-sdk';
|
|
338
|
+
|
|
339
|
+
const client = new DocWalClient({ apiKey: 'docwal_live_xxxxx' });
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
const result = await client.credentials.issue({
|
|
343
|
+
templateId: 'invalid-template',
|
|
344
|
+
individualEmail: 'student@example.com',
|
|
345
|
+
credentialData: {}
|
|
346
|
+
});
|
|
347
|
+
} catch (error) {
|
|
348
|
+
if (error instanceof AuthenticationError) {
|
|
349
|
+
console.error('Authentication failed:', error.message);
|
|
350
|
+
console.error('Check your API key');
|
|
351
|
+
} else if (error instanceof ValidationError) {
|
|
352
|
+
console.error('Validation error:', error.message);
|
|
353
|
+
console.error('Check required fields');
|
|
354
|
+
} else if (error instanceof NotFoundError) {
|
|
355
|
+
console.error('Resource not found:', error.message);
|
|
356
|
+
} else if (error instanceof RateLimitError) {
|
|
357
|
+
console.error('Rate limit exceeded');
|
|
358
|
+
} else {
|
|
359
|
+
console.error('Error:', error);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Rate Limits
|
|
365
|
+
|
|
366
|
+
- **Pilot**: 500 requests/hour
|
|
367
|
+
- **Standard**: 1,000 requests/hour
|
|
368
|
+
- **Enterprise**: Unlimited
|
|
369
|
+
|
|
370
|
+
When rate limit is exceeded, `RateLimitError` is thrown.
|
|
371
|
+
|
|
372
|
+
## Express.js Integration Example
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import express from 'express';
|
|
376
|
+
import { DocWalClient } from 'docwal-sdk';
|
|
377
|
+
|
|
378
|
+
const app = express();
|
|
379
|
+
const docwal = new DocWalClient({ apiKey: process.env.DOCWAL_API_KEY! });
|
|
380
|
+
|
|
381
|
+
app.use(express.json());
|
|
382
|
+
|
|
383
|
+
app.post('/api/issue-credential', async (req, res) => {
|
|
384
|
+
try {
|
|
385
|
+
const result = await docwal.credentials.issue({
|
|
386
|
+
templateId: req.body.template_id,
|
|
387
|
+
individualEmail: req.body.email,
|
|
388
|
+
credentialData: req.body.data
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
res.json({ success: true, data: result });
|
|
392
|
+
} catch (error) {
|
|
393
|
+
res.status(500).json({ success: false, error: error.message });
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
app.listen(3000);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Support
|
|
401
|
+
|
|
402
|
+
- **Email**: support@docwal.com
|
|
403
|
+
- **Documentation**: https://docs.docwal.com
|
|
404
|
+
- **API Reference**: https://docwal.com/api/docs
|
|
405
|
+
- **GitHub**: https://github.com/docwal/docwal-nodejs
|
|
406
|
+
|
|
407
|
+
## License
|
|
408
|
+
|
|
409
|
+
MIT License - see LICENSE file for details.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocWal Node.js SDK
|
|
3
|
+
*
|
|
4
|
+
* Official Node.js SDK for DocWal API - Issue and manage verifiable digital credentials.
|
|
5
|
+
*/
|
|
6
|
+
import { AxiosInstance } from 'axios';
|
|
7
|
+
import { Readable } from 'stream';
|
|
8
|
+
export interface DocWalConfig {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CredentialData {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
export interface IssueCredentialParams {
|
|
17
|
+
templateId: string;
|
|
18
|
+
individualEmail: string;
|
|
19
|
+
credentialData: CredentialData;
|
|
20
|
+
documentFile?: Buffer | Readable;
|
|
21
|
+
expiresAt?: string;
|
|
22
|
+
claimTokenExpiresHours?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface IssueCredentialResponse {
|
|
25
|
+
doc_id: string;
|
|
26
|
+
document_hash: string;
|
|
27
|
+
status: string;
|
|
28
|
+
claim_token: string;
|
|
29
|
+
}
|
|
30
|
+
export interface BatchCredential {
|
|
31
|
+
individual_email: string;
|
|
32
|
+
credential_data: CredentialData;
|
|
33
|
+
}
|
|
34
|
+
export interface BatchIssueResponse {
|
|
35
|
+
total_rows: number;
|
|
36
|
+
success_count: number;
|
|
37
|
+
failure_count: number;
|
|
38
|
+
results: Array<{
|
|
39
|
+
row: number;
|
|
40
|
+
status: string;
|
|
41
|
+
doc_id?: string;
|
|
42
|
+
error?: string;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
export interface Credential {
|
|
46
|
+
doc_id: string;
|
|
47
|
+
document_hash: string;
|
|
48
|
+
issued_at: string;
|
|
49
|
+
expires_at?: string;
|
|
50
|
+
is_revoked: boolean;
|
|
51
|
+
revoked_at?: string;
|
|
52
|
+
revocation_reason?: string;
|
|
53
|
+
template_name: string;
|
|
54
|
+
credential_data: CredentialData;
|
|
55
|
+
ownership?: {
|
|
56
|
+
individual_email: string;
|
|
57
|
+
is_claimed: boolean;
|
|
58
|
+
claimed_at?: string;
|
|
59
|
+
claim_token_expires?: string;
|
|
60
|
+
};
|
|
61
|
+
has_document_file: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface Template {
|
|
64
|
+
id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
description: string;
|
|
67
|
+
credential_type: string;
|
|
68
|
+
schema: Record<string, any>;
|
|
69
|
+
version: string;
|
|
70
|
+
is_active: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface TeamMember {
|
|
73
|
+
id: string;
|
|
74
|
+
user: {
|
|
75
|
+
email: string;
|
|
76
|
+
full_name: string;
|
|
77
|
+
};
|
|
78
|
+
role: 'owner' | 'admin' | 'issuer';
|
|
79
|
+
is_active: boolean;
|
|
80
|
+
created_at: string;
|
|
81
|
+
}
|
|
82
|
+
export declare class DocWalError extends Error {
|
|
83
|
+
statusCode?: number | undefined;
|
|
84
|
+
response?: any | undefined;
|
|
85
|
+
constructor(message: string, statusCode?: number | undefined, response?: any | undefined);
|
|
86
|
+
}
|
|
87
|
+
export declare class AuthenticationError extends DocWalError {
|
|
88
|
+
constructor(message: string, statusCode?: number, response?: any);
|
|
89
|
+
}
|
|
90
|
+
export declare class ValidationError extends DocWalError {
|
|
91
|
+
constructor(message: string, statusCode?: number, response?: any);
|
|
92
|
+
}
|
|
93
|
+
export declare class RateLimitError extends DocWalError {
|
|
94
|
+
constructor(message: string, statusCode?: number, response?: any);
|
|
95
|
+
}
|
|
96
|
+
export declare class NotFoundError extends DocWalError {
|
|
97
|
+
constructor(message: string, statusCode?: number, response?: any);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* DocWal API Client
|
|
101
|
+
*/
|
|
102
|
+
export declare class DocWalClient {
|
|
103
|
+
private client;
|
|
104
|
+
credentials: CredentialsResource;
|
|
105
|
+
templates: TemplatesResource;
|
|
106
|
+
apiKeys: APIKeysResource;
|
|
107
|
+
team: TeamResource;
|
|
108
|
+
constructor(config: DocWalConfig);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Credentials Resource
|
|
112
|
+
*/
|
|
113
|
+
declare class CredentialsResource {
|
|
114
|
+
private client;
|
|
115
|
+
constructor(client: AxiosInstance);
|
|
116
|
+
/**
|
|
117
|
+
* Issue a single credential
|
|
118
|
+
*/
|
|
119
|
+
issue(params: IssueCredentialParams): Promise<IssueCredentialResponse>;
|
|
120
|
+
/**
|
|
121
|
+
* Issue multiple credentials in batch
|
|
122
|
+
*/
|
|
123
|
+
batchIssue(templateId: string, credentials: BatchCredential[], sendNotifications?: boolean): Promise<BatchIssueResponse>;
|
|
124
|
+
/**
|
|
125
|
+
* Batch upload with ZIP file
|
|
126
|
+
*/
|
|
127
|
+
batchUpload(templateId: string, file: Buffer | Readable, sendNotifications?: boolean): Promise<BatchIssueResponse>;
|
|
128
|
+
/**
|
|
129
|
+
* List all credentials
|
|
130
|
+
*/
|
|
131
|
+
list(limit?: number, offset?: number): Promise<Credential[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Get credential by doc_id
|
|
134
|
+
*/
|
|
135
|
+
get(docId: string): Promise<Credential>;
|
|
136
|
+
/**
|
|
137
|
+
* Revoke credential
|
|
138
|
+
*/
|
|
139
|
+
revoke(docId: string, reason: string): Promise<{
|
|
140
|
+
message: string;
|
|
141
|
+
}>;
|
|
142
|
+
/**
|
|
143
|
+
* Resend claim link
|
|
144
|
+
*/
|
|
145
|
+
resendClaimLink(docId: string, claimTokenExpiresHours?: number): Promise<{
|
|
146
|
+
message: string;
|
|
147
|
+
claim_token: string;
|
|
148
|
+
claim_token_expires: string;
|
|
149
|
+
recipient_email: string;
|
|
150
|
+
}>;
|
|
151
|
+
/**
|
|
152
|
+
* Download credential file
|
|
153
|
+
*/
|
|
154
|
+
download(docId: string): Promise<Buffer>;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Templates Resource
|
|
158
|
+
*/
|
|
159
|
+
declare class TemplatesResource {
|
|
160
|
+
private client;
|
|
161
|
+
constructor(client: AxiosInstance);
|
|
162
|
+
list(): Promise<Template[]>;
|
|
163
|
+
get(templateId: string): Promise<Template>;
|
|
164
|
+
create(params: {
|
|
165
|
+
name: string;
|
|
166
|
+
description: string;
|
|
167
|
+
credentialType: string;
|
|
168
|
+
schema: Record<string, any>;
|
|
169
|
+
version?: string;
|
|
170
|
+
}): Promise<Template>;
|
|
171
|
+
update(templateId: string, updates: Partial<Template>): Promise<Template>;
|
|
172
|
+
delete(templateId: string): Promise<{
|
|
173
|
+
message: string;
|
|
174
|
+
}>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* API Keys Resource
|
|
178
|
+
*/
|
|
179
|
+
declare class APIKeysResource {
|
|
180
|
+
private client;
|
|
181
|
+
constructor(client: AxiosInstance);
|
|
182
|
+
generate(): Promise<{
|
|
183
|
+
api_key: string;
|
|
184
|
+
created_at: string;
|
|
185
|
+
warning: string;
|
|
186
|
+
}>;
|
|
187
|
+
info(): Promise<{
|
|
188
|
+
has_api_key: boolean;
|
|
189
|
+
api_key_masked?: string;
|
|
190
|
+
created_at?: string;
|
|
191
|
+
last_used_at?: string;
|
|
192
|
+
is_active: boolean;
|
|
193
|
+
}>;
|
|
194
|
+
regenerate(): Promise<{
|
|
195
|
+
api_key: string;
|
|
196
|
+
created_at: string;
|
|
197
|
+
warning: string;
|
|
198
|
+
}>;
|
|
199
|
+
revoke(): Promise<{
|
|
200
|
+
message: string;
|
|
201
|
+
revoked_at: string;
|
|
202
|
+
}>;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Team Resource
|
|
206
|
+
*/
|
|
207
|
+
declare class TeamResource {
|
|
208
|
+
private client;
|
|
209
|
+
constructor(client: AxiosInstance);
|
|
210
|
+
list(): Promise<{
|
|
211
|
+
members: TeamMember[];
|
|
212
|
+
pending_invitations: any[];
|
|
213
|
+
stats: {
|
|
214
|
+
total_members: number;
|
|
215
|
+
active_members: number;
|
|
216
|
+
tier_limit: number | null;
|
|
217
|
+
};
|
|
218
|
+
}>;
|
|
219
|
+
checkEmail(email: string): Promise<{
|
|
220
|
+
valid: boolean;
|
|
221
|
+
domain_matches: boolean;
|
|
222
|
+
user_exists: boolean;
|
|
223
|
+
is_already_member: boolean;
|
|
224
|
+
recommendation: string;
|
|
225
|
+
}>;
|
|
226
|
+
invite(params: {
|
|
227
|
+
email: string;
|
|
228
|
+
role?: 'owner' | 'admin' | 'issuer';
|
|
229
|
+
sendEmail?: boolean;
|
|
230
|
+
addDirectly?: boolean;
|
|
231
|
+
}): Promise<{
|
|
232
|
+
message: string;
|
|
233
|
+
invitation?: any;
|
|
234
|
+
member?: TeamMember;
|
|
235
|
+
}>;
|
|
236
|
+
updateRole(memberId: string, role: string): Promise<{
|
|
237
|
+
message: string;
|
|
238
|
+
member: TeamMember;
|
|
239
|
+
}>;
|
|
240
|
+
deactivate(memberId: string, reason?: string): Promise<{
|
|
241
|
+
message: string;
|
|
242
|
+
}>;
|
|
243
|
+
reactivate(memberId: string): Promise<{
|
|
244
|
+
message: string;
|
|
245
|
+
}>;
|
|
246
|
+
remove(memberId: string): Promise<{
|
|
247
|
+
message: string;
|
|
248
|
+
}>;
|
|
249
|
+
}
|
|
250
|
+
export default DocWalClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DocWal Node.js SDK
|
|
4
|
+
*
|
|
5
|
+
* Official Node.js SDK for DocWal API - Issue and manage verifiable digital credentials.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DocWalClient = exports.NotFoundError = exports.RateLimitError = exports.ValidationError = exports.AuthenticationError = exports.DocWalError = void 0;
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
14
|
+
// Errors
|
|
15
|
+
class DocWalError extends Error {
|
|
16
|
+
constructor(message, statusCode, response) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.statusCode = statusCode;
|
|
19
|
+
this.response = response;
|
|
20
|
+
this.name = 'DocWalError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.DocWalError = DocWalError;
|
|
24
|
+
class AuthenticationError extends DocWalError {
|
|
25
|
+
constructor(message, statusCode, response) {
|
|
26
|
+
super(message, statusCode, response);
|
|
27
|
+
this.name = 'AuthenticationError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.AuthenticationError = AuthenticationError;
|
|
31
|
+
class ValidationError extends DocWalError {
|
|
32
|
+
constructor(message, statusCode, response) {
|
|
33
|
+
super(message, statusCode, response);
|
|
34
|
+
this.name = 'ValidationError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.ValidationError = ValidationError;
|
|
38
|
+
class RateLimitError extends DocWalError {
|
|
39
|
+
constructor(message, statusCode, response) {
|
|
40
|
+
super(message, statusCode, response);
|
|
41
|
+
this.name = 'RateLimitError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.RateLimitError = RateLimitError;
|
|
45
|
+
class NotFoundError extends DocWalError {
|
|
46
|
+
constructor(message, statusCode, response) {
|
|
47
|
+
super(message, statusCode, response);
|
|
48
|
+
this.name = 'NotFoundError';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.NotFoundError = NotFoundError;
|
|
52
|
+
/**
|
|
53
|
+
* DocWal API Client
|
|
54
|
+
*/
|
|
55
|
+
class DocWalClient {
|
|
56
|
+
constructor(config) {
|
|
57
|
+
const { apiKey, baseUrl = 'https://docwal.com/api', timeout = 30000 } = config;
|
|
58
|
+
this.client = axios_1.default.create({
|
|
59
|
+
baseURL: baseUrl,
|
|
60
|
+
timeout,
|
|
61
|
+
headers: {
|
|
62
|
+
'X-API-Key': apiKey,
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
// Error interceptor
|
|
67
|
+
this.client.interceptors.response.use((response) => response, (error) => {
|
|
68
|
+
if (error.response) {
|
|
69
|
+
const status = error.response.status;
|
|
70
|
+
const data = error.response.data;
|
|
71
|
+
const message = data?.error || error.message;
|
|
72
|
+
if (status === 401) {
|
|
73
|
+
throw new AuthenticationError(message, status, error.response);
|
|
74
|
+
}
|
|
75
|
+
else if (status === 400) {
|
|
76
|
+
throw new ValidationError(message, status, error.response);
|
|
77
|
+
}
|
|
78
|
+
else if (status === 404) {
|
|
79
|
+
throw new NotFoundError(message, status, error.response);
|
|
80
|
+
}
|
|
81
|
+
else if (status === 429) {
|
|
82
|
+
throw new RateLimitError(message, status, error.response);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
throw new DocWalError(message, status, error.response);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (error.request) {
|
|
89
|
+
throw new DocWalError('No response from server');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw new DocWalError(error.message);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Initialize resources
|
|
96
|
+
this.credentials = new CredentialsResource(this.client);
|
|
97
|
+
this.templates = new TemplatesResource(this.client);
|
|
98
|
+
this.apiKeys = new APIKeysResource(this.client);
|
|
99
|
+
this.team = new TeamResource(this.client);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.DocWalClient = DocWalClient;
|
|
103
|
+
/**
|
|
104
|
+
* Credentials Resource
|
|
105
|
+
*/
|
|
106
|
+
class CredentialsResource {
|
|
107
|
+
constructor(client) {
|
|
108
|
+
this.client = client;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Issue a single credential
|
|
112
|
+
*/
|
|
113
|
+
async issue(params) {
|
|
114
|
+
const { templateId, individualEmail, credentialData, documentFile, expiresAt, claimTokenExpiresHours = 720, } = params;
|
|
115
|
+
if (documentFile) {
|
|
116
|
+
const formData = new form_data_1.default();
|
|
117
|
+
formData.append('template_id', templateId);
|
|
118
|
+
formData.append('individual_email', individualEmail);
|
|
119
|
+
formData.append('credential_data', JSON.stringify(credentialData));
|
|
120
|
+
formData.append('claim_token_expires_hours', claimTokenExpiresHours.toString());
|
|
121
|
+
if (expiresAt) {
|
|
122
|
+
formData.append('expires_at', expiresAt);
|
|
123
|
+
}
|
|
124
|
+
formData.append('document_file', documentFile, 'document.pdf');
|
|
125
|
+
const response = await this.client.post('/credentials/issue/', formData, {
|
|
126
|
+
headers: formData.getHeaders(),
|
|
127
|
+
});
|
|
128
|
+
return response.data;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const response = await this.client.post('/credentials/issue/', {
|
|
132
|
+
template_id: templateId,
|
|
133
|
+
individual_email: individualEmail,
|
|
134
|
+
credential_data: credentialData,
|
|
135
|
+
claim_token_expires_hours: claimTokenExpiresHours,
|
|
136
|
+
...(expiresAt && { expires_at: expiresAt }),
|
|
137
|
+
});
|
|
138
|
+
return response.data;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Issue multiple credentials in batch
|
|
143
|
+
*/
|
|
144
|
+
async batchIssue(templateId, credentials, sendNotifications = true) {
|
|
145
|
+
const response = await this.client.post('/credentials/batch/', {
|
|
146
|
+
template_id: templateId,
|
|
147
|
+
credentials,
|
|
148
|
+
send_notifications: sendNotifications,
|
|
149
|
+
});
|
|
150
|
+
return response.data;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Batch upload with ZIP file
|
|
154
|
+
*/
|
|
155
|
+
async batchUpload(templateId, file, sendNotifications = true) {
|
|
156
|
+
const formData = new form_data_1.default();
|
|
157
|
+
formData.append('template_id', templateId);
|
|
158
|
+
formData.append('send_notifications', sendNotifications.toString());
|
|
159
|
+
formData.append('file', file, 'batch.zip');
|
|
160
|
+
const response = await this.client.post('/credentials/batch-upload/', formData, {
|
|
161
|
+
headers: formData.getHeaders(),
|
|
162
|
+
});
|
|
163
|
+
return response.data;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* List all credentials
|
|
167
|
+
*/
|
|
168
|
+
async list(limit = 100, offset = 0) {
|
|
169
|
+
const response = await this.client.get('/credentials/', {
|
|
170
|
+
params: { limit, offset },
|
|
171
|
+
});
|
|
172
|
+
return response.data;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get credential by doc_id
|
|
176
|
+
*/
|
|
177
|
+
async get(docId) {
|
|
178
|
+
const response = await this.client.get(`/credentials/${docId}/`);
|
|
179
|
+
return response.data;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Revoke credential
|
|
183
|
+
*/
|
|
184
|
+
async revoke(docId, reason) {
|
|
185
|
+
const response = await this.client.post(`/credentials/${docId}/revoke/`, {
|
|
186
|
+
reason,
|
|
187
|
+
});
|
|
188
|
+
return response.data;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Resend claim link
|
|
192
|
+
*/
|
|
193
|
+
async resendClaimLink(docId, claimTokenExpiresHours = 720) {
|
|
194
|
+
const response = await this.client.post(`/credentials/${docId}/resend-claim/`, {
|
|
195
|
+
claim_token_expires_hours: claimTokenExpiresHours,
|
|
196
|
+
});
|
|
197
|
+
return response.data;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Download credential file
|
|
201
|
+
*/
|
|
202
|
+
async download(docId) {
|
|
203
|
+
const response = await this.client.get(`/credentials/${docId}/download/`, {
|
|
204
|
+
responseType: 'arraybuffer',
|
|
205
|
+
});
|
|
206
|
+
return Buffer.from(response.data);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Templates Resource
|
|
211
|
+
*/
|
|
212
|
+
class TemplatesResource {
|
|
213
|
+
constructor(client) {
|
|
214
|
+
this.client = client;
|
|
215
|
+
}
|
|
216
|
+
async list() {
|
|
217
|
+
const response = await this.client.get('/templates/');
|
|
218
|
+
return response.data;
|
|
219
|
+
}
|
|
220
|
+
async get(templateId) {
|
|
221
|
+
const response = await this.client.get(`/templates/${templateId}/`);
|
|
222
|
+
return response.data;
|
|
223
|
+
}
|
|
224
|
+
async create(params) {
|
|
225
|
+
const response = await this.client.post('/templates/', {
|
|
226
|
+
name: params.name,
|
|
227
|
+
description: params.description,
|
|
228
|
+
credential_type: params.credentialType,
|
|
229
|
+
schema: params.schema,
|
|
230
|
+
version: params.version || '1.0',
|
|
231
|
+
});
|
|
232
|
+
return response.data;
|
|
233
|
+
}
|
|
234
|
+
async update(templateId, updates) {
|
|
235
|
+
const response = await this.client.patch(`/templates/${templateId}/`, updates);
|
|
236
|
+
return response.data;
|
|
237
|
+
}
|
|
238
|
+
async delete(templateId) {
|
|
239
|
+
const response = await this.client.delete(`/templates/${templateId}/`);
|
|
240
|
+
return response.data;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* API Keys Resource
|
|
245
|
+
*/
|
|
246
|
+
class APIKeysResource {
|
|
247
|
+
constructor(client) {
|
|
248
|
+
this.client = client;
|
|
249
|
+
}
|
|
250
|
+
async generate() {
|
|
251
|
+
const response = await this.client.post('/institutions/api-keys/generate/');
|
|
252
|
+
return response.data;
|
|
253
|
+
}
|
|
254
|
+
async info() {
|
|
255
|
+
const response = await this.client.get('/institutions/api-keys/info/');
|
|
256
|
+
return response.data;
|
|
257
|
+
}
|
|
258
|
+
async regenerate() {
|
|
259
|
+
const response = await this.client.post('/institutions/api-keys/regenerate/');
|
|
260
|
+
return response.data;
|
|
261
|
+
}
|
|
262
|
+
async revoke() {
|
|
263
|
+
const response = await this.client.post('/institutions/api-keys/revoke/');
|
|
264
|
+
return response.data;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Team Resource
|
|
269
|
+
*/
|
|
270
|
+
class TeamResource {
|
|
271
|
+
constructor(client) {
|
|
272
|
+
this.client = client;
|
|
273
|
+
}
|
|
274
|
+
async list() {
|
|
275
|
+
const response = await this.client.get('/institutions/team/');
|
|
276
|
+
return response.data;
|
|
277
|
+
}
|
|
278
|
+
async checkEmail(email) {
|
|
279
|
+
const response = await this.client.post('/institutions/team/check-email/', {
|
|
280
|
+
email,
|
|
281
|
+
});
|
|
282
|
+
return response.data;
|
|
283
|
+
}
|
|
284
|
+
async invite(params) {
|
|
285
|
+
const response = await this.client.post('/institutions/team/invite/', {
|
|
286
|
+
email: params.email,
|
|
287
|
+
role: params.role || 'issuer',
|
|
288
|
+
send_email: params.sendEmail !== false,
|
|
289
|
+
add_directly: params.addDirectly || false,
|
|
290
|
+
});
|
|
291
|
+
return response.data;
|
|
292
|
+
}
|
|
293
|
+
async updateRole(memberId, role) {
|
|
294
|
+
const response = await this.client.patch(`/institutions/team/members/${memberId}/role/`, {
|
|
295
|
+
role,
|
|
296
|
+
});
|
|
297
|
+
return response.data;
|
|
298
|
+
}
|
|
299
|
+
async deactivate(memberId, reason) {
|
|
300
|
+
const response = await this.client.post(`/institutions/team/members/${memberId}/deactivate/`, {
|
|
301
|
+
...(reason && { reason }),
|
|
302
|
+
});
|
|
303
|
+
return response.data;
|
|
304
|
+
}
|
|
305
|
+
async reactivate(memberId) {
|
|
306
|
+
const response = await this.client.post(`/institutions/team/members/${memberId}/reactivate/`);
|
|
307
|
+
return response.data;
|
|
308
|
+
}
|
|
309
|
+
async remove(memberId) {
|
|
310
|
+
const response = await this.client.delete(`/institutions/team/members/${memberId}/remove/`);
|
|
311
|
+
return response.data;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
exports.default = DocWalClient;
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "docwal-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official Node.js SDK for DocWal API - Issue and manage verifiable digital credentials",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublishOnly": "npm run build",
|
|
10
|
+
"test": "jest"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"docwal",
|
|
14
|
+
"credentials",
|
|
15
|
+
"verifiable",
|
|
16
|
+
"digital",
|
|
17
|
+
"education",
|
|
18
|
+
"blockchain"
|
|
19
|
+
],
|
|
20
|
+
"author": "DocWal <support@docwal.com>",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/docwal/docwal-nodejs"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/docwal/docwal-nodejs/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://docs.docwal.com",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"axios": "^1.6.0",
|
|
32
|
+
"form-data": "^4.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"typescript": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=14.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|