@scell/sdk 1.0.0 → 1.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/README.md +73 -3
- package/dist/index.d.mts +252 -3
- package/dist/index.d.ts +252 -3
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +76 -0
- package/src/resources/invoices.ts +217 -0
- package/src/types/index.ts +9 -0
- package/src/types/invoices.ts +91 -0
- package/src/types/webhooks.ts +30 -1
package/dist/index.mjs
CHANGED
|
@@ -401,6 +401,60 @@ var HttpClient = class {
|
|
|
401
401
|
...options
|
|
402
402
|
});
|
|
403
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* GET request that returns raw binary data as ArrayBuffer
|
|
406
|
+
*
|
|
407
|
+
* Use this for downloading files (PDF, XML, etc.)
|
|
408
|
+
*
|
|
409
|
+
* @param path - API endpoint path
|
|
410
|
+
* @param query - Query parameters
|
|
411
|
+
* @param options - Request options
|
|
412
|
+
* @returns ArrayBuffer containing the file content
|
|
413
|
+
*/
|
|
414
|
+
async getRaw(path, query, options) {
|
|
415
|
+
const url = this.buildUrl(path, query);
|
|
416
|
+
const requestHeaders = this.buildHeaders(options?.headers);
|
|
417
|
+
const requestTimeout = options?.timeout ?? this.timeout;
|
|
418
|
+
delete requestHeaders["Content-Type"];
|
|
419
|
+
requestHeaders["Accept"] = "*/*";
|
|
420
|
+
const controller = new AbortController();
|
|
421
|
+
const timeoutId = setTimeout(() => controller.abort(), requestTimeout);
|
|
422
|
+
if (options?.signal) {
|
|
423
|
+
options.signal.addEventListener("abort", () => controller.abort());
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
const response = await this.fetchFn(url, {
|
|
427
|
+
method: "GET",
|
|
428
|
+
headers: requestHeaders,
|
|
429
|
+
signal: controller.signal
|
|
430
|
+
});
|
|
431
|
+
clearTimeout(timeoutId);
|
|
432
|
+
if (!response.ok) {
|
|
433
|
+
const contentType = response.headers.get("Content-Type") ?? "";
|
|
434
|
+
let responseBody;
|
|
435
|
+
if (contentType.includes("application/json")) {
|
|
436
|
+
responseBody = await response.json();
|
|
437
|
+
} else {
|
|
438
|
+
responseBody = await response.text();
|
|
439
|
+
}
|
|
440
|
+
parseApiError(response.status, responseBody, response.headers);
|
|
441
|
+
}
|
|
442
|
+
return response.arrayBuffer();
|
|
443
|
+
} catch (error) {
|
|
444
|
+
clearTimeout(timeoutId);
|
|
445
|
+
if (error instanceof Error) {
|
|
446
|
+
if (error.name === "AbortError") {
|
|
447
|
+
throw new ScellTimeoutError(
|
|
448
|
+
`Request timed out after ${requestTimeout}ms`
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
if (error.name === "TypeError" && error.message.includes("fetch")) {
|
|
452
|
+
throw new ScellNetworkError("Network request failed", error);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
throw error;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
404
458
|
};
|
|
405
459
|
|
|
406
460
|
// src/resources/api-keys.ts
|
|
@@ -1135,6 +1189,188 @@ var InvoicesResource = class {
|
|
|
1135
1189
|
async convert(input, requestOptions) {
|
|
1136
1190
|
return this.http.post("/invoices/convert", input, requestOptions);
|
|
1137
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* List incoming invoices (from suppliers)
|
|
1194
|
+
*
|
|
1195
|
+
* Returns invoices where your company is the buyer.
|
|
1196
|
+
*
|
|
1197
|
+
* @param params - Filter and pagination options
|
|
1198
|
+
* @param requestOptions - Request options
|
|
1199
|
+
* @returns Paginated list of incoming invoices
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* ```typescript
|
|
1203
|
+
* // List all incoming invoices
|
|
1204
|
+
* const { data, meta } = await client.invoices.incoming({
|
|
1205
|
+
* status: 'pending',
|
|
1206
|
+
* per_page: 50
|
|
1207
|
+
* });
|
|
1208
|
+
* console.log(`Found ${meta.total} incoming invoices`);
|
|
1209
|
+
*
|
|
1210
|
+
* // Filter by seller
|
|
1211
|
+
* const fromSupplier = await client.invoices.incoming({
|
|
1212
|
+
* seller_siret: '12345678901234'
|
|
1213
|
+
* });
|
|
1214
|
+
* ```
|
|
1215
|
+
*/
|
|
1216
|
+
async incoming(params = {}, requestOptions) {
|
|
1217
|
+
return this.http.get(
|
|
1218
|
+
"/invoices/incoming",
|
|
1219
|
+
params,
|
|
1220
|
+
requestOptions
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Accept an incoming invoice
|
|
1225
|
+
*
|
|
1226
|
+
* Mark an incoming invoice as accepted, optionally specifying a payment date.
|
|
1227
|
+
*
|
|
1228
|
+
* @param id - Invoice UUID
|
|
1229
|
+
* @param data - Optional acceptance data
|
|
1230
|
+
* @param requestOptions - Request options
|
|
1231
|
+
* @returns Updated invoice
|
|
1232
|
+
*
|
|
1233
|
+
* @example
|
|
1234
|
+
* ```typescript
|
|
1235
|
+
* // Accept with payment date
|
|
1236
|
+
* const { data: invoice } = await client.invoices.accept('invoice-uuid', {
|
|
1237
|
+
* payment_date: '2024-02-15',
|
|
1238
|
+
* note: 'Approved by accounting'
|
|
1239
|
+
* });
|
|
1240
|
+
*
|
|
1241
|
+
* // Simple acceptance
|
|
1242
|
+
* await client.invoices.accept('invoice-uuid');
|
|
1243
|
+
* ```
|
|
1244
|
+
*/
|
|
1245
|
+
async accept(id, data, requestOptions) {
|
|
1246
|
+
return this.http.post(
|
|
1247
|
+
`/invoices/${id}/accept`,
|
|
1248
|
+
data,
|
|
1249
|
+
requestOptions
|
|
1250
|
+
);
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Reject an incoming invoice
|
|
1254
|
+
*
|
|
1255
|
+
* Mark an incoming invoice as rejected with a reason.
|
|
1256
|
+
*
|
|
1257
|
+
* @param id - Invoice UUID
|
|
1258
|
+
* @param data - Rejection details
|
|
1259
|
+
* @param requestOptions - Request options
|
|
1260
|
+
* @returns Updated invoice
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```typescript
|
|
1264
|
+
* const { data: invoice } = await client.invoices.reject('invoice-uuid', {
|
|
1265
|
+
* reason: 'Invoice amount does not match purchase order',
|
|
1266
|
+
* reason_code: 'incorrect_amount'
|
|
1267
|
+
* });
|
|
1268
|
+
* ```
|
|
1269
|
+
*/
|
|
1270
|
+
async reject(id, data, requestOptions) {
|
|
1271
|
+
return this.http.post(
|
|
1272
|
+
`/invoices/${id}/reject`,
|
|
1273
|
+
data,
|
|
1274
|
+
requestOptions
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Dispute an incoming invoice
|
|
1279
|
+
*
|
|
1280
|
+
* Open a dispute on an incoming invoice for resolution.
|
|
1281
|
+
*
|
|
1282
|
+
* @param id - Invoice UUID
|
|
1283
|
+
* @param data - Dispute details
|
|
1284
|
+
* @param requestOptions - Request options
|
|
1285
|
+
* @returns Updated invoice
|
|
1286
|
+
*
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```typescript
|
|
1289
|
+
* const { data: invoice } = await client.invoices.dispute('invoice-uuid', {
|
|
1290
|
+
* reason: 'Billed amount exceeds agreed price',
|
|
1291
|
+
* dispute_type: 'amount_dispute',
|
|
1292
|
+
* expected_amount: 950.00
|
|
1293
|
+
* });
|
|
1294
|
+
* ```
|
|
1295
|
+
*/
|
|
1296
|
+
async dispute(id, data, requestOptions) {
|
|
1297
|
+
return this.http.post(
|
|
1298
|
+
`/invoices/${id}/dispute`,
|
|
1299
|
+
data,
|
|
1300
|
+
requestOptions
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Mark an incoming invoice as paid
|
|
1305
|
+
*
|
|
1306
|
+
* This is a mandatory step in the French e-invoicing lifecycle for incoming invoices.
|
|
1307
|
+
* Once marked as paid, the invoice status changes to 'paid' and payment details are recorded.
|
|
1308
|
+
*
|
|
1309
|
+
* @param id - Invoice UUID
|
|
1310
|
+
* @param data - Optional payment details (reference, date, note)
|
|
1311
|
+
* @param requestOptions - Request options
|
|
1312
|
+
* @returns Updated invoice with payment information
|
|
1313
|
+
*
|
|
1314
|
+
* @example
|
|
1315
|
+
* ```typescript
|
|
1316
|
+
* // Mark as paid with payment details
|
|
1317
|
+
* const { data: invoice } = await client.invoices.markPaid('invoice-uuid', {
|
|
1318
|
+
* payment_reference: 'VIR-2026-0124',
|
|
1319
|
+
* paid_at: '2026-01-24T10:30:00Z',
|
|
1320
|
+
* note: 'Payment received via bank transfer'
|
|
1321
|
+
* });
|
|
1322
|
+
*
|
|
1323
|
+
* // Simple mark as paid (uses current date/time)
|
|
1324
|
+
* await client.invoices.markPaid('invoice-uuid');
|
|
1325
|
+
* ```
|
|
1326
|
+
*/
|
|
1327
|
+
async markPaid(id, data, requestOptions) {
|
|
1328
|
+
return this.http.post(
|
|
1329
|
+
`/invoices/${id}/mark-paid`,
|
|
1330
|
+
data,
|
|
1331
|
+
requestOptions
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Download invoice source file as binary content
|
|
1336
|
+
*
|
|
1337
|
+
* Downloads the original invoice file (PDF with embedded XML for Factur-X,
|
|
1338
|
+
* or standalone XML for UBL/CII formats).
|
|
1339
|
+
*
|
|
1340
|
+
* @param id - Invoice UUID
|
|
1341
|
+
* @param format - File format to download: 'pdf' (default) or 'xml'
|
|
1342
|
+
* @param requestOptions - Request options
|
|
1343
|
+
* @returns ArrayBuffer containing the file content
|
|
1344
|
+
*
|
|
1345
|
+
* @example
|
|
1346
|
+
* ```typescript
|
|
1347
|
+
* // Download invoice as PDF (Factur-X)
|
|
1348
|
+
* const pdfBuffer = await client.invoices.downloadFile('invoice-uuid');
|
|
1349
|
+
*
|
|
1350
|
+
* // In Node.js, save to file:
|
|
1351
|
+
* import { writeFileSync } from 'fs';
|
|
1352
|
+
* writeFileSync('invoice.pdf', Buffer.from(pdfBuffer));
|
|
1353
|
+
*
|
|
1354
|
+
* // Download XML version (UBL/CII)
|
|
1355
|
+
* const xmlBuffer = await client.invoices.downloadFile('invoice-uuid', 'xml');
|
|
1356
|
+
* writeFileSync('invoice.xml', Buffer.from(xmlBuffer));
|
|
1357
|
+
*
|
|
1358
|
+
* // In browser, trigger download:
|
|
1359
|
+
* const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
|
|
1360
|
+
* const url = URL.createObjectURL(blob);
|
|
1361
|
+
* const a = document.createElement('a');
|
|
1362
|
+
* a.href = url;
|
|
1363
|
+
* a.download = 'invoice.pdf';
|
|
1364
|
+
* a.click();
|
|
1365
|
+
* ```
|
|
1366
|
+
*/
|
|
1367
|
+
async downloadFile(id, format = "pdf", requestOptions) {
|
|
1368
|
+
return this.http.getRaw(
|
|
1369
|
+
`/invoices/${id}/download`,
|
|
1370
|
+
{ format },
|
|
1371
|
+
requestOptions
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1138
1374
|
};
|
|
1139
1375
|
|
|
1140
1376
|
// src/resources/signatures.ts
|