@financica/scrada-client 0.2.0 → 0.3.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/dist/index.d.ts +26 -0
- package/dist/index.js +63 -12
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -227,6 +227,7 @@ declare class ScradaApiClient {
|
|
|
227
227
|
getInboundDocument(companyId: string, documentId: string): Promise<ScradaInboundDocumentResponse>;
|
|
228
228
|
getInboundDocumentPdf(companyId: string, documentId: string): Promise<ScradaInboundPdfResponse>;
|
|
229
229
|
confirmInboundDocument(companyId: string, documentId: string): Promise<void>;
|
|
230
|
+
private postOutbound;
|
|
230
231
|
/**
|
|
231
232
|
* @param options.idempotencyKey Sent as `Idempotency-Key`. A transient
|
|
232
233
|
* network-error retry with the same key is collapsed by Scrada, so the
|
|
@@ -236,7 +237,32 @@ declare class ScradaApiClient {
|
|
|
236
237
|
sendOutboundSalesInvoice(companyId: string, payload: PeppolOnlyInvoice, options?: {
|
|
237
238
|
idempotencyKey?: string;
|
|
238
239
|
}): Promise<string>;
|
|
240
|
+
/**
|
|
241
|
+
* Send a self-billing invoice or credit note (buyer issues the document
|
|
242
|
+
* on behalf of the supplier). Same payload shape as a sales invoice.
|
|
243
|
+
*
|
|
244
|
+
* @param options.idempotencyKey See `sendOutboundSalesInvoice`.
|
|
245
|
+
*/
|
|
246
|
+
sendOutboundSelfBillingInvoice(companyId: string, payload: PeppolOnlyInvoice, options?: {
|
|
247
|
+
idempotencyKey?: string;
|
|
248
|
+
}): Promise<string>;
|
|
249
|
+
/**
|
|
250
|
+
* Deliver a pre-built UBL document directly to Peppol. Use this when you
|
|
251
|
+
* already have a UBL XML string (BIS3 invoice, credit note, self-billing,
|
|
252
|
+
* Invoice Response, etc.); for JSON payloads use `sendOutboundSalesInvoice`
|
|
253
|
+
* or `sendOutboundSelfBillingInvoice` instead.
|
|
254
|
+
*
|
|
255
|
+
* @param options.idempotencyKey See `sendOutboundSalesInvoice`.
|
|
256
|
+
*/
|
|
257
|
+
sendOutboundDocument(companyId: string, ubl: string, options?: {
|
|
258
|
+
idempotencyKey?: string;
|
|
259
|
+
}): Promise<string>;
|
|
239
260
|
getOutboundDocumentInfo(companyId: string, documentId: string): Promise<ScradaOutboundDocumentInfo>;
|
|
261
|
+
/**
|
|
262
|
+
* Fetch the rendered UBL XML for an outbound document — useful when the
|
|
263
|
+
* document was sent as JSON and Scrada generated the UBL.
|
|
264
|
+
*/
|
|
265
|
+
getOutboundDocumentUbl(companyId: string, documentId: string): Promise<string>;
|
|
240
266
|
lookupPeppolParticipant(companyId: string, scheme: string, id: string): Promise<ScradaPeppolLookupResponse>;
|
|
241
267
|
lookupPeppolParty(companyId: string, payload: Record<string, unknown>): Promise<ScradaPeppolLookupResponse>;
|
|
242
268
|
}
|
package/dist/index.js
CHANGED
|
@@ -247,32 +247,83 @@ var ScradaApiClient = class {
|
|
|
247
247
|
});
|
|
248
248
|
}
|
|
249
249
|
// ── Outbound documents ──────────────────────────────────────────────
|
|
250
|
-
|
|
251
|
-
* @param options.idempotencyKey Sent as `Idempotency-Key`. A transient
|
|
252
|
-
* network-error retry with the same key is collapsed by Scrada, so the
|
|
253
|
-
* recipient's Peppol endpoint won't receive the same invoice twice. The
|
|
254
|
-
* caller should pass a deterministic key (typically the invoice ID).
|
|
255
|
-
*/
|
|
256
|
-
async sendOutboundSalesInvoice(companyId, payload, options) {
|
|
250
|
+
async postOutbound(params) {
|
|
257
251
|
const headers = {
|
|
258
|
-
"Content-Type":
|
|
252
|
+
"Content-Type": params.contentType
|
|
259
253
|
};
|
|
260
|
-
if (
|
|
261
|
-
headers["Idempotency-Key"] =
|
|
254
|
+
if (params.idempotencyKey) {
|
|
255
|
+
headers["Idempotency-Key"] = params.idempotencyKey;
|
|
262
256
|
}
|
|
263
257
|
const response = await this.request({
|
|
264
|
-
path: `/company/${companyId}/peppol/outbound
|
|
258
|
+
path: `/company/${params.companyId}/peppol/outbound/${params.segment}`,
|
|
265
259
|
method: "POST",
|
|
266
260
|
headers,
|
|
267
|
-
body:
|
|
261
|
+
body: params.body
|
|
268
262
|
});
|
|
269
263
|
return normalizeDocumentId(response);
|
|
270
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* @param options.idempotencyKey Sent as `Idempotency-Key`. A transient
|
|
267
|
+
* network-error retry with the same key is collapsed by Scrada, so the
|
|
268
|
+
* recipient's Peppol endpoint won't receive the same invoice twice. The
|
|
269
|
+
* caller should pass a deterministic key (typically the invoice ID).
|
|
270
|
+
*/
|
|
271
|
+
async sendOutboundSalesInvoice(companyId, payload, options) {
|
|
272
|
+
return this.postOutbound({
|
|
273
|
+
companyId,
|
|
274
|
+
segment: "salesInvoice",
|
|
275
|
+
body: JSON.stringify(payload),
|
|
276
|
+
contentType: "application/json",
|
|
277
|
+
idempotencyKey: options?.idempotencyKey
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Send a self-billing invoice or credit note (buyer issues the document
|
|
282
|
+
* on behalf of the supplier). Same payload shape as a sales invoice.
|
|
283
|
+
*
|
|
284
|
+
* @param options.idempotencyKey See `sendOutboundSalesInvoice`.
|
|
285
|
+
*/
|
|
286
|
+
async sendOutboundSelfBillingInvoice(companyId, payload, options) {
|
|
287
|
+
return this.postOutbound({
|
|
288
|
+
companyId,
|
|
289
|
+
segment: "selfBillingInvoice",
|
|
290
|
+
body: JSON.stringify(payload),
|
|
291
|
+
contentType: "application/json",
|
|
292
|
+
idempotencyKey: options?.idempotencyKey
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Deliver a pre-built UBL document directly to Peppol. Use this when you
|
|
297
|
+
* already have a UBL XML string (BIS3 invoice, credit note, self-billing,
|
|
298
|
+
* Invoice Response, etc.); for JSON payloads use `sendOutboundSalesInvoice`
|
|
299
|
+
* or `sendOutboundSelfBillingInvoice` instead.
|
|
300
|
+
*
|
|
301
|
+
* @param options.idempotencyKey See `sendOutboundSalesInvoice`.
|
|
302
|
+
*/
|
|
303
|
+
async sendOutboundDocument(companyId, ubl, options) {
|
|
304
|
+
return this.postOutbound({
|
|
305
|
+
companyId,
|
|
306
|
+
segment: "document",
|
|
307
|
+
body: ubl,
|
|
308
|
+
contentType: "application/xml",
|
|
309
|
+
idempotencyKey: options?.idempotencyKey
|
|
310
|
+
});
|
|
311
|
+
}
|
|
271
312
|
async getOutboundDocumentInfo(companyId, documentId) {
|
|
272
313
|
return this.request({
|
|
273
314
|
path: `/company/${companyId}/peppol/outbound/document/${documentId}/info`
|
|
274
315
|
});
|
|
275
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Fetch the rendered UBL XML for an outbound document — useful when the
|
|
319
|
+
* document was sent as JSON and Scrada generated the UBL.
|
|
320
|
+
*/
|
|
321
|
+
async getOutboundDocumentUbl(companyId, documentId) {
|
|
322
|
+
return this.request({
|
|
323
|
+
path: `/company/${companyId}/peppol/outbound/document/${documentId}/ubl`,
|
|
324
|
+
expect: "text"
|
|
325
|
+
});
|
|
326
|
+
}
|
|
276
327
|
// ── Peppol participant lookup ───────────────────────────────────────
|
|
277
328
|
async lookupPeppolParticipant(companyId, scheme, id) {
|
|
278
329
|
return this.request({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export const DEFAULT_SCRADA_API_BASE_URL = \"https://api.scrada.be/v1\";\n\n/** Language sent in the Scrada `Language` request header (server may localize errors). */\nexport const SCRADA_LANGUAGE_HEADER = \"EN\";\n\n// ── Peppol identifier scheme defaults ────────────────────────────────\n\nexport const DEFAULT_PEPPOL_SENDER_IDENTIFIER_SCHEME = \"iso6523-actorid-upis\";\n/** ISO/IEC 6523 0208: Belgian enterprise number (KBO/BCE). */\nexport const DEFAULT_PEPPOL_COMPANY_IDENTIFIER_SCHEME = \"0208\";\n/** ISO/IEC 6523 9925: Belgian VAT number scheme. */\nexport const DEFAULT_PEPPOL_VAT_IDENTIFIER_SCHEME = \"9925\";\nexport const DEFAULT_PEPPOL_DOCUMENT_TYPE_SCHEME = \"busdox-docid-qns\";\nexport const DEFAULT_PEPPOL_DOCUMENT_TYPE_VALUE =\n\t\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1\";\nexport const DEFAULT_PEPPOL_PROCESS_SCHEME = \"cenbii-procid-ubl\";\nexport const DEFAULT_PEPPOL_PROCESS_VALUE =\n\t\"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\";\n\n// ── Scrada attachment file type codes ────────────────────────────────\n\n/** Scrada `attachment.fileType` value for the primary invoice/credit note PDF. */\nexport const SCRADA_ATTACHMENT_FILE_TYPE_INVOICE = 1;\n","export class ScradaApiError extends Error {\n\tstatus: number;\n\tdetails: unknown;\n\n\tconstructor(message: string, status: number, details: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"ScradaApiError\";\n\t\tthis.status = status;\n\t\tthis.details = details;\n\t}\n}\n\nconst tryParseJson = (value: string): unknown => {\n\ttry {\n\t\treturn JSON.parse(value) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst normalizeDetailMessage = (value: string) => value.trim().replace(/\\s+/g, \" \");\n\nconst collectDetailMessages = (value: unknown, collector: Set<string>, depth = 0) => {\n\tif (depth > 4 || value === null || value === undefined) return;\n\n\tif (typeof value === \"string\") {\n\t\tconst normalized = normalizeDetailMessage(value);\n\t\tif (normalized.length > 0) collector.add(normalized);\n\t\treturn;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tfor (const entry of value) {\n\t\t\tcollectDetailMessages(entry, collector, depth + 1);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof value !== \"object\") return;\n\tconst record = value as Record<string, unknown>;\n\n\tconst preferredFields = [\n\t\t\"defaultFormat\",\n\t\t\"message\",\n\t\t\"error\",\n\t\t\"title\",\n\t\t\"detail\",\n\t\t\"description\",\n\t\t\"reason\",\n\t];\n\n\tfor (const field of preferredFields) {\n\t\tconst fieldValue = record[field];\n\t\tif (typeof fieldValue === \"string\") {\n\t\t\tconst normalized = normalizeDetailMessage(fieldValue);\n\t\t\tif (normalized.length > 0) collector.add(normalized);\n\t\t}\n\t}\n\n\tconst nestedFields = [\"details\", \"errors\", \"validationErrors\", \"modelState\"];\n\tfor (const field of nestedFields) {\n\t\tif (field in record) {\n\t\t\tcollectDetailMessages(record[field], collector, depth + 1);\n\t\t}\n\t}\n\n\tfor (const [key, fieldValue] of Object.entries(record)) {\n\t\tif (preferredFields.includes(key) || nestedFields.includes(key)) continue;\n\t\tif (typeof fieldValue === \"string\") {\n\t\t\tconst normalized = normalizeDetailMessage(fieldValue);\n\t\t\tif (normalized.length > 0 && /error|invalid|missing|required/i.test(key)) {\n\t\t\t\tcollector.add(normalized);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tArray.isArray(fieldValue) ||\n\t\t\t(fieldValue && typeof fieldValue === \"object\")\n\t\t) {\n\t\t\tcollectDetailMessages(fieldValue, collector, depth + 1);\n\t\t}\n\t}\n};\n\n/**\n * Walks a Scrada error response body and pulls out the human-readable\n * message strings. Returns `null` when nothing usable is found.\n *\n * Scrada returns errors in several shapes (string, `{message}`,\n * `{errors: [{detail}]}`, `{modelState: {...}}`, etc.); this collapses\n * them into a single ` | `-separated summary.\n */\nexport const summarizeScradaErrorDetails = (details: unknown): string | null => {\n\tconst collector = new Set<string>();\n\tcollectDetailMessages(details, collector);\n\tif (collector.size === 0) return null;\n\treturn Array.from(collector).slice(0, 6).join(\" | \");\n};\n\nconst coerceErrorMessage = (details: unknown, fallback: string) =>\n\tsummarizeScradaErrorDetails(details) ?? fallback;\n\n/**\n * Converts a non-2xx Scrada response into a ScradaApiError, parsing the body\n * as JSON when possible and extracting message strings via\n * {@link summarizeScradaErrorDetails}.\n */\nexport const scradaApiErrorFromResponse = async (\n\tresponse: Response,\n): Promise<ScradaApiError> => {\n\tconst textBody = await response.text();\n\tconst parsed = tryParseJson(textBody) ?? textBody;\n\treturn new ScradaApiError(\n\t\tcoerceErrorMessage(\n\t\t\tparsed,\n\t\t\t`Scrada request failed with status ${response.status}`,\n\t\t),\n\t\tresponse.status,\n\t\tparsed,\n\t);\n};\n","import { DEFAULT_SCRADA_API_BASE_URL, SCRADA_LANGUAGE_HEADER } from \"./constants\";\nimport { scradaApiErrorFromResponse } from \"./errors\";\nimport type {\n\tPeppolOnlyInvoice,\n\tScradaInboundDocumentResponse,\n\tScradaInboundUnconfirmedResponse,\n\tScradaOutboundDocumentInfo,\n\tScradaPeppolLookupResponse,\n} from \"./types\";\n\ntype ScradaRequestMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\nexport interface ScradaApiClientOptions {\n\tapiKey: string;\n\tpassword: string;\n\tbaseUrl?: string;\n\t/** Override the global `fetch` (e.g. for testing). */\n\tfetch?: typeof fetch;\n}\n\nexport interface ScradaInboundPdfResponse {\n\tarrayBuffer: ArrayBuffer;\n\tcontentType: string;\n\theaders: Record<string, string>;\n}\n\nconst joinUrl = (baseUrl: string, path: string) => {\n\tconst normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\treturn `${normalizedBase}${normalizedPath}`;\n};\n\nconst normalizeHeaders = (headers: Headers) => {\n\tconst result: Record<string, string> = {};\n\theaders.forEach((value, key) => {\n\t\tresult[key.toLowerCase()] = value;\n\t});\n\treturn result;\n};\n\nconst normalizeDocumentId = (value: unknown): string => {\n\tif (typeof value === \"string\" && value.trim().length > 0) return value.trim();\n\tif (value && typeof value === \"object\") {\n\t\tconst record = value as Record<string, unknown>;\n\t\tif (typeof record.id === \"string\" && record.id.trim().length > 0) {\n\t\t\treturn record.id.trim();\n\t\t}\n\t\tif (\n\t\t\ttypeof record.documentID === \"string\" &&\n\t\t\trecord.documentID.trim().length > 0\n\t\t) {\n\t\t\treturn record.documentID.trim();\n\t\t}\n\t}\n\tthrow new Error(\"Unable to resolve document ID from Scrada response\");\n};\n\nconst tryParseJson = (value: string): unknown => {\n\ttry {\n\t\treturn JSON.parse(value) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n/**\n * HTTP client for the Scrada Peppol API.\n *\n * https://api.scrada.be/v1\n *\n * Authenticates with API key + password sent as `X-API-KEY` / `X-PASSWORD`\n * headers. All non-2xx responses surface as `ScradaApiError`.\n */\nexport class ScradaApiClient {\n\tprivate readonly apiKey: string;\n\tprivate readonly password: string;\n\tprivate readonly baseUrl: string;\n\tprivate readonly fetchImpl: typeof fetch;\n\n\tconstructor(options: ScradaApiClientOptions) {\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.password = options.password;\n\t\tthis.baseUrl = options.baseUrl ?? DEFAULT_SCRADA_API_BASE_URL;\n\t\tthis.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\tprivate buildHeaders(extra?: HeadersInit): Headers {\n\t\tconst headers = new Headers({\n\t\t\t\"X-API-KEY\": this.apiKey,\n\t\t\t\"X-PASSWORD\": this.password,\n\t\t\tLanguage: SCRADA_LANGUAGE_HEADER,\n\t\t});\n\t\tif (extra) {\n\t\t\tconst extraHeaders = new Headers(extra);\n\t\t\textraHeaders.forEach((value, key) => {\n\t\t\t\theaders.set(key, value);\n\t\t\t});\n\t\t}\n\t\treturn headers;\n\t}\n\n\tprivate async request<T>(params: {\n\t\tpath: string;\n\t\tmethod?: ScradaRequestMethod;\n\t\tbody?: BodyInit;\n\t\theaders?: HeadersInit;\n\t\texpect?: \"json\" | \"text\" | \"arrayBuffer\";\n\t}): Promise<T> {\n\t\tconst response = await this.fetchImpl(joinUrl(this.baseUrl, params.path), {\n\t\t\tmethod: params.method ?? \"GET\",\n\t\t\theaders: this.buildHeaders(params.headers),\n\t\t\tbody: params.body,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow await scradaApiErrorFromResponse(response);\n\t\t}\n\n\t\tconst expect = params.expect ?? \"json\";\n\t\tif (expect === \"arrayBuffer\") {\n\t\t\treturn (await response.arrayBuffer()) as T;\n\t\t}\n\t\tif (expect === \"text\") {\n\t\t\treturn (await response.text()) as T;\n\t\t}\n\n\t\tconst textBody = await response.text();\n\t\tif (!textBody) return null as T;\n\t\tconst parsed = tryParseJson(textBody);\n\t\tif (parsed !== null) return parsed as T;\n\t\treturn textBody as T;\n\t}\n\n\t// ── Peppol registration ─────────────────────────────────────────────\n\n\tasync registerCompany(\n\t\tcompanyId: string,\n\t\tpayload: Record<string, unknown>,\n\t): Promise<string> {\n\t\tconst response = await this.request<unknown>({\n\t\t\tpath: `/company/${companyId}/peppol/register`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\t\treturn normalizeDocumentId(response);\n\t}\n\n\tasync deregisterCompany(\n\t\tcompanyId: string,\n\t\tparticipantIdentifierScheme: string,\n\t\tparticipantIdentifierValue: string,\n\t): Promise<void> {\n\t\tawait this.request<null>({\n\t\t\tpath: `/company/${companyId}/peppol/deregister/${encodeURIComponent(\n\t\t\t\tparticipantIdentifierScheme,\n\t\t\t)}/${encodeURIComponent(participantIdentifierValue)}`,\n\t\t\tmethod: \"DELETE\",\n\t\t});\n\t}\n\n\t// ── Inbound documents ───────────────────────────────────────────────\n\n\tasync getUnconfirmedInboundDocuments(\n\t\tcompanyId: string,\n\t): Promise<ScradaInboundUnconfirmedResponse> {\n\t\treturn this.request<ScradaInboundUnconfirmedResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/inbound/document/unconfirmed`,\n\t\t});\n\t}\n\n\tasync getInboundDocument(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaInboundDocumentResponse> {\n\t\tconst response = await this.fetchImpl(\n\t\t\tjoinUrl(\n\t\t\t\tthis.baseUrl,\n\t\t\t\t`/company/${companyId}/peppol/inbound/document/${documentId}`,\n\t\t\t),\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: this.buildHeaders(),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) throw await scradaApiErrorFromResponse(response);\n\n\t\treturn {\n\t\t\tbody: await response.text(),\n\t\t\tcontentType: response.headers.get(\"content-type\"),\n\t\t\theaders: normalizeHeaders(response.headers),\n\t\t};\n\t}\n\n\tasync getInboundDocumentPdf(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaInboundPdfResponse> {\n\t\tconst response = await this.fetchImpl(\n\t\t\tjoinUrl(\n\t\t\t\tthis.baseUrl,\n\t\t\t\t`/company/${companyId}/peppol/inbound/document/${documentId}/pdf`,\n\t\t\t),\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: this.buildHeaders(),\n\t\t\t},\n\t\t);\n\t\tif (!response.ok) throw await scradaApiErrorFromResponse(response);\n\n\t\treturn {\n\t\t\tarrayBuffer: await response.arrayBuffer(),\n\t\t\tcontentType: response.headers.get(\"content-type\") ?? \"application/pdf\",\n\t\t\theaders: normalizeHeaders(response.headers),\n\t\t};\n\t}\n\n\tasync confirmInboundDocument(companyId: string, documentId: string): Promise<void> {\n\t\tawait this.request<null>({\n\t\t\tpath: `/company/${companyId}/peppol/inbound/document/${documentId}/confirm`,\n\t\t\tmethod: \"PUT\",\n\t\t});\n\t}\n\n\t// ── Outbound documents ──────────────────────────────────────────────\n\n\t/**\n\t * @param options.idempotencyKey Sent as `Idempotency-Key`. A transient\n\t * network-error retry with the same key is collapsed by Scrada, so the\n\t * recipient's Peppol endpoint won't receive the same invoice twice. The\n\t * caller should pass a deterministic key (typically the invoice ID).\n\t */\n\tasync sendOutboundSalesInvoice(\n\t\tcompanyId: string,\n\t\tpayload: PeppolOnlyInvoice,\n\t\toptions?: { idempotencyKey?: string },\n\t): Promise<string> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t};\n\t\tif (options?.idempotencyKey) {\n\t\t\theaders[\"Idempotency-Key\"] = options.idempotencyKey;\n\t\t}\n\t\tconst response = await this.request<unknown>({\n\t\t\tpath: `/company/${companyId}/peppol/outbound/salesInvoice`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\t\treturn normalizeDocumentId(response);\n\t}\n\n\tasync getOutboundDocumentInfo(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaOutboundDocumentInfo> {\n\t\treturn this.request<ScradaOutboundDocumentInfo>({\n\t\t\tpath: `/company/${companyId}/peppol/outbound/document/${documentId}/info`,\n\t\t});\n\t}\n\n\t// ── Peppol participant lookup ───────────────────────────────────────\n\n\tasync lookupPeppolParticipant(\n\t\tcompanyId: string,\n\t\tscheme: string,\n\t\tid: string,\n\t): Promise<ScradaPeppolLookupResponse> {\n\t\treturn this.request<ScradaPeppolLookupResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/lookup/${encodeURIComponent(\n\t\t\t\tscheme,\n\t\t\t)}/${encodeURIComponent(id)}`,\n\t\t});\n\t}\n\n\tasync lookupPeppolParty(\n\t\tcompanyId: string,\n\t\tpayload: Record<string, unknown>,\n\t): Promise<ScradaPeppolLookupResponse> {\n\t\treturn this.request<ScradaPeppolLookupResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/lookup`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\t}\n}\n\n/**\n * Create a Scrada API client from the canonical environment variables.\n * Throws when SCRADA_API_KEY or SCRADA_PASSWORD is missing.\n */\nexport const createScradaApiClientFromEnv = (\n\tenv: NodeJS.ProcessEnv = process.env,\n): ScradaApiClient => {\n\tconst apiKey = env.SCRADA_API_KEY;\n\tconst password = env.SCRADA_PASSWORD;\n\tif (!apiKey || !password) {\n\t\tthrow new Error(\n\t\t\t\"Scrada credentials are not configured. Set SCRADA_API_KEY and SCRADA_PASSWORD.\",\n\t\t);\n\t}\n\n\treturn new ScradaApiClient({\n\t\tapiKey,\n\t\tpassword,\n\t\tbaseUrl: env.SCRADA_API_BASE_URL,\n\t});\n};\n"],"mappings":"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","names":["tryParseJson"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export const DEFAULT_SCRADA_API_BASE_URL = \"https://api.scrada.be/v1\";\n\n/** Language sent in the Scrada `Language` request header (server may localize errors). */\nexport const SCRADA_LANGUAGE_HEADER = \"EN\";\n\n// ── Peppol identifier scheme defaults ────────────────────────────────\n\nexport const DEFAULT_PEPPOL_SENDER_IDENTIFIER_SCHEME = \"iso6523-actorid-upis\";\n/** ISO/IEC 6523 0208: Belgian enterprise number (KBO/BCE). */\nexport const DEFAULT_PEPPOL_COMPANY_IDENTIFIER_SCHEME = \"0208\";\n/** ISO/IEC 6523 9925: Belgian VAT number scheme. */\nexport const DEFAULT_PEPPOL_VAT_IDENTIFIER_SCHEME = \"9925\";\nexport const DEFAULT_PEPPOL_DOCUMENT_TYPE_SCHEME = \"busdox-docid-qns\";\nexport const DEFAULT_PEPPOL_DOCUMENT_TYPE_VALUE =\n\t\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1\";\nexport const DEFAULT_PEPPOL_PROCESS_SCHEME = \"cenbii-procid-ubl\";\nexport const DEFAULT_PEPPOL_PROCESS_VALUE =\n\t\"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\";\n\n// ── Scrada attachment file type codes ────────────────────────────────\n\n/** Scrada `attachment.fileType` value for the primary invoice/credit note PDF. */\nexport const SCRADA_ATTACHMENT_FILE_TYPE_INVOICE = 1;\n","export class ScradaApiError extends Error {\n\tstatus: number;\n\tdetails: unknown;\n\n\tconstructor(message: string, status: number, details: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"ScradaApiError\";\n\t\tthis.status = status;\n\t\tthis.details = details;\n\t}\n}\n\nconst tryParseJson = (value: string): unknown => {\n\ttry {\n\t\treturn JSON.parse(value) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst normalizeDetailMessage = (value: string) => value.trim().replace(/\\s+/g, \" \");\n\nconst collectDetailMessages = (value: unknown, collector: Set<string>, depth = 0) => {\n\tif (depth > 4 || value === null || value === undefined) return;\n\n\tif (typeof value === \"string\") {\n\t\tconst normalized = normalizeDetailMessage(value);\n\t\tif (normalized.length > 0) collector.add(normalized);\n\t\treturn;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tfor (const entry of value) {\n\t\t\tcollectDetailMessages(entry, collector, depth + 1);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof value !== \"object\") return;\n\tconst record = value as Record<string, unknown>;\n\n\tconst preferredFields = [\n\t\t\"defaultFormat\",\n\t\t\"message\",\n\t\t\"error\",\n\t\t\"title\",\n\t\t\"detail\",\n\t\t\"description\",\n\t\t\"reason\",\n\t];\n\n\tfor (const field of preferredFields) {\n\t\tconst fieldValue = record[field];\n\t\tif (typeof fieldValue === \"string\") {\n\t\t\tconst normalized = normalizeDetailMessage(fieldValue);\n\t\t\tif (normalized.length > 0) collector.add(normalized);\n\t\t}\n\t}\n\n\tconst nestedFields = [\"details\", \"errors\", \"validationErrors\", \"modelState\"];\n\tfor (const field of nestedFields) {\n\t\tif (field in record) {\n\t\t\tcollectDetailMessages(record[field], collector, depth + 1);\n\t\t}\n\t}\n\n\tfor (const [key, fieldValue] of Object.entries(record)) {\n\t\tif (preferredFields.includes(key) || nestedFields.includes(key)) continue;\n\t\tif (typeof fieldValue === \"string\") {\n\t\t\tconst normalized = normalizeDetailMessage(fieldValue);\n\t\t\tif (normalized.length > 0 && /error|invalid|missing|required/i.test(key)) {\n\t\t\t\tcollector.add(normalized);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tArray.isArray(fieldValue) ||\n\t\t\t(fieldValue && typeof fieldValue === \"object\")\n\t\t) {\n\t\t\tcollectDetailMessages(fieldValue, collector, depth + 1);\n\t\t}\n\t}\n};\n\n/**\n * Walks a Scrada error response body and pulls out the human-readable\n * message strings. Returns `null` when nothing usable is found.\n *\n * Scrada returns errors in several shapes (string, `{message}`,\n * `{errors: [{detail}]}`, `{modelState: {...}}`, etc.); this collapses\n * them into a single ` | `-separated summary.\n */\nexport const summarizeScradaErrorDetails = (details: unknown): string | null => {\n\tconst collector = new Set<string>();\n\tcollectDetailMessages(details, collector);\n\tif (collector.size === 0) return null;\n\treturn Array.from(collector).slice(0, 6).join(\" | \");\n};\n\nconst coerceErrorMessage = (details: unknown, fallback: string) =>\n\tsummarizeScradaErrorDetails(details) ?? fallback;\n\n/**\n * Converts a non-2xx Scrada response into a ScradaApiError, parsing the body\n * as JSON when possible and extracting message strings via\n * {@link summarizeScradaErrorDetails}.\n */\nexport const scradaApiErrorFromResponse = async (\n\tresponse: Response,\n): Promise<ScradaApiError> => {\n\tconst textBody = await response.text();\n\tconst parsed = tryParseJson(textBody) ?? textBody;\n\treturn new ScradaApiError(\n\t\tcoerceErrorMessage(\n\t\t\tparsed,\n\t\t\t`Scrada request failed with status ${response.status}`,\n\t\t),\n\t\tresponse.status,\n\t\tparsed,\n\t);\n};\n","import { DEFAULT_SCRADA_API_BASE_URL, SCRADA_LANGUAGE_HEADER } from \"./constants\";\nimport { scradaApiErrorFromResponse } from \"./errors\";\nimport type {\n\tPeppolOnlyInvoice,\n\tScradaInboundDocumentResponse,\n\tScradaInboundUnconfirmedResponse,\n\tScradaOutboundDocumentInfo,\n\tScradaPeppolLookupResponse,\n} from \"./types\";\n\ntype ScradaRequestMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\nexport interface ScradaApiClientOptions {\n\tapiKey: string;\n\tpassword: string;\n\tbaseUrl?: string;\n\t/** Override the global `fetch` (e.g. for testing). */\n\tfetch?: typeof fetch;\n}\n\nexport interface ScradaInboundPdfResponse {\n\tarrayBuffer: ArrayBuffer;\n\tcontentType: string;\n\theaders: Record<string, string>;\n}\n\nconst joinUrl = (baseUrl: string, path: string) => {\n\tconst normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\treturn `${normalizedBase}${normalizedPath}`;\n};\n\nconst normalizeHeaders = (headers: Headers) => {\n\tconst result: Record<string, string> = {};\n\theaders.forEach((value, key) => {\n\t\tresult[key.toLowerCase()] = value;\n\t});\n\treturn result;\n};\n\nconst normalizeDocumentId = (value: unknown): string => {\n\tif (typeof value === \"string\" && value.trim().length > 0) return value.trim();\n\tif (value && typeof value === \"object\") {\n\t\tconst record = value as Record<string, unknown>;\n\t\tif (typeof record.id === \"string\" && record.id.trim().length > 0) {\n\t\t\treturn record.id.trim();\n\t\t}\n\t\tif (\n\t\t\ttypeof record.documentID === \"string\" &&\n\t\t\trecord.documentID.trim().length > 0\n\t\t) {\n\t\t\treturn record.documentID.trim();\n\t\t}\n\t}\n\tthrow new Error(\"Unable to resolve document ID from Scrada response\");\n};\n\nconst tryParseJson = (value: string): unknown => {\n\ttry {\n\t\treturn JSON.parse(value) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n/**\n * HTTP client for the Scrada Peppol API.\n *\n * https://api.scrada.be/v1\n *\n * Authenticates with API key + password sent as `X-API-KEY` / `X-PASSWORD`\n * headers. All non-2xx responses surface as `ScradaApiError`.\n */\nexport class ScradaApiClient {\n\tprivate readonly apiKey: string;\n\tprivate readonly password: string;\n\tprivate readonly baseUrl: string;\n\tprivate readonly fetchImpl: typeof fetch;\n\n\tconstructor(options: ScradaApiClientOptions) {\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.password = options.password;\n\t\tthis.baseUrl = options.baseUrl ?? DEFAULT_SCRADA_API_BASE_URL;\n\t\tthis.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\tprivate buildHeaders(extra?: HeadersInit): Headers {\n\t\tconst headers = new Headers({\n\t\t\t\"X-API-KEY\": this.apiKey,\n\t\t\t\"X-PASSWORD\": this.password,\n\t\t\tLanguage: SCRADA_LANGUAGE_HEADER,\n\t\t});\n\t\tif (extra) {\n\t\t\tconst extraHeaders = new Headers(extra);\n\t\t\textraHeaders.forEach((value, key) => {\n\t\t\t\theaders.set(key, value);\n\t\t\t});\n\t\t}\n\t\treturn headers;\n\t}\n\n\tprivate async request<T>(params: {\n\t\tpath: string;\n\t\tmethod?: ScradaRequestMethod;\n\t\tbody?: BodyInit;\n\t\theaders?: HeadersInit;\n\t\texpect?: \"json\" | \"text\" | \"arrayBuffer\";\n\t}): Promise<T> {\n\t\tconst response = await this.fetchImpl(joinUrl(this.baseUrl, params.path), {\n\t\t\tmethod: params.method ?? \"GET\",\n\t\t\theaders: this.buildHeaders(params.headers),\n\t\t\tbody: params.body,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow await scradaApiErrorFromResponse(response);\n\t\t}\n\n\t\tconst expect = params.expect ?? \"json\";\n\t\tif (expect === \"arrayBuffer\") {\n\t\t\treturn (await response.arrayBuffer()) as T;\n\t\t}\n\t\tif (expect === \"text\") {\n\t\t\treturn (await response.text()) as T;\n\t\t}\n\n\t\tconst textBody = await response.text();\n\t\tif (!textBody) return null as T;\n\t\tconst parsed = tryParseJson(textBody);\n\t\tif (parsed !== null) return parsed as T;\n\t\treturn textBody as T;\n\t}\n\n\t// ── Peppol registration ─────────────────────────────────────────────\n\n\tasync registerCompany(\n\t\tcompanyId: string,\n\t\tpayload: Record<string, unknown>,\n\t): Promise<string> {\n\t\tconst response = await this.request<unknown>({\n\t\t\tpath: `/company/${companyId}/peppol/register`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\t\treturn normalizeDocumentId(response);\n\t}\n\n\tasync deregisterCompany(\n\t\tcompanyId: string,\n\t\tparticipantIdentifierScheme: string,\n\t\tparticipantIdentifierValue: string,\n\t): Promise<void> {\n\t\tawait this.request<null>({\n\t\t\tpath: `/company/${companyId}/peppol/deregister/${encodeURIComponent(\n\t\t\t\tparticipantIdentifierScheme,\n\t\t\t)}/${encodeURIComponent(participantIdentifierValue)}`,\n\t\t\tmethod: \"DELETE\",\n\t\t});\n\t}\n\n\t// ── Inbound documents ───────────────────────────────────────────────\n\n\tasync getUnconfirmedInboundDocuments(\n\t\tcompanyId: string,\n\t): Promise<ScradaInboundUnconfirmedResponse> {\n\t\treturn this.request<ScradaInboundUnconfirmedResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/inbound/document/unconfirmed`,\n\t\t});\n\t}\n\n\tasync getInboundDocument(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaInboundDocumentResponse> {\n\t\tconst response = await this.fetchImpl(\n\t\t\tjoinUrl(\n\t\t\t\tthis.baseUrl,\n\t\t\t\t`/company/${companyId}/peppol/inbound/document/${documentId}`,\n\t\t\t),\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: this.buildHeaders(),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) throw await scradaApiErrorFromResponse(response);\n\n\t\treturn {\n\t\t\tbody: await response.text(),\n\t\t\tcontentType: response.headers.get(\"content-type\"),\n\t\t\theaders: normalizeHeaders(response.headers),\n\t\t};\n\t}\n\n\tasync getInboundDocumentPdf(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaInboundPdfResponse> {\n\t\tconst response = await this.fetchImpl(\n\t\t\tjoinUrl(\n\t\t\t\tthis.baseUrl,\n\t\t\t\t`/company/${companyId}/peppol/inbound/document/${documentId}/pdf`,\n\t\t\t),\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: this.buildHeaders(),\n\t\t\t},\n\t\t);\n\t\tif (!response.ok) throw await scradaApiErrorFromResponse(response);\n\n\t\treturn {\n\t\t\tarrayBuffer: await response.arrayBuffer(),\n\t\t\tcontentType: response.headers.get(\"content-type\") ?? \"application/pdf\",\n\t\t\theaders: normalizeHeaders(response.headers),\n\t\t};\n\t}\n\n\tasync confirmInboundDocument(companyId: string, documentId: string): Promise<void> {\n\t\tawait this.request<null>({\n\t\t\tpath: `/company/${companyId}/peppol/inbound/document/${documentId}/confirm`,\n\t\t\tmethod: \"PUT\",\n\t\t});\n\t}\n\n\t// ── Outbound documents ──────────────────────────────────────────────\n\n\tprivate async postOutbound(params: {\n\t\tcompanyId: string;\n\t\tsegment: \"salesInvoice\" | \"selfBillingInvoice\" | \"document\";\n\t\tbody: BodyInit;\n\t\tcontentType: \"application/json\" | \"application/xml\";\n\t\tidempotencyKey?: string;\n\t}): Promise<string> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"Content-Type\": params.contentType,\n\t\t};\n\t\tif (params.idempotencyKey) {\n\t\t\theaders[\"Idempotency-Key\"] = params.idempotencyKey;\n\t\t}\n\t\tconst response = await this.request<unknown>({\n\t\t\tpath: `/company/${params.companyId}/peppol/outbound/${params.segment}`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: params.body,\n\t\t});\n\t\treturn normalizeDocumentId(response);\n\t}\n\n\t/**\n\t * @param options.idempotencyKey Sent as `Idempotency-Key`. A transient\n\t * network-error retry with the same key is collapsed by Scrada, so the\n\t * recipient's Peppol endpoint won't receive the same invoice twice. The\n\t * caller should pass a deterministic key (typically the invoice ID).\n\t */\n\tasync sendOutboundSalesInvoice(\n\t\tcompanyId: string,\n\t\tpayload: PeppolOnlyInvoice,\n\t\toptions?: { idempotencyKey?: string },\n\t): Promise<string> {\n\t\treturn this.postOutbound({\n\t\t\tcompanyId,\n\t\t\tsegment: \"salesInvoice\",\n\t\t\tbody: JSON.stringify(payload),\n\t\t\tcontentType: \"application/json\",\n\t\t\tidempotencyKey: options?.idempotencyKey,\n\t\t});\n\t}\n\n\t/**\n\t * Send a self-billing invoice or credit note (buyer issues the document\n\t * on behalf of the supplier). Same payload shape as a sales invoice.\n\t *\n\t * @param options.idempotencyKey See `sendOutboundSalesInvoice`.\n\t */\n\tasync sendOutboundSelfBillingInvoice(\n\t\tcompanyId: string,\n\t\tpayload: PeppolOnlyInvoice,\n\t\toptions?: { idempotencyKey?: string },\n\t): Promise<string> {\n\t\treturn this.postOutbound({\n\t\t\tcompanyId,\n\t\t\tsegment: \"selfBillingInvoice\",\n\t\t\tbody: JSON.stringify(payload),\n\t\t\tcontentType: \"application/json\",\n\t\t\tidempotencyKey: options?.idempotencyKey,\n\t\t});\n\t}\n\n\t/**\n\t * Deliver a pre-built UBL document directly to Peppol. Use this when you\n\t * already have a UBL XML string (BIS3 invoice, credit note, self-billing,\n\t * Invoice Response, etc.); for JSON payloads use `sendOutboundSalesInvoice`\n\t * or `sendOutboundSelfBillingInvoice` instead.\n\t *\n\t * @param options.idempotencyKey See `sendOutboundSalesInvoice`.\n\t */\n\tasync sendOutboundDocument(\n\t\tcompanyId: string,\n\t\tubl: string,\n\t\toptions?: { idempotencyKey?: string },\n\t): Promise<string> {\n\t\treturn this.postOutbound({\n\t\t\tcompanyId,\n\t\t\tsegment: \"document\",\n\t\t\tbody: ubl,\n\t\t\tcontentType: \"application/xml\",\n\t\t\tidempotencyKey: options?.idempotencyKey,\n\t\t});\n\t}\n\n\tasync getOutboundDocumentInfo(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<ScradaOutboundDocumentInfo> {\n\t\treturn this.request<ScradaOutboundDocumentInfo>({\n\t\t\tpath: `/company/${companyId}/peppol/outbound/document/${documentId}/info`,\n\t\t});\n\t}\n\n\t/**\n\t * Fetch the rendered UBL XML for an outbound document — useful when the\n\t * document was sent as JSON and Scrada generated the UBL.\n\t */\n\tasync getOutboundDocumentUbl(\n\t\tcompanyId: string,\n\t\tdocumentId: string,\n\t): Promise<string> {\n\t\treturn this.request<string>({\n\t\t\tpath: `/company/${companyId}/peppol/outbound/document/${documentId}/ubl`,\n\t\t\texpect: \"text\",\n\t\t});\n\t}\n\n\t// ── Peppol participant lookup ───────────────────────────────────────\n\n\tasync lookupPeppolParticipant(\n\t\tcompanyId: string,\n\t\tscheme: string,\n\t\tid: string,\n\t): Promise<ScradaPeppolLookupResponse> {\n\t\treturn this.request<ScradaPeppolLookupResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/lookup/${encodeURIComponent(\n\t\t\t\tscheme,\n\t\t\t)}/${encodeURIComponent(id)}`,\n\t\t});\n\t}\n\n\tasync lookupPeppolParty(\n\t\tcompanyId: string,\n\t\tpayload: Record<string, unknown>,\n\t): Promise<ScradaPeppolLookupResponse> {\n\t\treturn this.request<ScradaPeppolLookupResponse>({\n\t\t\tpath: `/company/${companyId}/peppol/lookup`,\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\t}\n}\n\n/**\n * Create a Scrada API client from the canonical environment variables.\n * Throws when SCRADA_API_KEY or SCRADA_PASSWORD is missing.\n */\nexport const createScradaApiClientFromEnv = (\n\tenv: NodeJS.ProcessEnv = process.env,\n): ScradaApiClient => {\n\tconst apiKey = env.SCRADA_API_KEY;\n\tconst password = env.SCRADA_PASSWORD;\n\tif (!apiKey || !password) {\n\t\tthrow new Error(\n\t\t\t\"Scrada credentials are not configured. Set SCRADA_API_KEY and SCRADA_PASSWORD.\",\n\t\t);\n\t}\n\n\treturn new ScradaApiClient({\n\t\tapiKey,\n\t\tpassword,\n\t\tbaseUrl: env.SCRADA_API_BASE_URL,\n\t});\n};\n"],"mappings":"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","names":["tryParseJson"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financica/scrada-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TypeScript HTTP client for the Scrada Peppol API (https://api.scrada.be/v1).",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/financica/scrada-client.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": "https://github.com/financica/scrada-client/issues",
|
|
11
|
+
"homepage": "https://github.com/financica/scrada-client#readme",
|
|
6
12
|
"type": "module",
|
|
7
13
|
"exports": {
|
|
8
14
|
".": {
|