salesdock 0.1.1

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.js ADDED
@@ -0,0 +1,3344 @@
1
+ import { z } from 'zod';
2
+
3
+ // src/client.ts
4
+
5
+ // src/core/config.ts
6
+ var PRODUCTION_BASE_URL = "https://app.salesdock.nl";
7
+ var STAGING_BASE_URL = "https://app-staging.salesdock.nl";
8
+ var DEFAULT_VERSION = "v1";
9
+ var SDK_VERSION = "0.1.0";
10
+ function resolveConfig(config) {
11
+ if (!config || typeof config !== "object") {
12
+ throw new Error("Salesdock: configuration object is required.");
13
+ }
14
+ if (!config.domain || typeof config.domain !== "string") {
15
+ throw new Error(
16
+ 'Salesdock: `domain` is required (your account sub-domain, e.g. "testomgeving").'
17
+ );
18
+ }
19
+ if (!config.token || typeof config.token !== "string") {
20
+ throw new Error("Salesdock: `token` (Bearer API token) is required.");
21
+ }
22
+ const resolvedFetch = config.fetch ?? globalFetch();
23
+ if (!resolvedFetch) {
24
+ throw new Error(
25
+ "Salesdock: no global `fetch` found in this runtime. Pass a `fetch` implementation in the config."
26
+ );
27
+ }
28
+ const baseUrl = (config.baseUrl ?? PRODUCTION_BASE_URL).replace(/\/+$/, "");
29
+ return {
30
+ domain: config.domain,
31
+ token: config.token,
32
+ scope: config.scope ?? "user",
33
+ version: config.version ?? DEFAULT_VERSION,
34
+ baseUrl,
35
+ fetch: resolvedFetch,
36
+ validateResponses: config.validateResponses ?? true,
37
+ validateRequests: config.validateRequests ?? true,
38
+ maxRetries: config.maxRetries ?? 2,
39
+ retryDelayMs: config.retryDelayMs ?? 500,
40
+ timeout: config.timeout ?? 6e4,
41
+ headers: { ...config.headers ?? {} },
42
+ onRequest: config.onRequest,
43
+ onResponse: config.onResponse,
44
+ userAgent: config.userAgent
45
+ };
46
+ }
47
+ function globalFetch() {
48
+ const f = globalThis.fetch;
49
+ return typeof f === "function" ? f.bind(globalThis) : void 0;
50
+ }
51
+
52
+ // src/core/errors.ts
53
+ var SalesdockError = class extends Error {
54
+ constructor(message, options = {}) {
55
+ super(message, options.cause !== void 0 ? { cause: options.cause } : void 0);
56
+ this.name = new.target.name;
57
+ this.status = options.status;
58
+ this.code = options.code;
59
+ this.body = options.body;
60
+ this.errors = options.errors;
61
+ this.url = options.url;
62
+ this.method = options.method;
63
+ this.retryAfterMs = options.retryAfterMs;
64
+ Object.setPrototypeOf(this, new.target.prototype);
65
+ }
66
+ };
67
+ var SalesdockValidationError = class extends SalesdockError {
68
+ };
69
+ var SalesdockAuthenticationError = class extends SalesdockError {
70
+ };
71
+ var SalesdockForbiddenError = class extends SalesdockError {
72
+ };
73
+ var SalesdockNotFoundError = class extends SalesdockError {
74
+ };
75
+ var SalesdockMethodNotAllowedError = class extends SalesdockError {
76
+ };
77
+ var SalesdockRateLimitError = class extends SalesdockError {
78
+ };
79
+ var SalesdockServerError = class extends SalesdockError {
80
+ };
81
+ var SalesdockConnectionError = class extends SalesdockError {
82
+ };
83
+ var SalesdockTimeoutError = class extends SalesdockConnectionError {
84
+ };
85
+ var SalesdockInvalidRequestError = class extends SalesdockError {
86
+ constructor(message, zodError, options = {}) {
87
+ super(message, options);
88
+ this.zodError = zodError;
89
+ }
90
+ };
91
+ var SalesdockResponseValidationError = class extends SalesdockError {
92
+ constructor(message, zodError, options = {}) {
93
+ super(message, options);
94
+ this.zodError = zodError;
95
+ }
96
+ };
97
+ function errorFromResponse(status, body, context) {
98
+ const parsed = body && typeof body === "object" ? body : {};
99
+ const rawTextMessage = typeof body === "string" && body.trim() ? body.trim().slice(0, 500) : void 0;
100
+ const message = typeof parsed.message === "string" && parsed.message || rawTextMessage || defaultMessageForStatus(status);
101
+ const options = {
102
+ status,
103
+ code: typeof parsed.code === "number" ? parsed.code : void 0,
104
+ body,
105
+ errors: parsed.errors,
106
+ url: context.url,
107
+ method: context.method,
108
+ retryAfterMs: context.retryAfterMs
109
+ };
110
+ switch (status) {
111
+ case 400:
112
+ case 422:
113
+ return new SalesdockValidationError(message, options);
114
+ case 401:
115
+ return new SalesdockAuthenticationError(message, options);
116
+ case 403:
117
+ return new SalesdockForbiddenError(message, options);
118
+ case 404:
119
+ return new SalesdockNotFoundError(message, options);
120
+ case 405:
121
+ return new SalesdockMethodNotAllowedError(message, options);
122
+ case 429:
123
+ return new SalesdockRateLimitError(message, options);
124
+ default:
125
+ if (status >= 500) return new SalesdockServerError(message, options);
126
+ return new SalesdockError(message, options);
127
+ }
128
+ }
129
+ function defaultMessageForStatus(status) {
130
+ switch (status) {
131
+ case 400:
132
+ return "Bad request";
133
+ case 401:
134
+ return "Unauthorized";
135
+ case 403:
136
+ return "Forbidden";
137
+ case 404:
138
+ return "Not found";
139
+ case 405:
140
+ return "Method not allowed";
141
+ case 422:
142
+ return "Unprocessable entity";
143
+ case 429:
144
+ return "Too many requests";
145
+ default:
146
+ return status >= 500 ? "Server error" : `Request failed with status ${status}`;
147
+ }
148
+ }
149
+ function loose(shape) {
150
+ return z.object(shape).passthrough();
151
+ }
152
+ function nullish(schema) {
153
+ return schema.nullish();
154
+ }
155
+ var idSchema = z.union([z.number(), z.string()]);
156
+ var boolishSchema = z.union([
157
+ z.boolean(),
158
+ z.literal("0"),
159
+ z.literal("1"),
160
+ z.literal(0),
161
+ z.literal(1)
162
+ ]);
163
+ var dateTimeSchema = z.string();
164
+ function envelopeSchema(data) {
165
+ return z.object({
166
+ success: z.boolean(),
167
+ data,
168
+ message: z.string().optional()
169
+ }).passthrough();
170
+ }
171
+ var paginationLinkSchema = loose({
172
+ url: z.string().nullable(),
173
+ label: z.string(),
174
+ active: z.boolean()
175
+ });
176
+ function offsetPaginatedSchema(item) {
177
+ return loose({
178
+ current_page: z.number(),
179
+ data: z.array(item),
180
+ first_page_url: z.string().nullable().optional(),
181
+ from: z.number().nullable().optional(),
182
+ last_page: z.number(),
183
+ last_page_url: z.string().nullable().optional(),
184
+ links: z.array(paginationLinkSchema).optional(),
185
+ next_page_url: z.string().nullable().optional(),
186
+ path: z.string().optional(),
187
+ per_page: z.union([z.number(), z.string()]),
188
+ prev_page_url: z.string().nullable().optional(),
189
+ to: z.number().nullable().optional(),
190
+ total: z.number()
191
+ });
192
+ }
193
+ function cursorPaginatedSchema(item) {
194
+ return loose({
195
+ path: z.string().optional(),
196
+ per_page: z.union([z.number(), z.string()]),
197
+ next_cursor: z.string().nullable().optional(),
198
+ next_page_url: z.string().nullable().optional(),
199
+ prev_cursor: z.string().nullable().optional(),
200
+ prev_page_url: z.string().nullable().optional(),
201
+ data: z.array(item)
202
+ });
203
+ }
204
+ var addressSchema = loose({
205
+ postcode: nullish(z.string()),
206
+ housenumber: nullish(z.union([z.string(), z.number()])),
207
+ suffix: nullish(z.string()),
208
+ streetname: nullish(z.string()),
209
+ city: nullish(z.string())
210
+ });
211
+ var customerSchema = loose({
212
+ gender: nullish(z.string()),
213
+ initials: nullish(z.string()),
214
+ firstname: nullish(z.string()),
215
+ infix: nullish(z.string()),
216
+ lastname: nullish(z.string()),
217
+ birthdate: nullish(z.string()),
218
+ email: nullish(z.string()),
219
+ phone: nullish(z.string()),
220
+ business: nullish(z.union([z.boolean(), z.string(), z.number()])),
221
+ company_name: nullish(z.string()),
222
+ contact_person: nullish(z.string()),
223
+ coc: nullish(z.string()),
224
+ vat: nullish(z.string()),
225
+ iban: nullish(z.string()),
226
+ iban_holder: nullish(z.string()),
227
+ address: addressSchema.optional()
228
+ });
229
+ var extraFieldSchema = loose({
230
+ id: idSchema.optional(),
231
+ identifier: nullish(z.string()),
232
+ type: nullish(z.string()),
233
+ label: nullish(z.string()),
234
+ value: z.unknown().optional()
235
+ });
236
+ var statusSchema = loose({
237
+ status_identifier: nullish(z.string()),
238
+ status: nullish(z.string()),
239
+ status_remark: nullish(z.string())
240
+ });
241
+
242
+ // src/core/http.ts
243
+ var RETRYABLE_5XX = /* @__PURE__ */ new Set([500, 502, 503, 504]);
244
+ var HttpClient = class {
245
+ constructor(config) {
246
+ this.config = config;
247
+ }
248
+ /** Execute a request and return the validated `data` payload. */
249
+ async request(req) {
250
+ const url = this.buildUrl(req.segments, req.query);
251
+ return this.send(req.method, url, req.dataSchema, req.body, req.options);
252
+ }
253
+ /** Build a full request URL from path segments and query parameters. */
254
+ buildUrl(segments, query) {
255
+ const base = `${this.config.baseUrl}/api/${encodeURIComponent(
256
+ this.config.domain
257
+ )}/${encodeURIComponent(this.config.version)}`;
258
+ const path = segments.map((s) => encodeURIComponent(String(s))).join("/");
259
+ const qs = buildQueryString(query);
260
+ return `${base}/${path}${qs ? `?${qs}` : ""}`;
261
+ }
262
+ async send(method, url, dataSchema, body, options) {
263
+ const headers = this.buildHeaders(body !== void 0, options?.headers);
264
+ const serializedBody = body !== void 0 ? JSON.stringify(body) : void 0;
265
+ const safeToRetry = options?.idempotent ?? method === "GET";
266
+ const maxAttempts = this.config.maxRetries + 1;
267
+ let lastError;
268
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
269
+ const isLastAttempt = attempt === maxAttempts - 1;
270
+ await this.config.onRequest?.({ method, url, headers, body: serializedBody });
271
+ const started = nowMs();
272
+ let res;
273
+ try {
274
+ res = await this.fetchWithTimeout(method, url, headers, serializedBody, options);
275
+ } catch (err) {
276
+ lastError = wrapNetworkError(err, url, method);
277
+ const aborted = options?.signal?.aborted === true;
278
+ const isTimeout = err instanceof SalesdockTimeoutError;
279
+ if (!aborted && !isTimeout && safeToRetry && !isLastAttempt) {
280
+ await sleep(this.backoffDelay(attempt, void 0));
281
+ continue;
282
+ }
283
+ throw lastError;
284
+ }
285
+ const durationMs = nowMs() - started;
286
+ await this.config.onResponse?.({
287
+ method,
288
+ url,
289
+ status: res.status,
290
+ durationMs
291
+ });
292
+ const { parsedBody, rawText } = await readBody(res);
293
+ const success = res.ok && !(parsedBody && typeof parsedBody === "object" && parsedBody.success === false);
294
+ if (success) {
295
+ if (parsedBody === void 0) {
296
+ if (!rawText) return void 0;
297
+ throw new SalesdockError("Salesdock returned a non-JSON success response body.", {
298
+ status: res.status,
299
+ url,
300
+ method,
301
+ body: rawText
302
+ });
303
+ }
304
+ return this.validateResponse(dataSchema, parsedBody, url, method);
305
+ }
306
+ const retryAfterMs = parseRetryAfter(res.headers.get("retry-after"));
307
+ const statusRetryable = res.status === 429 || RETRYABLE_5XX.has(res.status) && safeToRetry;
308
+ if (statusRetryable && !isLastAttempt) {
309
+ await sleep(this.backoffDelay(attempt, retryAfterMs));
310
+ continue;
311
+ }
312
+ throw errorFromResponse(res.status, parsedBody ?? rawText, {
313
+ url,
314
+ method,
315
+ retryAfterMs
316
+ });
317
+ }
318
+ throw lastError instanceof Error ? lastError : new SalesdockConnectionError("Request failed", { url, method });
319
+ }
320
+ validateResponse(dataSchema, parsedBody, url, method) {
321
+ if (!this.config.validateResponses) {
322
+ if (parsedBody && typeof parsedBody === "object" && "data" in parsedBody) {
323
+ return parsedBody.data;
324
+ }
325
+ return parsedBody;
326
+ }
327
+ const schema = envelopeSchema(dataSchema);
328
+ const result = schema.safeParse(parsedBody);
329
+ if (!result.success) {
330
+ throw new SalesdockResponseValidationError(
331
+ "Salesdock response did not match the expected schema. If the API changed, you can disable this check with `validateResponses: false`.",
332
+ result.error,
333
+ { url, method, body: parsedBody }
334
+ );
335
+ }
336
+ return result.data.data;
337
+ }
338
+ buildHeaders(hasBody, extra) {
339
+ const headers = {
340
+ Accept: "application/json",
341
+ Authorization: `Bearer ${this.config.token}`,
342
+ ...this.config.headers
343
+ };
344
+ if (hasBody) headers["Content-Type"] = "application/json";
345
+ if (this.config.userAgent) {
346
+ headers["User-Agent"] = `salesdock-sdk/${SDK_VERSION} ${this.config.userAgent}`;
347
+ }
348
+ if (extra) Object.assign(headers, extra);
349
+ return headers;
350
+ }
351
+ async fetchWithTimeout(method, url, headers, body, options) {
352
+ const timeout = options?.timeout ?? this.config.timeout;
353
+ const controller = timeout > 0 ? new AbortController() : void 0;
354
+ let timer;
355
+ let timedOut = false;
356
+ if (controller && timeout > 0) {
357
+ timer = setTimeout(() => {
358
+ timedOut = true;
359
+ controller.abort();
360
+ }, timeout);
361
+ }
362
+ const onExternalAbort = () => controller?.abort();
363
+ if (options?.signal) {
364
+ if (options.signal.aborted) controller?.abort();
365
+ else options.signal.addEventListener("abort", onExternalAbort, { once: true });
366
+ }
367
+ try {
368
+ const signal = controller?.signal ?? options?.signal;
369
+ return await this.config.fetch(url, {
370
+ method,
371
+ headers,
372
+ body,
373
+ signal
374
+ });
375
+ } catch (err) {
376
+ if (timedOut) {
377
+ throw new SalesdockTimeoutError(`Request timed out after ${timeout}ms`, {
378
+ url,
379
+ method,
380
+ cause: err
381
+ });
382
+ }
383
+ throw err;
384
+ } finally {
385
+ if (timer) clearTimeout(timer);
386
+ if (options?.signal) options.signal.removeEventListener("abort", onExternalAbort);
387
+ }
388
+ }
389
+ backoffDelay(attempt, retryAfterMs) {
390
+ if (retryAfterMs !== void 0) return retryAfterMs;
391
+ const base = this.config.retryDelayMs * Math.pow(2, attempt);
392
+ const jitter = base * 0.25 * Math.random();
393
+ return Math.round(base + jitter);
394
+ }
395
+ };
396
+ function buildQueryString(query) {
397
+ if (!query) return "";
398
+ const params = new URLSearchParams();
399
+ for (const [key, value] of Object.entries(query)) {
400
+ if (value === null || value === void 0) continue;
401
+ if (Array.isArray(value)) {
402
+ for (const v of value) {
403
+ if (v === null || v === void 0) continue;
404
+ params.append(`${key}[]`, String(v));
405
+ }
406
+ } else {
407
+ params.append(key, String(value));
408
+ }
409
+ }
410
+ return params.toString();
411
+ }
412
+ async function readBody(res) {
413
+ let rawText = "";
414
+ try {
415
+ rawText = await res.text();
416
+ } catch {
417
+ return { parsedBody: void 0, rawText: "" };
418
+ }
419
+ if (!rawText) return { parsedBody: void 0, rawText };
420
+ try {
421
+ return { parsedBody: JSON.parse(rawText), rawText };
422
+ } catch {
423
+ return { parsedBody: void 0, rawText };
424
+ }
425
+ }
426
+ function parseRetryAfter(value) {
427
+ if (!value) return void 0;
428
+ const seconds = Number(value);
429
+ if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1e3);
430
+ const date = Date.parse(value);
431
+ if (!Number.isNaN(date)) return Math.max(0, date - Date.now());
432
+ return void 0;
433
+ }
434
+ function wrapNetworkError(err, url, method) {
435
+ if (err instanceof SalesdockTimeoutError) return err;
436
+ return new SalesdockConnectionError(
437
+ err instanceof Error ? err.message : "Network request failed",
438
+ { url, method, cause: err }
439
+ );
440
+ }
441
+ function sleep(ms) {
442
+ return new Promise((resolve) => setTimeout(resolve, ms));
443
+ }
444
+ function nowMs() {
445
+ return Date.now();
446
+ }
447
+
448
+ // src/resources/base.ts
449
+ var BaseResource = class {
450
+ constructor(http, config) {
451
+ this.http = http;
452
+ this.config = config;
453
+ }
454
+ /** Resolve the scope segment for a call (per-call override beats config). */
455
+ scope(options) {
456
+ return options?.scope ?? this.config.scope;
457
+ }
458
+ /**
459
+ * Validate request input against a Zod schema when request validation is
460
+ * enabled, returning the parsed value. Throws
461
+ * {@link SalesdockInvalidRequestError} on failure (before any network call).
462
+ */
463
+ parseInput(schema, value, label) {
464
+ if (!this.config.validateRequests) return value;
465
+ const result = schema.safeParse(value);
466
+ if (!result.success) {
467
+ throw new SalesdockInvalidRequestError(
468
+ `Invalid input for ${label}: ${summarize(result.error)}`,
469
+ result.error
470
+ );
471
+ }
472
+ return result.data;
473
+ }
474
+ };
475
+ function summarize(error) {
476
+ return error.issues.slice(0, 5).map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ");
477
+ }
478
+
479
+ // src/core/pagination.ts
480
+ var OffsetPage = class _OffsetPage {
481
+ constructor(meta, loader) {
482
+ this.loader = loader;
483
+ this.meta = meta;
484
+ this.items = meta.data ?? [];
485
+ }
486
+ get currentPage() {
487
+ return this.meta.current_page;
488
+ }
489
+ get lastPage() {
490
+ return this.meta.last_page;
491
+ }
492
+ get perPage() {
493
+ const n = Number(this.meta.per_page);
494
+ return Number.isFinite(n) ? n : 0;
495
+ }
496
+ get total() {
497
+ return this.meta.total;
498
+ }
499
+ get hasNextPage() {
500
+ return Boolean(this.meta.next_page_url);
501
+ }
502
+ get hasPrevPage() {
503
+ return Boolean(this.meta.prev_page_url);
504
+ }
505
+ /** Fetch the next page, or `null` if there is none. */
506
+ async nextPage() {
507
+ if (!this.meta.next_page_url) return null;
508
+ const meta = await this.loader(this.meta.next_page_url);
509
+ return new _OffsetPage(meta, this.loader);
510
+ }
511
+ /** Fetch the previous page, or `null` if there is none. */
512
+ async prevPage() {
513
+ if (!this.meta.prev_page_url) return null;
514
+ const meta = await this.loader(this.meta.prev_page_url);
515
+ return new _OffsetPage(meta, this.loader);
516
+ }
517
+ /** Collect every item across this and all following pages into one array. */
518
+ async all() {
519
+ const out = [];
520
+ for await (const item of this) out.push(item);
521
+ return out;
522
+ }
523
+ /** Async-iterate items across this and all subsequent pages. */
524
+ async *[Symbol.asyncIterator]() {
525
+ let page = this;
526
+ while (page) {
527
+ for (const item of page.items) yield item;
528
+ page = await page.nextPage();
529
+ }
530
+ }
531
+ };
532
+ var CursorPage = class _CursorPage {
533
+ constructor(meta, loader) {
534
+ this.loader = loader;
535
+ this.meta = meta;
536
+ this.items = meta.data ?? [];
537
+ }
538
+ get perPage() {
539
+ const n = Number(this.meta.per_page);
540
+ return Number.isFinite(n) ? n : 0;
541
+ }
542
+ get nextCursor() {
543
+ return this.meta.next_cursor ?? null;
544
+ }
545
+ get prevCursor() {
546
+ return this.meta.prev_cursor ?? null;
547
+ }
548
+ get hasNextPage() {
549
+ return Boolean(this.meta.next_page_url);
550
+ }
551
+ get hasPrevPage() {
552
+ return Boolean(this.meta.prev_page_url);
553
+ }
554
+ /** Fetch the next page, or `null` if there is none. */
555
+ async nextPage() {
556
+ if (!this.meta.next_page_url) return null;
557
+ const meta = await this.loader(this.meta.next_page_url);
558
+ return new _CursorPage(meta, this.loader);
559
+ }
560
+ /** Fetch the previous page, or `null` if there is none. */
561
+ async prevPage() {
562
+ if (!this.meta.prev_page_url) return null;
563
+ const meta = await this.loader(this.meta.prev_page_url);
564
+ return new _CursorPage(meta, this.loader);
565
+ }
566
+ /** Collect every item across this and all following pages into one array. */
567
+ async all() {
568
+ const out = [];
569
+ for await (const item of this) out.push(item);
570
+ return out;
571
+ }
572
+ /** Async-iterate items across this and all subsequent pages. */
573
+ async *[Symbol.asyncIterator]() {
574
+ let page = this;
575
+ while (page) {
576
+ for (const item of page.items) yield item;
577
+ page = await page.nextPage();
578
+ }
579
+ }
580
+ };
581
+ async function fetchOffsetPage(http, itemSchema, segments, query, options) {
582
+ const schema = offsetPaginatedSchema(itemSchema);
583
+ const loader = (url) => http.request({
584
+ method: "GET",
585
+ segments,
586
+ dataSchema: schema,
587
+ query: mergePageQuery(query, url),
588
+ options
589
+ });
590
+ const meta = await http.request({
591
+ method: "GET",
592
+ segments,
593
+ dataSchema: schema,
594
+ query,
595
+ options
596
+ });
597
+ return new OffsetPage(meta, loader);
598
+ }
599
+ async function fetchCursorPage(http, itemSchema, segments, query, options) {
600
+ const schema = cursorPaginatedSchema(itemSchema);
601
+ const loader = (url) => http.request({
602
+ method: "GET",
603
+ segments,
604
+ dataSchema: schema,
605
+ query: mergePageQuery(query, url),
606
+ options
607
+ });
608
+ const meta = await http.request({
609
+ method: "GET",
610
+ segments,
611
+ dataSchema: schema,
612
+ query,
613
+ options
614
+ });
615
+ return new CursorPage(meta, loader);
616
+ }
617
+ function mergePageQuery(original, pageUrl) {
618
+ const out = { ...original ?? {} };
619
+ let search;
620
+ try {
621
+ search = new URL(pageUrl).searchParams;
622
+ } catch {
623
+ return out;
624
+ }
625
+ for (const rawKey of new Set(search.keys())) {
626
+ const key = rawKey.endsWith("[]") ? rawKey.slice(0, -2) : rawKey;
627
+ const all = search.getAll(rawKey);
628
+ out[key] = rawKey.endsWith("[]") || all.length > 1 ? all : all[0];
629
+ }
630
+ return out;
631
+ }
632
+
633
+ // src/resources/sales.ts
634
+ var CreateSaleResultSchema = loose({ sale_id: idSchema });
635
+ var MutateSaleResultSchema = loose({ sale_id: idSchema });
636
+ var saleCreateBaseShape = {
637
+ transaction_type: z.enum(["offer", "order"]).optional(),
638
+ sale_channel: z.string().optional(),
639
+ product_id: z.union([z.string(), z.number()]).optional(),
640
+ // Customer
641
+ gender: z.string().optional(),
642
+ firstname: z.string().optional(),
643
+ lastname: z.string().optional(),
644
+ birthdate: z.string().nullable().optional(),
645
+ email: z.string().optional(),
646
+ phone: z.string().optional(),
647
+ contact_person: z.string().nullable().optional(),
648
+ company_name: z.string().nullable().optional(),
649
+ company_coc: z.string().nullable().optional(),
650
+ company_coc_branch_number: z.string().nullable().optional(),
651
+ company_vat: z.string().nullable().optional(),
652
+ iban: z.string().optional(),
653
+ iban_holder: z.string().optional(),
654
+ business: z.union([z.string(), z.number(), z.boolean()]).optional(),
655
+ // Address
656
+ postcode: z.string().optional(),
657
+ housenumber: z.union([z.string(), z.number()]).optional(),
658
+ suffix: z.string().nullable().optional(),
659
+ streetname: z.string().optional(),
660
+ city: z.string().optional(),
661
+ // Connection address
662
+ connection_postcode: z.string().optional(),
663
+ connection_housenumber: z.union([z.string(), z.number()]).optional(),
664
+ connection_suffix: z.string().nullable().optional(),
665
+ connection_streetname: z.string().optional(),
666
+ connection_city: z.string().optional(),
667
+ // Misc
668
+ valid_till: z.string().optional(),
669
+ signature: z.string().optional(),
670
+ initial_user_firstname: z.string().optional(),
671
+ initial_user_lastname: z.string().optional(),
672
+ initial_organisation_name: z.string().optional(),
673
+ // Free-form question answers and agreement acceptances (identifier -> value)
674
+ questionData: z.record(z.string(), z.unknown()).optional(),
675
+ agreements: z.record(z.string(), z.unknown()).optional()
676
+ };
677
+ var energyFieldsShape = {
678
+ type: z.string().optional(),
679
+ has_return: z.union([z.string(), z.number()]).optional(),
680
+ building_function: z.union([z.string(), z.number()]).optional(),
681
+ return: z.union([z.string(), z.number()]).optional(),
682
+ return_e_high: z.union([z.string(), z.number()]).optional(),
683
+ return_e_low: z.union([z.string(), z.number()]).optional(),
684
+ usage_e_single: z.union([z.string(), z.number()]).nullable().optional(),
685
+ usage_e_high: z.union([z.string(), z.number()]).nullable().optional(),
686
+ usage_e_low: z.union([z.string(), z.number()]).nullable().optional(),
687
+ usage_g: z.union([z.string(), z.number()]).nullable().optional(),
688
+ tarifftype: z.union([z.string(), z.number()]).optional(),
689
+ e_gridoperator: z.string().optional(),
690
+ g_gridoperator: z.string().optional(),
691
+ e_connection_type: z.string().optional(),
692
+ g_connection_type: z.string().optional(),
693
+ g_region: z.string().optional(),
694
+ electricity_ean: z.string().nullable().optional(),
695
+ gas_ean: z.string().nullable().optional(),
696
+ delivery_mainly_private: z.union([z.string(), z.number()]).optional()
697
+ };
698
+ var EnergyNlSaleInputSchema = z.object({ ...saleCreateBaseShape, ...energyFieldsShape }).passthrough();
699
+ var EnergyBeSaleInputSchema = z.object({
700
+ ...saleCreateBaseShape,
701
+ ...energyFieldsShape,
702
+ e_measurement_frequency: z.string().optional(),
703
+ g_measurement_frequency: z.string().optional(),
704
+ exclusive_night: z.union([z.string(), z.number()]).optional(),
705
+ usage_e_exclusive: z.union([z.string(), z.number()]).optional(),
706
+ region: z.string().optional(),
707
+ e_grid_operator: z.string().optional(),
708
+ g_grid_operator: z.string().optional()
709
+ }).passthrough();
710
+ var relatedProductsSchema = z.union([z.record(z.string(), z.unknown()), z.array(z.unknown())]).optional();
711
+ var TelecomSaleInputSchema = z.object({ ...saleCreateBaseShape, related_products: relatedProductsSchema }).passthrough();
712
+ var HostedVoiceSaleInputSchema = z.object({
713
+ ...saleCreateBaseShape,
714
+ includes_internet: z.union([z.string(), z.number()]).optional(),
715
+ related_products: relatedProductsSchema
716
+ }).passthrough();
717
+ var SolarSaleInputSchema = z.object({
718
+ ...saleCreateBaseShape,
719
+ sell_type: z.string().optional(),
720
+ usage: z.union([z.string(), z.number()]).optional(),
721
+ building_type: z.string().optional(),
722
+ household_size: z.union([z.string(), z.number()]).optional(),
723
+ address: z.string().optional(),
724
+ country: z.string().optional(),
725
+ area: z.union([z.string(), z.number()]).optional(),
726
+ panel_product: z.union([z.string(), z.number()]).optional(),
727
+ panel_count: z.union([z.string(), z.number()]).optional(),
728
+ option_products: z.array(z.unknown()).optional()
729
+ }).passthrough();
730
+ var HeatPumpSaleInputSchema = z.object({
731
+ ...saleCreateBaseShape,
732
+ sell_type: z.string().optional(),
733
+ number_of_persons: z.union([z.string(), z.number()]).optional(),
734
+ electricity_usage: z.union([z.string(), z.number()]).optional(),
735
+ gas_usage: z.union([z.string(), z.number()]).optional(),
736
+ heating_system: z.string().optional(),
737
+ gas_usage_tap_water_per_person: z.union([z.string(), z.number()]).optional()
738
+ }).passthrough();
739
+ var DefaultSaleInputSchema = z.object(saleCreateBaseShape).passthrough();
740
+ var MultiProductSaleInputSchema = z.object({
741
+ ...saleCreateBaseShape,
742
+ related_products: z.array(
743
+ z.object({
744
+ product_id: z.union([z.string(), z.number()]),
745
+ quantity: z.union([z.string(), z.number()]).optional(),
746
+ section_identifier: z.string().optional()
747
+ }).passthrough()
748
+ ).optional()
749
+ }).passthrough();
750
+ var mutationBlockSchema = z.object({
751
+ delete: z.array(z.union([z.string(), z.number()])).optional(),
752
+ upsert: z.unknown().optional()
753
+ }).passthrough();
754
+ var UpdateSaleInputSchema = z.object({
755
+ product_id: z.union([z.string(), z.number()]).optional(),
756
+ valid_till: z.string().optional(),
757
+ customer: z.object({
758
+ business: z.union([z.boolean(), z.string(), z.number()]).optional(),
759
+ gender: z.string().optional(),
760
+ firstname: z.string().optional(),
761
+ lastname: z.string().optional(),
762
+ birthdate: z.string().nullable().optional(),
763
+ email: z.string().optional(),
764
+ phone: z.string().nullable().optional(),
765
+ company_name: z.string().nullable().optional(),
766
+ contact_person: z.string().nullable().optional(),
767
+ coc: z.string().nullable().optional(),
768
+ vat: z.string().nullable().optional(),
769
+ address: z.record(z.string(), z.unknown()).optional(),
770
+ correspondence_address: z.record(z.string(), z.unknown()).optional()
771
+ }).passthrough().optional(),
772
+ product_questions: mutationBlockSchema.optional(),
773
+ agreements: mutationBlockSchema.optional()
774
+ }).passthrough();
775
+ var UpdateEnergyProductInputSchema = z.object({
776
+ type: z.string().optional(),
777
+ active: z.union([z.string(), z.number()]).optional(),
778
+ valid_from: z.string().optional(),
779
+ valid_till: z.string().optional(),
780
+ tariff_single: z.string().optional(),
781
+ tariff_high: z.string().optional(),
782
+ tariff_low: z.string().optional(),
783
+ tariff_high_t2: z.string().optional(),
784
+ tariff_low_t2: z.string().optional(),
785
+ tariff_return: z.string().optional(),
786
+ tariff_return_high: z.string().optional(),
787
+ tariff_return_low: z.string().optional(),
788
+ tariff_fixed_e: z.string().optional(),
789
+ g_region_tax_level: z.string().optional(),
790
+ tariff_g: z.string().optional(),
791
+ tariff_g_g2: z.string().optional(),
792
+ tariff_fixed_g: z.string().optional(),
793
+ product_type: z.string().optional()
794
+ }).passthrough();
795
+ var UpdateSaleFieldsInputSchema = z.record(z.string(), z.unknown());
796
+ var CreateOptinInputSchema = z.record(z.string(), z.unknown());
797
+ var SaleListItemSchema = loose({
798
+ id: idSchema,
799
+ user_id: nullish(idSchema),
800
+ type: nullish(z.string()),
801
+ sub_type: nullish(z.string()),
802
+ offer: nullish(z.unknown()),
803
+ offer_accepted: nullish(z.unknown()),
804
+ status: nullish(z.union([z.string(), statusSchema])),
805
+ verification: nullish(z.unknown()),
806
+ flow_id: nullish(idSchema),
807
+ product_id: nullish(idSchema),
808
+ incoming_id: nullish(idSchema),
809
+ created_at: nullish(z.string()),
810
+ finalized_at: nullish(z.string()),
811
+ updated_at: nullish(z.string()),
812
+ valid_till: nullish(z.string()),
813
+ firstname: nullish(z.string()),
814
+ lastname: nullish(z.string()),
815
+ email: nullish(z.string()),
816
+ phone: nullish(z.string()),
817
+ product_name: nullish(z.string()),
818
+ supplier_name: nullish(z.string()),
819
+ lead_id: nullish(idSchema),
820
+ relation_id: nullish(idSchema)
821
+ });
822
+ var SaleSchema = loose({
823
+ id: idSchema,
824
+ type: nullish(z.string()),
825
+ status: statusSchema.optional(),
826
+ offer_accepted: nullish(z.boolean()),
827
+ offer_valid_till: nullish(z.string()),
828
+ created_at: nullish(z.string()),
829
+ finalized_at: nullish(z.string()),
830
+ updated_at: nullish(z.string()),
831
+ channel: nullish(z.string()),
832
+ source: nullish(z.string()),
833
+ customer: customerSchema.optional()
834
+ });
835
+ var SaleExportRowSchema = z.record(z.string(), z.unknown());
836
+ var FlowListItemSchema = loose({
837
+ id: idSchema,
838
+ title: nullish(z.string()),
839
+ type: nullish(z.string()),
840
+ identifier: nullish(z.string()),
841
+ created_at: nullish(z.string()),
842
+ updated_at: nullish(z.string())
843
+ });
844
+ var FlowSchema = loose({
845
+ id: idSchema,
846
+ title: nullish(z.string()),
847
+ type: nullish(z.string()),
848
+ identifier: nullish(z.string()),
849
+ transaction_type: nullish(z.string()),
850
+ verification_method: nullish(z.string()),
851
+ created_at: nullish(z.string()),
852
+ updated_at: nullish(z.string())
853
+ });
854
+ var ProductQuestionListItemSchema = loose({
855
+ id: idSchema,
856
+ name: nullish(z.string()),
857
+ identifier: nullish(z.string()),
858
+ input_type: nullish(z.string()),
859
+ description: nullish(z.string())
860
+ });
861
+ var ProductQuestionSchema = loose({
862
+ id: idSchema,
863
+ name: nullish(z.string()),
864
+ identifier: nullish(z.string()),
865
+ input_type: nullish(z.string()),
866
+ description: nullish(z.string()),
867
+ required: nullish(z.unknown()),
868
+ visible: nullish(z.unknown()),
869
+ options: nullish(z.unknown()),
870
+ default_value: nullish(z.unknown()),
871
+ created_at: nullish(z.string()),
872
+ updated_at: nullish(z.string())
873
+ });
874
+ var AgreementListItemSchema = loose({
875
+ id: idSchema,
876
+ identifier: nullish(z.string()),
877
+ name: nullish(z.string()),
878
+ text: nullish(z.string())
879
+ });
880
+ var AgreementSchema = loose({
881
+ id: idSchema,
882
+ account_id: nullish(idSchema),
883
+ name: nullish(z.string()),
884
+ identifier: nullish(z.string()),
885
+ text: nullish(z.string()),
886
+ description: nullish(z.string()),
887
+ type: nullish(z.string()),
888
+ required: nullish(z.unknown()),
889
+ created_at: nullish(z.string())
890
+ });
891
+ var EnergyProductSchema = loose({
892
+ id: idSchema,
893
+ name: nullish(z.string()),
894
+ identifier: nullish(z.string()),
895
+ supplier_id: nullish(idSchema),
896
+ type: nullish(z.string()),
897
+ business: nullish(z.union([z.string(), z.number(), z.boolean()])),
898
+ cost_specifications: nullish(z.unknown()),
899
+ valid_from: nullish(z.string()),
900
+ valid_till: nullish(z.string())
901
+ });
902
+ var SaleStatusSchema = loose({
903
+ source: nullish(z.string()),
904
+ id: nullish(idSchema),
905
+ name: nullish(z.string()),
906
+ text: nullish(z.string()),
907
+ type: nullish(z.string()),
908
+ source_data: nullish(z.unknown())
909
+ });
910
+ var SaleDocumentSchema = loose({
911
+ name: nullish(z.string()),
912
+ location: nullish(z.string())
913
+ });
914
+ var SaleHistoryEntrySchema = loose({
915
+ type: nullish(z.string()),
916
+ modified_at: nullish(z.string()),
917
+ previous_status: nullish(z.unknown()),
918
+ new_status: nullish(z.unknown()),
919
+ remark: nullish(z.string()),
920
+ user: nullish(z.unknown()),
921
+ type_data: nullish(z.unknown())
922
+ });
923
+ var SaleProductsSchema = loose({
924
+ sale_id: idSchema,
925
+ products: nullish(z.unknown()),
926
+ additional_costs: nullish(z.unknown()),
927
+ discounts: nullish(z.unknown()),
928
+ totals: nullish(z.unknown())
929
+ });
930
+ var SaleOfLeadSchema = loose({ id: idSchema });
931
+ var SaleContractSchema = loose({
932
+ id: idSchema,
933
+ contract: loose({ content: nullish(z.string()) }).optional()
934
+ });
935
+ var EnergyUsageEstimationSchema = loose({
936
+ type: nullish(z.string()),
937
+ e_single: nullish(z.union([z.string(), z.number()])),
938
+ e_high: nullish(z.union([z.string(), z.number()])),
939
+ e_low: nullish(z.union([z.string(), z.number()])),
940
+ gas: nullish(z.union([z.string(), z.number()]))
941
+ });
942
+ var PanelsEstimationSchema = loose({
943
+ number_of_panels: nullish(z.union([z.string(), z.number()]))
944
+ });
945
+ var TelecomCompareSchema = loose({
946
+ address: nullish(z.unknown()),
947
+ bandwidth: nullish(z.unknown()),
948
+ products: nullish(z.unknown()),
949
+ options: nullish(z.unknown())
950
+ });
951
+ var SolarComparePackageSchema = loose({ packages: nullish(z.unknown()) });
952
+ var SaleMutationsBase = class extends BaseResource {
953
+ /** PATCH a sale proposal: `{scope}/proposal/{saleId}`. */
954
+ patchProposal(saleId, input, label, options) {
955
+ const body = this.parseInput(UpdateSaleInputSchema, input, label);
956
+ return this.http.request({
957
+ method: "PATCH",
958
+ segments: [this.scope(options), "proposal", saleId],
959
+ dataSchema: MutateSaleResultSchema,
960
+ body,
961
+ options
962
+ });
963
+ }
964
+ /** PATCH a finalized sale: `account/sales/{saleId}` (always `account` scope). */
965
+ patchFinalized(saleId, input, label, options) {
966
+ const body = this.parseInput(UpdateSaleInputSchema, input, label);
967
+ return this.http.request({
968
+ method: "PATCH",
969
+ segments: ["account", "sales", saleId],
970
+ dataSchema: MutateSaleResultSchema,
971
+ body,
972
+ options
973
+ });
974
+ }
975
+ };
976
+ var EnergyNlClient = class extends BaseResource {
977
+ /**
978
+ * Create an energy sale (offer or order) on a NL flow. `flowType` is your
979
+ * flow's type identifier and `flowIdentifier` the flow identifier.
980
+ */
981
+ create(flowType, flowIdentifier, input, options) {
982
+ const body = this.parseInput(EnergyNlSaleInputSchema, input, "sales.energy.nl.create");
983
+ return this.http.request({
984
+ method: "POST",
985
+ segments: ["sales", "flow", flowType, flowIdentifier],
986
+ dataSchema: CreateSaleResultSchema,
987
+ body,
988
+ options
989
+ });
990
+ }
991
+ /** List energy products with tariff + calculation for the given address/usage. */
992
+ listProducts(params, options) {
993
+ return this.http.request({
994
+ method: "GET",
995
+ segments: ["user", "products", "energy"],
996
+ dataSchema: z.array(EnergyProductSchema),
997
+ query: params,
998
+ options
999
+ });
1000
+ }
1001
+ /** Get a single energy product (by id) with tariff + calculation. */
1002
+ getProduct(productId, params, options) {
1003
+ return this.http.request({
1004
+ method: "GET",
1005
+ segments: ["user", "products", productId, "energy"],
1006
+ dataSchema: EnergyProductSchema,
1007
+ query: params,
1008
+ options
1009
+ });
1010
+ }
1011
+ /** Update an energy product's tariffs. */
1012
+ updateProduct(productId, input, options) {
1013
+ const body = this.parseInput(
1014
+ UpdateEnergyProductInputSchema,
1015
+ input,
1016
+ "sales.energy.nl.updateProduct"
1017
+ );
1018
+ return this.http.request({
1019
+ method: "PUT",
1020
+ segments: ["account", "products", productId, "energy"],
1021
+ dataSchema: z.unknown(),
1022
+ body,
1023
+ options
1024
+ });
1025
+ }
1026
+ };
1027
+ var EnergyBeClient = class extends BaseResource {
1028
+ /** Create an energy sale on a BE flow. */
1029
+ create(flowType, flowIdentifier, input, options) {
1030
+ const body = this.parseInput(EnergyBeSaleInputSchema, input, "sales.energy.be.create");
1031
+ return this.http.request({
1032
+ method: "POST",
1033
+ segments: ["sales", "flow", flowType, flowIdentifier],
1034
+ dataSchema: CreateSaleResultSchema,
1035
+ body,
1036
+ options
1037
+ });
1038
+ }
1039
+ /** List BE energy products with tariffs + calculations. */
1040
+ listProducts(params, options) {
1041
+ return this.http.request({
1042
+ method: "GET",
1043
+ segments: ["user", "products", "energy-be"],
1044
+ dataSchema: z.array(EnergyProductSchema),
1045
+ query: params,
1046
+ options
1047
+ });
1048
+ }
1049
+ };
1050
+ var EnergyClient = class extends BaseResource {
1051
+ constructor(http, config) {
1052
+ super(http, config);
1053
+ this.nl = new EnergyNlClient(http, config);
1054
+ this.be = new EnergyBeClient(http, config);
1055
+ }
1056
+ /** List energy sales (offset-paginated export-style rows). Honors the scope. */
1057
+ listSales(params = {}, options) {
1058
+ return fetchOffsetPage(
1059
+ this.http,
1060
+ SaleExportRowSchema,
1061
+ [this.scope(options), "sales", "energy"],
1062
+ params,
1063
+ options
1064
+ );
1065
+ }
1066
+ /** Estimate yearly energy usage for a household/business. */
1067
+ estimateUsage(params = {}, options) {
1068
+ return this.http.request({
1069
+ method: "GET",
1070
+ segments: ["user", "energy", "estimation"],
1071
+ dataSchema: EnergyUsageEstimationSchema,
1072
+ query: params,
1073
+ options
1074
+ });
1075
+ }
1076
+ };
1077
+ var TelecomClient = class extends SaleMutationsBase {
1078
+ /** Create a telecom sale (offer or order). */
1079
+ create(flowType, flowIdentifier, input, options) {
1080
+ const body = this.parseInput(TelecomSaleInputSchema, input, "sales.telecom.create");
1081
+ return this.http.request({
1082
+ method: "POST",
1083
+ segments: ["sales", "flow", flowType, flowIdentifier],
1084
+ dataSchema: CreateSaleResultSchema,
1085
+ body,
1086
+ options
1087
+ });
1088
+ }
1089
+ /** Update a telecom sale proposal. Honors the configured scope. */
1090
+ updateProposal(saleId, input, options) {
1091
+ return this.patchProposal(saleId, input, "sales.telecom.updateProposal", options);
1092
+ }
1093
+ /** Update a finalized telecom sale (always `account` scope). */
1094
+ updateFinalized(saleId, input, options) {
1095
+ return this.patchFinalized(saleId, input, "sales.telecom.updateFinalized", options);
1096
+ }
1097
+ /** Compare telecom availability/products for an address (no scope). */
1098
+ compare(input, options) {
1099
+ return this.http.request({
1100
+ method: "POST",
1101
+ segments: ["telecom", "compare"],
1102
+ dataSchema: TelecomCompareSchema,
1103
+ body: input,
1104
+ options
1105
+ });
1106
+ }
1107
+ };
1108
+ var HostedVoiceClient = class extends BaseResource {
1109
+ /** Create a hosted-voice sale. */
1110
+ create(flowType, flowIdentifier, input, options) {
1111
+ const body = this.parseInput(HostedVoiceSaleInputSchema, input, "sales.hostedVoice.create");
1112
+ return this.http.request({
1113
+ method: "POST",
1114
+ segments: ["sales", "flow", flowType, flowIdentifier],
1115
+ dataSchema: CreateSaleResultSchema,
1116
+ body,
1117
+ options
1118
+ });
1119
+ }
1120
+ };
1121
+ var SolarClient = class extends BaseResource {
1122
+ /** Create a solar-panel sale (flow type is fixed to `solar-panels`). */
1123
+ create(flowIdentifier, input, options) {
1124
+ const body = this.parseInput(SolarSaleInputSchema, input, "sales.solar.create");
1125
+ return this.http.request({
1126
+ method: "POST",
1127
+ segments: ["sales", "flow", "solar-panels", flowIdentifier],
1128
+ dataSchema: CreateSaleResultSchema,
1129
+ body,
1130
+ options
1131
+ });
1132
+ }
1133
+ /** Estimate the number of solar panels that fit a roof (no scope). */
1134
+ estimatePanels(params = {}, options) {
1135
+ return this.http.request({
1136
+ method: "GET",
1137
+ segments: ["solar", "estimate-panels"],
1138
+ dataSchema: PanelsEstimationSchema,
1139
+ query: params,
1140
+ options
1141
+ });
1142
+ }
1143
+ /** Compare solar packages for a configuration (no scope). */
1144
+ compare(input, options) {
1145
+ return this.http.request({
1146
+ method: "POST",
1147
+ segments: ["solar", "compare"],
1148
+ dataSchema: z.array(SolarComparePackageSchema),
1149
+ body: input,
1150
+ options
1151
+ });
1152
+ }
1153
+ };
1154
+ var HeatPumpsClient = class extends SaleMutationsBase {
1155
+ /** Create a heat-pump sale (flow type is fixed to `heat-pump`). */
1156
+ create(flowIdentifier, input, options) {
1157
+ const body = this.parseInput(HeatPumpSaleInputSchema, input, "sales.heatPumps.create");
1158
+ return this.http.request({
1159
+ method: "POST",
1160
+ segments: ["sales", "flow", "heat-pump", flowIdentifier],
1161
+ dataSchema: CreateSaleResultSchema,
1162
+ body,
1163
+ options
1164
+ });
1165
+ }
1166
+ /** Update a heat-pump sale proposal. Honors the configured scope. */
1167
+ updateProposal(saleId, input, options) {
1168
+ return this.patchProposal(saleId, input, "sales.heatPumps.updateProposal", options);
1169
+ }
1170
+ /** Update a finalized heat-pump sale (always `account` scope). */
1171
+ updateFinalized(saleId, input, options) {
1172
+ return this.patchFinalized(saleId, input, "sales.heatPumps.updateFinalized", options);
1173
+ }
1174
+ };
1175
+ var SalesClient = class extends SaleMutationsBase {
1176
+ constructor(http, config) {
1177
+ super(http, config);
1178
+ this.energy = new EnergyClient(http, config);
1179
+ this.telecom = new TelecomClient(http, config);
1180
+ this.hostedVoice = new HostedVoiceClient(http, config);
1181
+ this.solar = new SolarClient(http, config);
1182
+ this.heatPumps = new HeatPumpsClient(http, config);
1183
+ }
1184
+ /* ----------------------------- Sales listing ---------------------------- */
1185
+ /** List sales (offset-paginated). Honors the configured scope. */
1186
+ list(params = {}, options) {
1187
+ return fetchOffsetPage(
1188
+ this.http,
1189
+ SaleListItemSchema,
1190
+ [this.scope(options), "sales"],
1191
+ params,
1192
+ options
1193
+ );
1194
+ }
1195
+ /** Retrieve a single sale by id. Honors the configured scope. */
1196
+ get(saleId, options) {
1197
+ return this.http.request({
1198
+ method: "GET",
1199
+ segments: [this.scope(options), "sales", saleId],
1200
+ dataSchema: SaleSchema,
1201
+ options
1202
+ });
1203
+ }
1204
+ /** Retrieve a sale's signed contract (base64 PDF in `contract.content`). */
1205
+ getContract(saleId, options) {
1206
+ return this.http.request({
1207
+ method: "GET",
1208
+ segments: ["account", "sales", "contract", saleId],
1209
+ dataSchema: SaleContractSchema,
1210
+ options
1211
+ });
1212
+ }
1213
+ /** Retrieve the answers (question identifier -> value) given for a sale. */
1214
+ getAnswers(saleId, options) {
1215
+ return this.http.request({
1216
+ method: "GET",
1217
+ segments: [this.scope(options), "sales", "answers", saleId],
1218
+ dataSchema: z.record(z.string(), z.unknown()),
1219
+ options
1220
+ });
1221
+ }
1222
+ /** List sales rendered through an export template (offset-paginated rows). */
1223
+ listByExportTemplate(exportTemplate, params = {}, options) {
1224
+ return fetchOffsetPage(
1225
+ this.http,
1226
+ SaleExportRowSchema,
1227
+ ["account", "sales", "export", exportTemplate],
1228
+ params,
1229
+ options
1230
+ );
1231
+ }
1232
+ /* ------------------------------ Sale catalog ---------------------------- */
1233
+ /** List flows. Honors the configured scope. */
1234
+ listFlows(options) {
1235
+ return this.http.request({
1236
+ method: "GET",
1237
+ segments: [this.scope(options), "flows"],
1238
+ dataSchema: z.array(FlowListItemSchema),
1239
+ options
1240
+ });
1241
+ }
1242
+ /** Get a single flow by id. */
1243
+ getFlow(flowId, options) {
1244
+ return this.http.request({
1245
+ method: "GET",
1246
+ segments: [this.scope(options), "flows", flowId],
1247
+ dataSchema: FlowSchema,
1248
+ options
1249
+ });
1250
+ }
1251
+ /** List product questions. */
1252
+ listProductQuestions(options) {
1253
+ return this.http.request({
1254
+ method: "GET",
1255
+ segments: [this.scope(options), "productquestions"],
1256
+ dataSchema: z.array(ProductQuestionListItemSchema),
1257
+ options
1258
+ });
1259
+ }
1260
+ /** Get a single product question by id. */
1261
+ getProductQuestion(productQuestionId, options) {
1262
+ return this.http.request({
1263
+ method: "GET",
1264
+ segments: [this.scope(options), "productquestions", productQuestionId],
1265
+ dataSchema: ProductQuestionSchema,
1266
+ options
1267
+ });
1268
+ }
1269
+ /** List agreements. */
1270
+ listAgreements(options) {
1271
+ return this.http.request({
1272
+ method: "GET",
1273
+ segments: [this.scope(options), "agreements"],
1274
+ dataSchema: z.array(AgreementListItemSchema),
1275
+ options
1276
+ });
1277
+ }
1278
+ /** Get a single agreement by id. */
1279
+ getAgreement(agreementId, options) {
1280
+ return this.http.request({
1281
+ method: "GET",
1282
+ segments: [this.scope(options), "agreements", agreementId],
1283
+ dataSchema: AgreementSchema,
1284
+ options
1285
+ });
1286
+ }
1287
+ /* ----------------------------- Create sales ----------------------------- */
1288
+ /**
1289
+ * Low-level create-sale call: POST to `sales/flow/{flowType}/{flowIdentifier}`
1290
+ * with an arbitrary body. Prefer the typed helpers (`createDefault`,
1291
+ * `sales.energy.nl.create`, `sales.telecom.create`, ...) where they exist.
1292
+ */
1293
+ createSale(flowType, flowIdentifier, body, options) {
1294
+ return this.http.request({
1295
+ method: "POST",
1296
+ segments: ["sales", "flow", flowType, flowIdentifier],
1297
+ dataSchema: CreateSaleResultSchema,
1298
+ body,
1299
+ options
1300
+ });
1301
+ }
1302
+ /** Create a default (generic) sale. */
1303
+ createDefault(flowType, flowIdentifier, input, options) {
1304
+ const body = this.parseInput(DefaultSaleInputSchema, input, "sales.createDefault");
1305
+ return this.http.request({
1306
+ method: "POST",
1307
+ segments: ["sales", "flow", flowType, flowIdentifier],
1308
+ dataSchema: CreateSaleResultSchema,
1309
+ body,
1310
+ options
1311
+ });
1312
+ }
1313
+ /** Create a default sale with multiple related products. */
1314
+ createDefaultMultiple(flowType, flowIdentifier, input, options) {
1315
+ const body = this.parseInput(MultiProductSaleInputSchema, input, "sales.createDefaultMultiple");
1316
+ return this.http.request({
1317
+ method: "POST",
1318
+ segments: ["sales", "flow", flowType, flowIdentifier],
1319
+ dataSchema: CreateSaleResultSchema,
1320
+ body,
1321
+ options
1322
+ });
1323
+ }
1324
+ /** Update a default sale proposal. Honors the configured scope. */
1325
+ updateDefaultProposal(saleId, input, options) {
1326
+ return this.patchProposal(saleId, input, "sales.updateDefaultProposal", options);
1327
+ }
1328
+ /** Update a finalized default sale (always `account` scope). */
1329
+ updateDefaultFinalized(saleId, input, options) {
1330
+ return this.patchFinalized(saleId, input, "sales.updateDefaultFinalized", options);
1331
+ }
1332
+ /* ------------------------- Statuses & extra fields ---------------------- */
1333
+ /** List the available sale statuses. Honors the configured scope. */
1334
+ listStatuses(params = {}, options) {
1335
+ return this.http.request({
1336
+ method: "GET",
1337
+ segments: [this.scope(options), "statuses"],
1338
+ dataSchema: z.array(SaleStatusSchema),
1339
+ query: params,
1340
+ options
1341
+ });
1342
+ }
1343
+ /** Update a sale's status (always `account` scope). */
1344
+ updateStatus(saleId, params, options) {
1345
+ return this.http.request({
1346
+ method: "POST",
1347
+ segments: ["account", "sales", "updatestatus", saleId],
1348
+ dataSchema: z.unknown(),
1349
+ query: params,
1350
+ options
1351
+ });
1352
+ }
1353
+ /** Update a sale's status by the incoming id (always `account` scope). */
1354
+ updateStatusByIncoming(incomingId, params, options) {
1355
+ return this.http.request({
1356
+ method: "POST",
1357
+ segments: ["account", "sales", "updatestatus", "incoming", incomingId],
1358
+ dataSchema: z.unknown(),
1359
+ query: params,
1360
+ options
1361
+ });
1362
+ }
1363
+ /** Update a sale's extra field values (always `account` scope). */
1364
+ updateFields(saleId, fields, options) {
1365
+ const body = this.parseInput(UpdateSaleFieldsInputSchema, fields, "sales.updateFields");
1366
+ return this.http.request({
1367
+ method: "POST",
1368
+ segments: ["account", "sales", "updatefields", saleId],
1369
+ dataSchema: z.unknown(),
1370
+ body,
1371
+ options
1372
+ });
1373
+ }
1374
+ /** Update a sale's extra field values by incoming id (always `account` scope). */
1375
+ updateFieldsByIncoming(incomingId, fields, options) {
1376
+ const body = this.parseInput(
1377
+ UpdateSaleFieldsInputSchema,
1378
+ fields,
1379
+ "sales.updateFieldsByIncoming"
1380
+ );
1381
+ return this.http.request({
1382
+ method: "POST",
1383
+ segments: ["account", "sales", "updatefields", "incoming", incomingId],
1384
+ dataSchema: z.unknown(),
1385
+ body,
1386
+ options
1387
+ });
1388
+ }
1389
+ /** Cancel a sale (always `user` scope). */
1390
+ cancel(saleId, params, options) {
1391
+ return this.http.request({
1392
+ method: "POST",
1393
+ segments: ["user", "sales", "cancel", saleId],
1394
+ dataSchema: z.unknown(),
1395
+ query: params,
1396
+ options
1397
+ });
1398
+ }
1399
+ /* ------------------------------ Sale reads ------------------------------ */
1400
+ /** Get the sale linked to a lead. Honors the configured scope. */
1401
+ getOfLead(leadId, options) {
1402
+ return this.http.request({
1403
+ method: "GET",
1404
+ segments: [this.scope(options), "leads", leadId, "sale"],
1405
+ dataSchema: SaleOfLeadSchema,
1406
+ options
1407
+ });
1408
+ }
1409
+ /** Get a sale's products + totals breakdown. Honors the configured scope. */
1410
+ getProducts(saleId, options) {
1411
+ return this.http.request({
1412
+ method: "GET",
1413
+ segments: [this.scope(options), "sales", saleId, "products"],
1414
+ dataSchema: SaleProductsSchema,
1415
+ options
1416
+ });
1417
+ }
1418
+ /** Get the sale ids attached to a form instance. Honors the configured scope. */
1419
+ getOfFormInstance(formInstanceId, options) {
1420
+ return this.http.request({
1421
+ method: "GET",
1422
+ segments: [this.scope(options), "sales", "form_instance", formInstanceId],
1423
+ dataSchema: z.array(idSchema),
1424
+ options
1425
+ });
1426
+ }
1427
+ /** List a sale's documents (each with a download `location`). */
1428
+ getDocuments(saleId, options) {
1429
+ return this.http.request({
1430
+ method: "GET",
1431
+ segments: ["account", "sales", saleId, "documents"],
1432
+ dataSchema: z.array(SaleDocumentSchema),
1433
+ options
1434
+ });
1435
+ }
1436
+ /** Get a sale's change history (always `account` scope). */
1437
+ getHistory(saleId, options) {
1438
+ return this.http.request({
1439
+ method: "GET",
1440
+ segments: ["account", "sales", saleId, "history"],
1441
+ dataSchema: z.array(SaleHistoryEntrySchema),
1442
+ options
1443
+ });
1444
+ }
1445
+ /** Create an opt-in for a sale (always `account` scope). */
1446
+ createOptin(saleId, input = {}, options) {
1447
+ const body = this.parseInput(CreateOptinInputSchema, input, "sales.createOptin");
1448
+ return this.http.request({
1449
+ method: "POST",
1450
+ segments: ["account", "sales", saleId, "optin"],
1451
+ dataSchema: z.unknown(),
1452
+ body,
1453
+ options
1454
+ });
1455
+ }
1456
+ };
1457
+ var baseConceptFields = {
1458
+ /** The name of the dialer company in lower case (max 20 chars). */
1459
+ source: z.string(),
1460
+ /** A unique identifier for the record on the dialer platform. */
1461
+ source_id: z.union([z.string(), z.number()]),
1462
+ /** Gender of the customer: `"male"` or `"female"`. */
1463
+ gender: z.string().optional(),
1464
+ firstname: z.string().optional(),
1465
+ lastname: z.string().optional(),
1466
+ /** Date of birth in `dd-mm-yyyy` format. */
1467
+ birthdate: z.string().optional(),
1468
+ email: z.string().optional(),
1469
+ /** `1` for business, `0` for consumer. */
1470
+ customer_type: z.union([z.string(), z.number()]).optional(),
1471
+ company_name: z.string().optional(),
1472
+ contact_person: z.string().optional(),
1473
+ coc: z.string().optional(),
1474
+ postcode: z.string().optional(),
1475
+ housenumber: z.union([z.string(), z.number()]).optional(),
1476
+ suffix: z.string().optional(),
1477
+ streetname: z.string().optional(),
1478
+ city: z.string().optional(),
1479
+ /** Country code: `"NL"` or `"BE"`. */
1480
+ country: z.string().optional(),
1481
+ phone: z.string().optional(),
1482
+ mobile: z.string().optional()
1483
+ };
1484
+ var OptinChannelInputSchema = z.object({
1485
+ /** Channel type: `"email"` or `"phone"`. */
1486
+ type: z.string(),
1487
+ /** Email address or phone number, matching `type`. */
1488
+ value: z.string(),
1489
+ /** Topic(s) the customer has opted in for. */
1490
+ topic: z.string().optional(),
1491
+ /** When the opt-in was verified (phone double opt-in). */
1492
+ verified_at: z.string().optional(),
1493
+ /** IP address from which the opt-in was verified. */
1494
+ verified_ip: z.string().optional(),
1495
+ /** Verification method: `"sms"`, `"call"` or `"whatsapp"`. */
1496
+ verified_method: z.string().optional()
1497
+ }).passthrough();
1498
+ var CreateConceptTransactionSchema = z.object({
1499
+ ...baseConceptFields,
1500
+ /** Integer version of the source row (1-255). */
1501
+ source_version: z.union([z.string(), z.number()]).optional(),
1502
+ /** Arbitrary metadata associated with the source row. */
1503
+ source_metadata: z.unknown().optional()
1504
+ }).passthrough();
1505
+ var CreateConceptTransactionWithOptinSchema = z.object({
1506
+ ...baseConceptFields,
1507
+ source_version: z.union([z.string(), z.number()]).optional(),
1508
+ source_metadata: z.unknown().optional(),
1509
+ /** `1` to create an opt-in, `0` otherwise. */
1510
+ optin: z.union([z.string(), z.number()]).optional(),
1511
+ optin_source: z.string().optional(),
1512
+ /** When the opt-in was obtained (`yyyy-mm-dd HH:mm:ss`). */
1513
+ optin_obtained_at: z.string().optional(),
1514
+ optin_obtained_by: z.string().optional(),
1515
+ optin_obtained_system: z.string().optional(),
1516
+ optin_obtained_via_url: z.string().optional(),
1517
+ optin_client_ip: z.string().optional(),
1518
+ /** Until when the opt-in is valid (`yyyy-mm-dd HH:mm:ss`). */
1519
+ optin_valid_till: z.string().optional(),
1520
+ /** When the opt-in was withdrawn (`yyyy-mm-dd HH:mm:ss`). */
1521
+ optin_withdrawn_at: z.string().optional(),
1522
+ optin_remarks: z.string().optional(),
1523
+ optin_campaign_code: z.string().optional(),
1524
+ /** Proof of the opt-in as a base64 document plus its extension. */
1525
+ optin_proof: z.object({
1526
+ content: z.string().optional(),
1527
+ extension: z.string().optional()
1528
+ }).passthrough().optional(),
1529
+ /** The channels (at least one) the customer has opted in for. */
1530
+ optin_channels: z.array(OptinChannelInputSchema).optional()
1531
+ }).passthrough();
1532
+ var CreateConceptLeadSchema = z.object({ ...baseConceptFields }).passthrough();
1533
+ var ConceptTransactionResultSchema = loose({
1534
+ uuid: z.string(),
1535
+ order_url: nullish(z.string()),
1536
+ offer_url: nullish(z.string())
1537
+ });
1538
+ var ConceptLeadResultSchema = loose({
1539
+ uuid: z.string(),
1540
+ agenda_url: nullish(z.string()),
1541
+ lead_url: nullish(z.string())
1542
+ });
1543
+ var ConceptFieldSchema = loose({
1544
+ name: z.string(),
1545
+ type: nullish(z.string()),
1546
+ required: nullish(z.boolean()),
1547
+ description: nullish(z.string()),
1548
+ validations: z.array(z.string()).optional()
1549
+ });
1550
+ var ConceptFieldsSchema = loose({
1551
+ fields: z.array(ConceptFieldSchema),
1552
+ validators: z.record(z.string(), z.string()).optional()
1553
+ });
1554
+ var LastSaleSchema = loose({
1555
+ sale_id: idSchema
1556
+ });
1557
+ var ConceptTransactionSalesSchema = loose({
1558
+ sale_ids: z.array(idSchema)
1559
+ });
1560
+ var SaleViewUrlSchema = loose({
1561
+ admin: nullish(z.string()),
1562
+ reseller: nullish(z.string())
1563
+ });
1564
+ var DialerClient = class extends BaseResource {
1565
+ /** Create a concept transaction and get the prefilled order/offer URLs. */
1566
+ createConceptTransaction(input, options) {
1567
+ const body = this.parseInput(
1568
+ CreateConceptTransactionSchema,
1569
+ input,
1570
+ "dialer.createConceptTransaction"
1571
+ );
1572
+ return this.http.request({
1573
+ method: "POST",
1574
+ segments: ["account", "concepttransaction"],
1575
+ dataSchema: ConceptTransactionResultSchema,
1576
+ body,
1577
+ options
1578
+ });
1579
+ }
1580
+ /** Create a concept transaction together with opt-in information. */
1581
+ createConceptTransactionWithOptin(input, options) {
1582
+ const body = this.parseInput(
1583
+ CreateConceptTransactionWithOptinSchema,
1584
+ input,
1585
+ "dialer.createConceptTransactionWithOptin"
1586
+ );
1587
+ return this.http.request({
1588
+ method: "POST",
1589
+ segments: ["account", "concepttransaction"],
1590
+ dataSchema: ConceptTransactionResultSchema,
1591
+ body,
1592
+ options
1593
+ });
1594
+ }
1595
+ /** List the fields supported when creating a concept transaction. */
1596
+ getConceptTransactionFields(options) {
1597
+ return this.http.request({
1598
+ method: "GET",
1599
+ segments: ["account", "concepttransaction", "fields"],
1600
+ dataSchema: ConceptFieldsSchema,
1601
+ options
1602
+ });
1603
+ }
1604
+ /** List the concept-transaction fields including the opt-in fields. */
1605
+ getConceptTransactionFieldsWithOptin(options) {
1606
+ return this.http.request({
1607
+ method: "GET",
1608
+ segments: ["account", "concepttransaction", "fields", "optin"],
1609
+ dataSchema: ConceptFieldsSchema,
1610
+ options
1611
+ });
1612
+ }
1613
+ /** Create a concept lead and get the prefilled agenda/lead URLs. */
1614
+ createConceptLead(input, options) {
1615
+ const body = this.parseInput(CreateConceptLeadSchema, input, "dialer.createConceptLead");
1616
+ return this.http.request({
1617
+ method: "POST",
1618
+ segments: ["account", "conceptlead"],
1619
+ dataSchema: ConceptLeadResultSchema,
1620
+ body,
1621
+ options
1622
+ });
1623
+ }
1624
+ /** List the fields supported when creating a concept lead. */
1625
+ getConceptLeadFields(options) {
1626
+ return this.http.request({
1627
+ method: "GET",
1628
+ segments: ["account", "conceptlead", "fields"],
1629
+ dataSchema: ConceptFieldsSchema,
1630
+ options
1631
+ });
1632
+ }
1633
+ /**
1634
+ * Get the last sale id created from a concept transaction. At least one of
1635
+ * `source_id` or `uuid` must be provided.
1636
+ */
1637
+ getLastSale(source, params = {}, options) {
1638
+ return this.http.request({
1639
+ method: "GET",
1640
+ segments: ["account", "concepttransaction", "sale_id", source],
1641
+ dataSchema: LastSaleSchema,
1642
+ query: {
1643
+ source_id: params.source_id,
1644
+ uuid: params.uuid
1645
+ },
1646
+ options
1647
+ });
1648
+ }
1649
+ /**
1650
+ * Get all sale ids created from a concept transaction. At least one of
1651
+ * `source_id` or `uuid` must be provided.
1652
+ */
1653
+ getSales(source, params = {}, options) {
1654
+ return this.http.request({
1655
+ method: "GET",
1656
+ segments: ["account", "concepttransaction", "sales", source],
1657
+ dataSchema: ConceptTransactionSalesSchema,
1658
+ query: {
1659
+ source_id: params.source_id,
1660
+ uuid: params.uuid
1661
+ },
1662
+ options
1663
+ });
1664
+ }
1665
+ /** Get the admin/reseller URLs for viewing a sale by id. */
1666
+ getSaleViewUrl(saleId, options) {
1667
+ return this.http.request({
1668
+ method: "GET",
1669
+ segments: ["account", "sales", "url", saleId],
1670
+ dataSchema: SaleViewUrlSchema,
1671
+ options
1672
+ });
1673
+ }
1674
+ };
1675
+ var extraFieldsMapSchema = z.record(z.string(), z.unknown());
1676
+ var UserSchema = loose({
1677
+ id: idSchema,
1678
+ firstname: nullish(z.string()),
1679
+ lastname: nullish(z.string()),
1680
+ email: nullish(z.string()),
1681
+ role: nullish(z.string()),
1682
+ active: nullish(boolishSchema),
1683
+ /** Basic response: organisation name string. Extended response: an object. */
1684
+ organisation: nullish(
1685
+ z.union([
1686
+ z.string(),
1687
+ loose({
1688
+ id: nullish(idSchema),
1689
+ label: nullish(z.string()),
1690
+ identifier: nullish(z.string())
1691
+ })
1692
+ ])
1693
+ ),
1694
+ organisation_id: nullish(idSchema),
1695
+ organisation_identifier: nullish(z.string()),
1696
+ team: nullish(
1697
+ loose({
1698
+ id: nullish(idSchema),
1699
+ label: nullish(z.string()),
1700
+ identifier: nullish(z.string())
1701
+ })
1702
+ ),
1703
+ extrafields: nullish(extraFieldsMapSchema),
1704
+ business: nullish(
1705
+ loose({
1706
+ name: nullish(z.string()),
1707
+ email: nullish(z.string()),
1708
+ phone_number: nullish(z.string()),
1709
+ contact_person: nullish(z.string()),
1710
+ postcode: nullish(z.string()),
1711
+ housenumber: nullish(z.union([z.string(), z.number()])),
1712
+ housenumber_suffix: nullish(z.string()),
1713
+ suffix: nullish(z.string()),
1714
+ streetname: nullish(z.string()),
1715
+ city: nullish(z.string()),
1716
+ coc: nullish(z.string()),
1717
+ vat: nullish(z.string()),
1718
+ address: addressSchema.optional()
1719
+ })
1720
+ )
1721
+ });
1722
+ var OrganisationListItemSchema = loose({
1723
+ id: idSchema,
1724
+ name: nullish(z.string()),
1725
+ identifier: nullish(z.string()),
1726
+ company_name: nullish(z.string()),
1727
+ contact_person: nullish(z.string()),
1728
+ email: nullish(z.string()),
1729
+ phone: nullish(z.string()),
1730
+ extrafields: nullish(extraFieldsMapSchema)
1731
+ });
1732
+ var OrganisationLogoSchema = loose({
1733
+ extension: nullish(z.string()),
1734
+ content: nullish(z.string())
1735
+ });
1736
+ var OrganisationSchema = loose({
1737
+ id: idSchema,
1738
+ name: nullish(z.string()),
1739
+ text: nullish(z.string()),
1740
+ identifier: nullish(z.string()),
1741
+ description: nullish(z.string()),
1742
+ partner: nullish(z.string()),
1743
+ sales_channel: nullish(z.string()),
1744
+ contractor: nullish(z.string()),
1745
+ company_name: nullish(z.string()),
1746
+ contact_person: nullish(z.string()),
1747
+ postcode: nullish(z.string()),
1748
+ housenumber: nullish(z.union([z.string(), z.number()])),
1749
+ suffix: nullish(z.string()),
1750
+ streetname: nullish(z.string()),
1751
+ city: nullish(z.string()),
1752
+ email: nullish(z.string()),
1753
+ phone: nullish(z.string()),
1754
+ coc: nullish(z.string()),
1755
+ vat: nullish(z.string()),
1756
+ website: nullish(z.string()),
1757
+ created_at: nullish(z.string()),
1758
+ updated_at: nullish(z.string()),
1759
+ logo: nullish(OrganisationLogoSchema),
1760
+ extrafields: nullish(extraFieldsMapSchema)
1761
+ });
1762
+ var MutateOrganisationResultSchema = loose({ organisation_id: idSchema });
1763
+ var OrganisationProductsSchema = loose({ products: z.array(idSchema) });
1764
+ var OrganisationLogoInputSchema = z.object({
1765
+ /** Base64 string of the organisation logo. */
1766
+ content: z.string(),
1767
+ /** Image extension: `png`, `gif`, `jpg` or `jpeg`. */
1768
+ extension: z.string()
1769
+ }).passthrough();
1770
+ var OrganisationInputSchema = z.object({
1771
+ /** The name of the organisation. */
1772
+ name: z.string().optional(),
1773
+ /** Unique identifier slug for the organisation. */
1774
+ identifier: z.string().optional(),
1775
+ description: z.string().optional(),
1776
+ /** Sales channel: `d2d`, `retail`, `telemarketing`, `online` or `f2f`. */
1777
+ sales_channel: z.string().optional(),
1778
+ /** `yes` if the organisation is a contractor, otherwise `no`. */
1779
+ contractor: z.string().optional(),
1780
+ /** Required if `contractor` = `yes`. */
1781
+ company_name: z.string().optional(),
1782
+ /** Required if `contractor` = `yes`. */
1783
+ email: z.string().optional(),
1784
+ phone: z.string().optional(),
1785
+ /** Required if `contractor` = `yes`. */
1786
+ contact_person: z.string().optional(),
1787
+ /** Required if `contractor` = `yes`. */
1788
+ postcode: z.string().optional(),
1789
+ /** Required if `contractor` = `yes`. */
1790
+ housenumber: z.union([z.string(), z.number()]).optional(),
1791
+ suffix: z.string().optional(),
1792
+ /** Required if `contractor` = `yes`. */
1793
+ streetname: z.string().optional(),
1794
+ /** Required if `contractor` = `yes`. */
1795
+ city: z.string().optional(),
1796
+ /** Chamber of commerce number (required if `contractor` = `yes`). */
1797
+ coc: z.string().optional(),
1798
+ /** BTW/VAT number (required if `contractor` = `yes`). */
1799
+ vat: z.string().optional(),
1800
+ website: z.string().optional(),
1801
+ /** The organisation logo. */
1802
+ logo: OrganisationLogoInputSchema.optional()
1803
+ }).passthrough();
1804
+ var InviteUserInputSchema = z.object({
1805
+ /** Email of the user; becomes their Salesdock username. */
1806
+ email: z.string(),
1807
+ /** Role: `agent`, `teamleader`, `organisationadmin` or `admin`. */
1808
+ role: z.string(),
1809
+ /** The organisation the user belongs to. */
1810
+ organisation_id: idSchema,
1811
+ /** Team id — only required when the user is a `teamleader`. */
1812
+ team_id: idSchema.optional()
1813
+ }).passthrough();
1814
+ var OrganisationsClient = class extends BaseResource {
1815
+ /** List organisations (offset-paginated). */
1816
+ list(params = {}, options) {
1817
+ return fetchOffsetPage(
1818
+ this.http,
1819
+ OrganisationListItemSchema,
1820
+ ["account", "organisations"],
1821
+ params,
1822
+ options
1823
+ );
1824
+ }
1825
+ /** Retrieve a single organisation by id. */
1826
+ get(organisationId, options) {
1827
+ return this.http.request({
1828
+ method: "GET",
1829
+ segments: ["account", "organisations", organisationId],
1830
+ dataSchema: OrganisationSchema,
1831
+ options
1832
+ });
1833
+ }
1834
+ /** Create an organisation. */
1835
+ create(input, options) {
1836
+ const body = this.parseInput(OrganisationInputSchema, input, "users.organisations.create");
1837
+ return this.http.request({
1838
+ method: "POST",
1839
+ segments: ["account", "organisations"],
1840
+ dataSchema: MutateOrganisationResultSchema,
1841
+ body,
1842
+ options
1843
+ });
1844
+ }
1845
+ /** Update an organisation by id. */
1846
+ update(organisationId, input, options) {
1847
+ const body = this.parseInput(OrganisationInputSchema, input, "users.organisations.update");
1848
+ return this.http.request({
1849
+ method: "PUT",
1850
+ segments: ["account", "organisations", organisationId],
1851
+ dataSchema: MutateOrganisationResultSchema,
1852
+ body,
1853
+ options
1854
+ });
1855
+ }
1856
+ /** Delete an organisation by id (only allowed when it has no users). */
1857
+ delete(organisationId, options) {
1858
+ return this.http.request({
1859
+ method: "DELETE",
1860
+ segments: ["account", "organisations", organisationId],
1861
+ dataSchema: MutateOrganisationResultSchema,
1862
+ options
1863
+ });
1864
+ }
1865
+ /** List the product ids accessible to users of an organisation. */
1866
+ listProducts(organisationId, options) {
1867
+ return this.http.request({
1868
+ method: "GET",
1869
+ segments: ["account", "organisations", organisationId, "products"],
1870
+ dataSchema: OrganisationProductsSchema,
1871
+ options
1872
+ });
1873
+ }
1874
+ };
1875
+ var UsersClient = class extends BaseResource {
1876
+ constructor(http, config) {
1877
+ super(http, config);
1878
+ this.organisations = new OrganisationsClient(http, config);
1879
+ }
1880
+ /** List account users (offset-paginated). */
1881
+ list(params = {}, options) {
1882
+ return fetchOffsetPage(
1883
+ this.http,
1884
+ UserSchema,
1885
+ ["account", "users"],
1886
+ params,
1887
+ options
1888
+ );
1889
+ }
1890
+ /** Invite a user by email; sends them a Salesdock registration link. */
1891
+ invite(input, options) {
1892
+ const body = this.parseInput(InviteUserInputSchema, input, "users.invite");
1893
+ return this.http.request({
1894
+ method: "POST",
1895
+ segments: ["account", "invitation"],
1896
+ dataSchema: z.unknown(),
1897
+ body,
1898
+ options
1899
+ });
1900
+ }
1901
+ };
1902
+ var CommissionSchema = loose({
1903
+ sale_id: nullish(idSchema),
1904
+ partner_type: nullish(z.string()),
1905
+ product_id: nullish(idSchema),
1906
+ commission_plan: nullish(z.string()),
1907
+ description: nullish(z.string()),
1908
+ payout_percentage: nullish(z.union([z.string(), z.number()])),
1909
+ currency: nullish(z.string()),
1910
+ amount: nullish(z.union([z.string(), z.number()])),
1911
+ recurring_type: nullish(z.string()),
1912
+ recurring_count: nullish(z.union([z.string(), z.number()])),
1913
+ run_count: nullish(z.union([z.string(), z.number()]))
1914
+ });
1915
+ var CommissionTotalsBreakdownSchema = loose({
1916
+ total: nullish(z.number()),
1917
+ pending: nullish(z.number()),
1918
+ final: nullish(z.number())
1919
+ });
1920
+ var CommissionTotalsSchema = loose({
1921
+ amounts: CommissionTotalsBreakdownSchema.optional(),
1922
+ counts: CommissionTotalsBreakdownSchema.optional()
1923
+ });
1924
+ var CommissionListSchema = loose({
1925
+ items: z.array(CommissionSchema),
1926
+ totals: CommissionTotalsSchema.nullish()
1927
+ });
1928
+ var OutgoingCommissionsClient = class extends BaseResource {
1929
+ /** List all outgoing commissions (always `account` scope). */
1930
+ list(params = {}, options) {
1931
+ return this.http.request({
1932
+ method: "GET",
1933
+ segments: ["account", "commissions", "outgoing"],
1934
+ dataSchema: CommissionListSchema,
1935
+ query: params,
1936
+ options
1937
+ });
1938
+ }
1939
+ /** Get the outgoing commissions of a single sale (always `account` scope). */
1940
+ forSale(saleId, options) {
1941
+ return this.http.request({
1942
+ method: "GET",
1943
+ segments: ["account", "commissions", "outgoing", saleId],
1944
+ dataSchema: CommissionListSchema,
1945
+ options
1946
+ });
1947
+ }
1948
+ };
1949
+ var IncomingCommissionsClient = class extends BaseResource {
1950
+ /** List all incoming commissions (always `account` scope). */
1951
+ list(params = {}, options) {
1952
+ return this.http.request({
1953
+ method: "GET",
1954
+ segments: ["account", "commissions", "incoming"],
1955
+ dataSchema: CommissionListSchema,
1956
+ query: params,
1957
+ options
1958
+ });
1959
+ }
1960
+ /** Get the incoming commissions of a single sale (always `account` scope). */
1961
+ forSale(saleId, options) {
1962
+ return this.http.request({
1963
+ method: "GET",
1964
+ segments: ["account", "commissions", "incoming", saleId],
1965
+ dataSchema: CommissionListSchema,
1966
+ options
1967
+ });
1968
+ }
1969
+ };
1970
+ var CommissionsClient = class extends BaseResource {
1971
+ constructor(http, config) {
1972
+ super(http, config);
1973
+ this.outgoing = new OutgoingCommissionsClient(http, config);
1974
+ this.incoming = new IncomingCommissionsClient(http, config);
1975
+ }
1976
+ };
1977
+ var leadFieldEntrySchema = loose({
1978
+ label: nullish(z.string()),
1979
+ type: nullish(z.string()),
1980
+ value: z.unknown().optional()
1981
+ });
1982
+ var leadFieldMapSchema = z.union([z.record(leadFieldEntrySchema), z.array(z.unknown())]);
1983
+ var LeadLabelSchema = loose({
1984
+ id: idSchema,
1985
+ label: nullish(z.string()),
1986
+ identifier: nullish(z.string())
1987
+ });
1988
+ var leadUserRefSchema = loose({
1989
+ id: nullish(idSchema),
1990
+ name: nullish(z.string())
1991
+ });
1992
+ var LeadHistoryEntrySchema = loose({
1993
+ type: nullish(z.string()),
1994
+ modified_at: nullish(z.string()),
1995
+ previous_status: nullish(z.string()),
1996
+ new_status: nullish(z.string()),
1997
+ user: leadUserRefSchema.optional(),
1998
+ type_data: z.unknown().optional()
1999
+ });
2000
+ var TownshipSchema = loose({
2001
+ id: idSchema,
2002
+ identifier: nullish(z.string()),
2003
+ label: nullish(z.string()),
2004
+ active: nullish(z.union([z.number(), z.string(), z.boolean()])),
2005
+ boundaries: z.array(z.string()).optional()
2006
+ });
2007
+ var TownshipsClient = class extends BaseResource {
2008
+ /** List townships (always `account` scope, admin only). */
2009
+ list(params = {}, options) {
2010
+ return this.http.request({
2011
+ method: "GET",
2012
+ segments: ["account", "leads", "townships"],
2013
+ dataSchema: z.array(TownshipSchema),
2014
+ query: params,
2015
+ options
2016
+ });
2017
+ }
2018
+ };
2019
+ var LeadListItemSchema = loose({
2020
+ id: idSchema,
2021
+ business: nullish(z.union([z.boolean(), z.string(), z.number()])),
2022
+ gender: nullish(z.string()),
2023
+ firstname: nullish(z.string()),
2024
+ lastname: nullish(z.string()),
2025
+ postcode: nullish(z.string()),
2026
+ housenumber: nullish(z.union([z.string(), z.number()])),
2027
+ suffix: nullish(z.string()),
2028
+ streetname: nullish(z.string()),
2029
+ city: nullish(z.string()),
2030
+ email: nullish(z.string()),
2031
+ company_name: nullish(z.string()),
2032
+ activity: nullish(z.string()),
2033
+ locked: nullish(z.union([z.boolean(), z.string(), z.number()])),
2034
+ status: nullish(z.string()),
2035
+ created_by: nullish(idSchema),
2036
+ planned_user_id: nullish(idSchema),
2037
+ planned_date: nullish(z.string()),
2038
+ planned_by: nullish(idSchema),
2039
+ planned_at: nullish(z.string()),
2040
+ planned_from: nullish(z.string()),
2041
+ planned_to: nullish(z.string()),
2042
+ completed_at: nullish(z.string()),
2043
+ created_at: nullish(z.string()),
2044
+ updated_at: nullish(z.string()),
2045
+ planned_to_username: nullish(z.string()),
2046
+ completed_by_username: nullish(z.string()),
2047
+ relative_distance: nullish(z.number()),
2048
+ filter_status: nullish(z.string()),
2049
+ name: nullish(z.string()),
2050
+ address: nullish(z.string()),
2051
+ organisation_id: nullish(idSchema),
2052
+ township_id: nullish(idSchema),
2053
+ latitude: nullish(z.union([z.number(), z.string()])),
2054
+ longitude: nullish(z.union([z.number(), z.string()])),
2055
+ extrafields: leadFieldMapSchema.optional(),
2056
+ questions: leadFieldMapSchema.optional(),
2057
+ labels: z.array(LeadLabelSchema).optional(),
2058
+ history: z.array(LeadHistoryEntrySchema).optional()
2059
+ });
2060
+ var LeadSchema = loose({
2061
+ id: idSchema,
2062
+ origin: nullish(z.string()),
2063
+ business: nullish(z.union([z.boolean(), z.string(), z.number()])),
2064
+ gender: nullish(z.string()),
2065
+ firstname: nullish(z.string()),
2066
+ lastname: nullish(z.string()),
2067
+ birthdate: nullish(z.string()),
2068
+ email: nullish(z.string()),
2069
+ phone: nullish(z.string()),
2070
+ company_name: nullish(z.string()),
2071
+ contact_person: nullish(z.string()),
2072
+ coc: nullish(z.string()),
2073
+ vat: nullish(z.string()),
2074
+ postcode: nullish(z.string()),
2075
+ housenumber: nullish(z.union([z.string(), z.number()])),
2076
+ suffix: nullish(z.string()),
2077
+ streetname: nullish(z.string()),
2078
+ city: nullish(z.string()),
2079
+ country: nullish(z.string()),
2080
+ activity: nullish(z.string()),
2081
+ organisation_id: nullish(idSchema),
2082
+ township_id: nullish(idSchema),
2083
+ latitude: nullish(z.union([z.number(), z.string()])),
2084
+ longitude: nullish(z.union([z.number(), z.string()])),
2085
+ imported_file_name: nullish(z.string()),
2086
+ locked: nullish(z.union([z.boolean(), z.string(), z.number()])),
2087
+ status: nullish(z.string()),
2088
+ created_by: nullish(idSchema),
2089
+ planned_user_id: nullish(idSchema),
2090
+ planned_date: nullish(z.string()),
2091
+ planned_by: nullish(idSchema),
2092
+ planned_at: nullish(z.string()),
2093
+ planned_from: nullish(z.string()),
2094
+ planned_to: nullish(z.string()),
2095
+ completed_at: nullish(z.string()),
2096
+ completed_team_id: nullish(idSchema),
2097
+ completed_by: nullish(idSchema),
2098
+ created_at: nullish(z.string()),
2099
+ updated_at: nullish(z.string()),
2100
+ extrafields: leadFieldMapSchema.optional(),
2101
+ questions: leadFieldMapSchema.optional(),
2102
+ labels: z.array(LeadLabelSchema).optional(),
2103
+ history: z.array(LeadHistoryEntrySchema).optional()
2104
+ });
2105
+ var LeadActivitySchema = loose({
2106
+ id: idSchema,
2107
+ identifier: nullish(z.string()),
2108
+ label: nullish(z.string()),
2109
+ type: nullish(z.string())
2110
+ });
2111
+ var LeadSourceSchema = loose({
2112
+ id: idSchema,
2113
+ identifier: nullish(z.string()),
2114
+ label: nullish(z.string())
2115
+ });
2116
+ var LeadFormSchema = loose({
2117
+ id: idSchema,
2118
+ identifier: nullish(z.string()),
2119
+ label: nullish(z.string()),
2120
+ description: nullish(z.string()),
2121
+ active: nullish(z.boolean()),
2122
+ created_at: nullish(z.string()),
2123
+ updated_at: nullish(z.string())
2124
+ });
2125
+ var LeadFormElementSchema = loose({
2126
+ id: idSchema,
2127
+ identifier: nullish(z.string()),
2128
+ input_type: nullish(z.string()),
2129
+ label: nullish(z.string()),
2130
+ description: nullish(z.string()),
2131
+ filled_by_client: nullish(z.boolean()),
2132
+ filled_by_agent: nullish(z.boolean()),
2133
+ lead_component: nullish(z.boolean()),
2134
+ format: z.unknown().optional()
2135
+ });
2136
+ var LeadResultSchema = loose({
2137
+ created_at: nullish(z.string()),
2138
+ result_at: nullish(z.string()),
2139
+ action: nullish(z.string()),
2140
+ previous_status: nullish(z.string()),
2141
+ new_status: nullish(z.string()),
2142
+ contact_established: nullish(z.boolean()),
2143
+ sales_opportunity: nullish(z.boolean()),
2144
+ not_reached: nullish(z.boolean()),
2145
+ appointment: nullish(z.boolean()),
2146
+ latitude: nullish(z.union([z.number(), z.string()])),
2147
+ longitude: nullish(z.union([z.number(), z.string()])),
2148
+ distance: nullish(z.union([z.number(), z.string()])),
2149
+ result_latitude: nullish(z.union([z.number(), z.string()])),
2150
+ result_longitude: nullish(z.union([z.number(), z.string()])),
2151
+ result_distance: nullish(z.union([z.number(), z.string()])),
2152
+ user: leadUserRefSchema.optional(),
2153
+ organisation: loose({
2154
+ id: nullish(idSchema),
2155
+ name: nullish(z.string()),
2156
+ identifier: nullish(z.string())
2157
+ }).optional(),
2158
+ team: nullish(
2159
+ loose({
2160
+ id: nullish(idSchema),
2161
+ name: nullish(z.string())
2162
+ })
2163
+ ),
2164
+ township: nullish(
2165
+ loose({
2166
+ id: nullish(idSchema),
2167
+ name: nullish(z.string())
2168
+ })
2169
+ ),
2170
+ lead: loose({ id: idSchema }).optional()
2171
+ });
2172
+ var LeadStatusSchema = loose({
2173
+ source: nullish(z.string()),
2174
+ id: nullish(idSchema),
2175
+ name: nullish(z.string()),
2176
+ text: nullish(z.string()),
2177
+ type: nullish(z.string()),
2178
+ source_data: loose({
2179
+ contact_established: nullish(z.boolean()),
2180
+ sales_opportunity: nullish(z.boolean()),
2181
+ activities: nullish(z.array(z.string()))
2182
+ }).optional()
2183
+ });
2184
+ var LeadFormPdfSchema = loose({
2185
+ name: nullish(z.string()),
2186
+ /** Base64-encoded PDF bytes. Decode it yourself; the SDK keeps it as a string. */
2187
+ content: z.string()
2188
+ });
2189
+ var MutateLeadResultSchema = loose({ lead_id: idSchema });
2190
+ var CreateLeadFormInstanceResultSchema = loose({
2191
+ form_instance_id: idSchema,
2192
+ lead_id: idSchema
2193
+ });
2194
+ var CreateLeadAsAdminSchema = z.object({
2195
+ /** Lead activity identifier, e.g. `calling`. */
2196
+ activity: z.string().optional(),
2197
+ gender: z.string().optional(),
2198
+ firstname: z.string().optional(),
2199
+ lastname: z.string().optional(),
2200
+ postcode: z.string().optional(),
2201
+ housenumber: z.union([z.string(), z.number()]).optional(),
2202
+ suffix: z.string().optional(),
2203
+ streetname: z.string().optional(),
2204
+ city: z.string().optional(),
2205
+ birthdate: z.string().optional(),
2206
+ email: z.string().optional(),
2207
+ phone: z.string().optional(),
2208
+ business: z.union([z.string(), z.number(), z.boolean()]).optional(),
2209
+ company_name: z.string().optional(),
2210
+ contact_person: z.string().optional(),
2211
+ coc: z.string().optional(),
2212
+ vat: z.string().optional(),
2213
+ /** How to assign the lead, e.g. `user`. */
2214
+ assign: z.string().optional(),
2215
+ /** The user id to assign the lead to. */
2216
+ user: idSchema.optional(),
2217
+ /** Whether to plan the lead for a date: `1`/`0`. */
2218
+ planned_for_date: z.union([z.string(), z.number()]).optional(),
2219
+ /** Planned date in `dd-mm-yyyy` format. */
2220
+ planned_date: z.string().optional(),
2221
+ /** Planned start time in `hh:mm` format. */
2222
+ start_at: z.string().optional(),
2223
+ /** Planned end time in `hh:mm` format. */
2224
+ end_at: z.string().optional(),
2225
+ /** The lead source id. */
2226
+ lead_source_id: idSchema.optional(),
2227
+ /** Label ids to attach to the lead. */
2228
+ labels: z.array(idSchema).optional()
2229
+ }).passthrough();
2230
+ var UpdateLeadAsAdminSchema = CreateLeadAsAdminSchema;
2231
+ var CreateLeadAsResellerSchema = z.object({
2232
+ activity: z.string().optional(),
2233
+ gender: z.string().optional(),
2234
+ firstname: z.string().optional(),
2235
+ lastname: z.string().optional(),
2236
+ postcode: z.string().optional(),
2237
+ housenumber: z.union([z.string(), z.number()]).optional(),
2238
+ suffix: z.string().optional(),
2239
+ streetname: z.string().optional(),
2240
+ city: z.string().optional(),
2241
+ birthdate: z.string().optional(),
2242
+ email: z.string().optional(),
2243
+ phone: z.string().optional(),
2244
+ business: z.union([z.string(), z.number(), z.boolean()]).optional(),
2245
+ company_name: z.string().optional(),
2246
+ contact_person: z.string().optional(),
2247
+ coc: z.string().optional(),
2248
+ vat: z.string().optional(),
2249
+ /** The user id to assign the lead to. */
2250
+ user: idSchema.optional(),
2251
+ /** Whether to plan the lead for a date: `1`/`0`. */
2252
+ planned_for_date: z.union([z.string(), z.number()]).optional(),
2253
+ /** Planned date in `dd-mm-yyyy` format. */
2254
+ planned_date: z.string().optional(),
2255
+ /** Planned start time in `hh:mm` format. */
2256
+ start_at: z.string().optional(),
2257
+ /** Planned end time in `hh:mm` format. */
2258
+ end_at: z.string().optional(),
2259
+ /** The lead source id. */
2260
+ lead_source_id: idSchema.optional(),
2261
+ /** Label ids to attach to the lead. */
2262
+ labels: z.array(idSchema).optional()
2263
+ }).passthrough();
2264
+ var UpdateLeadAsResellerSchema = CreateLeadAsResellerSchema;
2265
+ var UpdateLeadStatusSchema = z.object({
2266
+ /** The new status identifier, e.g. `afspraak`. */
2267
+ status: z.string(),
2268
+ /** Optional remark accompanying the status change. */
2269
+ remark: z.string().optional()
2270
+ }).passthrough();
2271
+ var CreateLeadFormInstanceSchema = z.object({
2272
+ /** Answers keyed by form element identifier. */
2273
+ questionData: z.record(z.unknown()).optional(),
2274
+ /** The client's name. */
2275
+ client_name: z.string().optional(),
2276
+ /** The client's email address. */
2277
+ client_email: z.string().optional(),
2278
+ /** The client's phone number. */
2279
+ client_phone: z.string().optional()
2280
+ }).passthrough();
2281
+ var LeadsClient = class extends BaseResource {
2282
+ constructor(http, config) {
2283
+ super(http, config);
2284
+ this.townships = new TownshipsClient(http, config);
2285
+ }
2286
+ /** List leads (cursor-paginated). Honors the configured scope. */
2287
+ list(params = {}, options) {
2288
+ return fetchCursorPage(
2289
+ this.http,
2290
+ LeadListItemSchema,
2291
+ [this.scope(options), "leads"],
2292
+ params,
2293
+ options
2294
+ );
2295
+ }
2296
+ /** Retrieve a single lead by id. Honors the configured scope. */
2297
+ get(leadId, options) {
2298
+ return this.http.request({
2299
+ method: "GET",
2300
+ segments: [this.scope(options), "leads", leadId],
2301
+ dataSchema: LeadSchema,
2302
+ options
2303
+ });
2304
+ }
2305
+ /** List the available lead activities. Honors the configured scope. */
2306
+ listActivities(options) {
2307
+ return this.http.request({
2308
+ method: "GET",
2309
+ segments: [this.scope(options), "leads", "activities"],
2310
+ dataSchema: z.array(LeadActivitySchema),
2311
+ options
2312
+ });
2313
+ }
2314
+ /** List the available lead sources. Honors the configured scope. */
2315
+ listSources(options) {
2316
+ return this.http.request({
2317
+ method: "GET",
2318
+ segments: [this.scope(options), "leads", "sources"],
2319
+ dataSchema: z.array(LeadSourceSchema),
2320
+ options
2321
+ });
2322
+ }
2323
+ /** Create a lead as an admin (always `account` scope). */
2324
+ createAsAdmin(input, options) {
2325
+ const body = this.parseInput(CreateLeadAsAdminSchema, input, "leads.createAsAdmin");
2326
+ return this.http.request({
2327
+ method: "POST",
2328
+ segments: ["account", "leads"],
2329
+ dataSchema: MutateLeadResultSchema,
2330
+ body,
2331
+ options
2332
+ });
2333
+ }
2334
+ /** Update a lead by id as an admin (always `account` scope). */
2335
+ updateAsAdmin(leadId, input, options) {
2336
+ const body = this.parseInput(UpdateLeadAsAdminSchema, input, "leads.updateAsAdmin");
2337
+ return this.http.request({
2338
+ method: "PUT",
2339
+ segments: ["account", "leads", leadId],
2340
+ dataSchema: MutateLeadResultSchema,
2341
+ body,
2342
+ options
2343
+ });
2344
+ }
2345
+ /** Create a lead as a reseller (always `user` scope). */
2346
+ createAsReseller(input, options) {
2347
+ const body = this.parseInput(CreateLeadAsResellerSchema, input, "leads.createAsReseller");
2348
+ return this.http.request({
2349
+ method: "POST",
2350
+ segments: ["user", "leads"],
2351
+ dataSchema: MutateLeadResultSchema,
2352
+ body,
2353
+ options
2354
+ });
2355
+ }
2356
+ /** Update a lead by id as a reseller (always `user` scope). */
2357
+ updateAsReseller(leadId, input, options) {
2358
+ const body = this.parseInput(UpdateLeadAsResellerSchema, input, "leads.updateAsReseller");
2359
+ return this.http.request({
2360
+ method: "PUT",
2361
+ segments: ["user", "leads", leadId],
2362
+ dataSchema: MutateLeadResultSchema,
2363
+ body,
2364
+ options
2365
+ });
2366
+ }
2367
+ /** Retrieve a lead's form rendered as a base64-encoded PDF. Honors the configured scope. */
2368
+ getFormPdf(leadId, options) {
2369
+ return this.http.request({
2370
+ method: "GET",
2371
+ segments: [this.scope(options), "leads", leadId, "form", "pdf"],
2372
+ dataSchema: LeadFormPdfSchema,
2373
+ options
2374
+ });
2375
+ }
2376
+ /** Retrieve the change history of a lead. Honors the configured scope. */
2377
+ getHistory(leadId, options) {
2378
+ return this.http.request({
2379
+ method: "GET",
2380
+ segments: [this.scope(options), "leads", leadId, "history"],
2381
+ dataSchema: z.array(LeadHistoryEntrySchema),
2382
+ options
2383
+ });
2384
+ }
2385
+ /** Retrieve the results (logged actions) for a single lead. Honors the configured scope. */
2386
+ getResults(leadId, options) {
2387
+ return this.http.request({
2388
+ method: "GET",
2389
+ segments: [this.scope(options), "leads", leadId, "results"],
2390
+ dataSchema: z.array(LeadResultSchema),
2391
+ options
2392
+ });
2393
+ }
2394
+ /** List lead results across leads (cursor-paginated). Honors the configured scope. */
2395
+ listResults(params = {}, options) {
2396
+ return fetchCursorPage(
2397
+ this.http,
2398
+ LeadResultSchema,
2399
+ [this.scope(options), "leads", "results"],
2400
+ params,
2401
+ options
2402
+ );
2403
+ }
2404
+ /** Update a lead's status (always `account` scope). */
2405
+ updateStatus(leadId, input, options) {
2406
+ const body = this.parseInput(UpdateLeadStatusSchema, input, "leads.updateStatus");
2407
+ return this.http.request({
2408
+ method: "POST",
2409
+ segments: ["account", "leads", "status", leadId],
2410
+ dataSchema: z.unknown(),
2411
+ body,
2412
+ options
2413
+ });
2414
+ }
2415
+ /** List lead forms (templates). Honors the configured scope. */
2416
+ listForms(options) {
2417
+ return this.http.request({
2418
+ method: "GET",
2419
+ segments: [this.scope(options), "leads", "forms"],
2420
+ dataSchema: z.array(LeadFormSchema),
2421
+ options
2422
+ });
2423
+ }
2424
+ /** List the elements/fields of a lead form. Honors the configured scope. */
2425
+ getFormElements(leadFormId, options) {
2426
+ return this.http.request({
2427
+ method: "GET",
2428
+ segments: [this.scope(options), "leads", "forms", leadFormId, "elements"],
2429
+ dataSchema: z.array(LeadFormElementSchema),
2430
+ options
2431
+ });
2432
+ }
2433
+ /** Create a lead form instance (no scope segment). */
2434
+ createFormInstance(leadFormId, input, options) {
2435
+ const body = this.parseInput(CreateLeadFormInstanceSchema, input, "leads.createFormInstance");
2436
+ return this.http.request({
2437
+ method: "POST",
2438
+ segments: ["leads", "forms", leadFormId, "instances"],
2439
+ dataSchema: CreateLeadFormInstanceResultSchema,
2440
+ body,
2441
+ options
2442
+ });
2443
+ }
2444
+ /** List lead statuses. Honors the configured scope. */
2445
+ listStatuses(params = {}, options) {
2446
+ return this.http.request({
2447
+ method: "GET",
2448
+ segments: [this.scope(options), "statuses"],
2449
+ dataSchema: z.array(LeadStatusSchema),
2450
+ query: params,
2451
+ options
2452
+ });
2453
+ }
2454
+ };
2455
+ var FormSchema = loose({
2456
+ id: idSchema,
2457
+ name: nullish(z.string())
2458
+ });
2459
+ var FormElementSchema = loose({
2460
+ id: idSchema,
2461
+ name: nullish(z.string()),
2462
+ identifier: nullish(z.string()),
2463
+ input_type: nullish(z.string()),
2464
+ description: nullish(z.string())
2465
+ });
2466
+ var FormInstanceListItemSchema = loose({
2467
+ id: idSchema,
2468
+ title: nullish(z.string()),
2469
+ status: nullish(z.string()),
2470
+ status_remark: nullish(z.string()),
2471
+ organisation_name: nullish(z.string()),
2472
+ agent: nullish(z.string()),
2473
+ client_info: z.union([
2474
+ loose({
2475
+ client_name_for_receiving_confirmation_email: nullish(z.string()),
2476
+ client_email_for_receiving_confirmation_email: nullish(z.string())
2477
+ }),
2478
+ z.array(z.unknown())
2479
+ ]).optional(),
2480
+ created_at: nullish(z.string()),
2481
+ updated_at: nullish(z.string())
2482
+ });
2483
+ var FormInstanceRelationSchema = loose({
2484
+ id: idSchema,
2485
+ postcode: nullish(z.string()),
2486
+ housenumber: nullish(z.union([z.string(), z.number()])),
2487
+ suffix: nullish(z.string()),
2488
+ streetname: nullish(z.string()),
2489
+ city: nullish(z.string()),
2490
+ email: nullish(z.string()),
2491
+ phone: nullish(z.string()),
2492
+ company_name: nullish(z.string()),
2493
+ contact_person: nullish(z.string()),
2494
+ coc: nullish(z.string()),
2495
+ vat: nullish(z.string())
2496
+ });
2497
+ var FormInstanceSchema = loose({
2498
+ id: idSchema,
2499
+ title: nullish(z.string()),
2500
+ status: nullish(z.string()),
2501
+ status_remark: nullish(z.string()),
2502
+ agent: nullish(z.string()),
2503
+ organisation: nullish(z.string()),
2504
+ created_at: nullish(z.string()),
2505
+ updated_at: nullish(z.string()),
2506
+ relation: FormInstanceRelationSchema.optional(),
2507
+ client_name: nullish(z.string()),
2508
+ client_email: nullish(z.string()),
2509
+ question_data: z.record(z.string(), z.unknown()).optional()
2510
+ });
2511
+ var FillFormInstanceResultSchema = loose({
2512
+ form_instance_id: idSchema
2513
+ });
2514
+ var FormInstancePdfSchema = loose({
2515
+ id: idSchema,
2516
+ pdf: loose({
2517
+ /** The base64-encoded PDF document (not decoded by the SDK). */
2518
+ content: nullish(z.string())
2519
+ }).optional()
2520
+ });
2521
+ var FormStatusSchema = loose({
2522
+ source: nullish(z.string()),
2523
+ id: nullish(idSchema),
2524
+ name: nullish(z.string()),
2525
+ text: nullish(z.string()),
2526
+ type: nullish(z.string()),
2527
+ source_data: nullish(z.unknown())
2528
+ });
2529
+ var FillFormFileSchema = z.object({
2530
+ /** The file name, e.g. `"Some file.png"`. */
2531
+ name: z.string(),
2532
+ /** The file contents as a data URL (e.g. `"data:image/png;base64,..."`). */
2533
+ content: z.string()
2534
+ }).passthrough();
2535
+ var FillFormInstanceSchema = z.object({
2536
+ /**
2537
+ * Answers keyed by element identifier. Values are strings/numbers for most
2538
+ * inputs, or an array of `{ name, content }` for `file` elements.
2539
+ */
2540
+ questionData: z.record(
2541
+ z.string(),
2542
+ z.union([z.string(), z.number(), z.boolean(), z.array(FillFormFileSchema), z.unknown()])
2543
+ ),
2544
+ /** Name of the client receiving the confirmation email. */
2545
+ client_name: z.string().optional(),
2546
+ /** Email of the client receiving the confirmation email. */
2547
+ client_email: z.string().optional(),
2548
+ /** Phone number of the client. */
2549
+ client_phone: z.string().optional()
2550
+ }).passthrough();
2551
+ var FormsClient = class extends BaseResource {
2552
+ /** List the forms available to the user (offset-paginated). Honors the configured scope. */
2553
+ list(options) {
2554
+ return fetchOffsetPage(
2555
+ this.http,
2556
+ FormSchema,
2557
+ [this.scope(options), "forms"],
2558
+ void 0,
2559
+ options
2560
+ );
2561
+ }
2562
+ /** Retrieve all elements available for a form. Honors the configured scope. */
2563
+ getElements(formId, options) {
2564
+ return this.http.request({
2565
+ method: "GET",
2566
+ segments: [this.scope(options), "forms", formId, "elements"],
2567
+ dataSchema: z.array(FormElementSchema),
2568
+ options
2569
+ });
2570
+ }
2571
+ /** List form instances (offset-paginated). Honors the configured scope. */
2572
+ listInstances(params = {}, options) {
2573
+ return fetchOffsetPage(
2574
+ this.http,
2575
+ FormInstanceListItemSchema,
2576
+ [this.scope(options), "forms", "instances"],
2577
+ params,
2578
+ options
2579
+ );
2580
+ }
2581
+ /** Retrieve a single form instance by id. Honors the configured scope. */
2582
+ getInstance(formInstanceId, options) {
2583
+ return this.http.request({
2584
+ method: "GET",
2585
+ segments: [this.scope(options), "forms", "instances", formInstanceId],
2586
+ dataSchema: FormInstanceSchema,
2587
+ options
2588
+ });
2589
+ }
2590
+ /** Fill (create) a form instance for a form. This endpoint has no scope segment. */
2591
+ fillInstance(formId, input, options) {
2592
+ const body = this.parseInput(FillFormInstanceSchema, input, "forms.fillInstance");
2593
+ return this.http.request({
2594
+ method: "POST",
2595
+ segments: ["forms", formId, "instances"],
2596
+ dataSchema: FillFormInstanceResultSchema,
2597
+ body,
2598
+ options
2599
+ });
2600
+ }
2601
+ /** List the ids of form instances connected to a sale. Honors the configured scope. */
2602
+ listInstancesBySale(saleId, options) {
2603
+ return this.http.request({
2604
+ method: "GET",
2605
+ segments: [this.scope(options), "forms", "instances", "sale", saleId],
2606
+ dataSchema: z.array(idSchema),
2607
+ options
2608
+ });
2609
+ }
2610
+ /** Retrieve a form instance's PDF (base64 content). Honors the configured scope. */
2611
+ getInstancePdf(formInstanceId, options) {
2612
+ return this.http.request({
2613
+ method: "GET",
2614
+ segments: [this.scope(options), "forms", "instances", "pdf", formInstanceId],
2615
+ dataSchema: FormInstancePdfSchema,
2616
+ options
2617
+ });
2618
+ }
2619
+ /** List the available form statuses. Honors the configured scope. */
2620
+ listStatuses(params = {}, options) {
2621
+ return this.http.request({
2622
+ method: "GET",
2623
+ segments: [this.scope(options), "statuses"],
2624
+ dataSchema: z.array(FormStatusSchema),
2625
+ query: params,
2626
+ options
2627
+ });
2628
+ }
2629
+ };
2630
+ var RelationListItemSchema = loose({
2631
+ id: idSchema,
2632
+ business: nullish(z.union([z.boolean(), z.string(), z.number()])),
2633
+ shared_with: nullish(z.string()),
2634
+ organisation_id: nullish(idSchema),
2635
+ gender: nullish(z.string()),
2636
+ firstname: nullish(z.string()),
2637
+ lastname: nullish(z.string()),
2638
+ birthdate: nullish(z.string()),
2639
+ postcode: nullish(z.string()),
2640
+ housenumber: nullish(z.union([z.string(), z.number()])),
2641
+ suffix: nullish(z.string()),
2642
+ streetname: nullish(z.string()),
2643
+ city: nullish(z.string()),
2644
+ email: nullish(z.string()),
2645
+ phone: nullish(z.string()),
2646
+ company_name: nullish(z.string()),
2647
+ contact_person: nullish(z.string()),
2648
+ coc: nullish(z.string()),
2649
+ vat: nullish(z.string()),
2650
+ created_at: nullish(z.string()),
2651
+ updated_at: nullish(z.string())
2652
+ });
2653
+ var RelationSchema = loose({
2654
+ id: idSchema,
2655
+ created_at: nullish(z.string()),
2656
+ updated_at: nullish(z.string()),
2657
+ customer: loose({
2658
+ gender: nullish(z.string()),
2659
+ firstname: nullish(z.string()),
2660
+ lastname: nullish(z.string()),
2661
+ birthdate: nullish(z.string()),
2662
+ email: nullish(z.string()),
2663
+ phone: nullish(z.string()),
2664
+ business: nullish(z.union([z.boolean(), z.string(), z.number()])),
2665
+ company_name: nullish(z.string()),
2666
+ contact_person: nullish(z.string()),
2667
+ coc: nullish(z.string()),
2668
+ vat: nullish(z.string()),
2669
+ address: addressSchema.optional()
2670
+ }).optional(),
2671
+ shared_with: nullish(z.string()),
2672
+ organisation_id: nullish(idSchema),
2673
+ extrafields: z.array(extraFieldSchema).optional()
2674
+ });
2675
+ var MutateRelationResultSchema = loose({ relation_id: idSchema });
2676
+ var RelationInputSchema = z.object({
2677
+ visibility: z.string().optional(),
2678
+ organisation_id: idSchema.optional(),
2679
+ user_id: idSchema.optional(),
2680
+ gender: z.string().optional(),
2681
+ firstname: z.string().optional(),
2682
+ lastname: z.string().optional(),
2683
+ postcode: z.string().optional(),
2684
+ housenumber: z.union([z.string(), z.number()]).optional(),
2685
+ suffix: z.string().optional(),
2686
+ streetname: z.string().optional(),
2687
+ city: z.string().optional(),
2688
+ birthdate: z.string().optional(),
2689
+ email: z.string().optional(),
2690
+ phone: z.string().optional(),
2691
+ business: z.union([z.string(), z.number(), z.boolean()]).optional(),
2692
+ company_name: z.string().optional(),
2693
+ contact_person: z.string().optional(),
2694
+ company_coc: z.string().optional(),
2695
+ company_vat: z.string().optional()
2696
+ }).passthrough();
2697
+ var RelationsClient = class extends BaseResource {
2698
+ /** List relations (offset-paginated). Honors the configured scope. */
2699
+ list(params = {}, options) {
2700
+ return fetchOffsetPage(
2701
+ this.http,
2702
+ RelationListItemSchema,
2703
+ [this.scope(options), "relations"],
2704
+ params,
2705
+ options
2706
+ );
2707
+ }
2708
+ /** Retrieve a single relation by id (always `account` scope). */
2709
+ get(relationId, options) {
2710
+ return this.http.request({
2711
+ method: "GET",
2712
+ segments: ["account", "relations", relationId],
2713
+ dataSchema: RelationSchema,
2714
+ options
2715
+ });
2716
+ }
2717
+ /** Create a relation. Honors the configured scope. */
2718
+ create(input, options) {
2719
+ const body = this.parseInput(RelationInputSchema, input, "relations.create");
2720
+ return this.http.request({
2721
+ method: "POST",
2722
+ segments: [this.scope(options), "relations"],
2723
+ dataSchema: MutateRelationResultSchema,
2724
+ body,
2725
+ options
2726
+ });
2727
+ }
2728
+ /** Update a relation by id (always `account` scope). */
2729
+ update(relationId, input, options) {
2730
+ const body = this.parseInput(RelationInputSchema, input, "relations.update");
2731
+ return this.http.request({
2732
+ method: "PUT",
2733
+ segments: ["account", "relations", relationId],
2734
+ dataSchema: MutateRelationResultSchema,
2735
+ body,
2736
+ options
2737
+ });
2738
+ }
2739
+ };
2740
+ var SupplierListItemSchema = loose({
2741
+ id: idSchema,
2742
+ name: nullish(z.string()),
2743
+ text: nullish(z.string()),
2744
+ identifier: nullish(z.string()),
2745
+ description: nullish(z.string()),
2746
+ active: nullish(boolishSchema)
2747
+ });
2748
+ var MediaBlobSchema = loose({
2749
+ extension: nullish(z.string()),
2750
+ content: nullish(z.string())
2751
+ });
2752
+ var SupplierSchema = loose({
2753
+ id: idSchema,
2754
+ name: nullish(z.string()),
2755
+ text: nullish(z.string()),
2756
+ identifier: nullish(z.string()),
2757
+ description: nullish(z.string()),
2758
+ confirmation_pdf_layout: nullish(z.string()),
2759
+ contractor: nullish(z.string()),
2760
+ company_name: nullish(z.string()),
2761
+ contact_person: nullish(z.string()),
2762
+ postcode: nullish(z.string()),
2763
+ housenumber: nullish(z.union([z.string(), z.number()])),
2764
+ suffix: nullish(z.string()),
2765
+ streetname: nullish(z.string()),
2766
+ city: nullish(z.string()),
2767
+ email: nullish(z.string()),
2768
+ phone: nullish(z.string()),
2769
+ coc: nullish(z.string()),
2770
+ vat: nullish(z.string()),
2771
+ website: nullish(z.string()),
2772
+ logo: nullish(MediaBlobSchema),
2773
+ created_at: nullish(z.string()),
2774
+ updated_at: nullish(z.string()),
2775
+ email_template: nullish(z.string()),
2776
+ extrafields: z.array(extraFieldSchema).optional()
2777
+ });
2778
+ var MutateSupplierResultSchema = loose({ supplier_id: idSchema });
2779
+ var SupplierInputSchema = z.object({
2780
+ /** Name of the supplier. */
2781
+ name: z.string().optional(),
2782
+ /** Unique identifier (slug) for the supplier. */
2783
+ identifier: z.string().optional(),
2784
+ /** `0` = inactive, `1` = active. */
2785
+ active: z.union([z.string(), z.number(), z.boolean()]).optional(),
2786
+ description: z.string().optional(),
2787
+ /** `"yes"` = is a contractor, `"no"` = not a contractor. */
2788
+ contractor: z.string().optional(),
2789
+ company_name: z.string().optional(),
2790
+ contact_person: z.string().optional(),
2791
+ postcode: z.string().optional(),
2792
+ housenumber: z.union([z.string(), z.number()]).optional(),
2793
+ suffix: z.string().optional(),
2794
+ streetname: z.string().optional(),
2795
+ city: z.string().optional(),
2796
+ coc: z.string().optional(),
2797
+ vat: z.string().optional(),
2798
+ email: z.string().optional(),
2799
+ phone: z.string().optional(),
2800
+ website: z.string().optional(),
2801
+ /** Logo as `{ content: base64, extension: "png"|"gif"|"jpg"|"jpeg" }`. */
2802
+ logo: z.object({ content: z.string().optional(), extension: z.string().optional() }).passthrough().optional()
2803
+ }).passthrough();
2804
+ var SuppliersClient = class extends BaseResource {
2805
+ /** List suppliers with their basic details. Honors the configured scope. */
2806
+ list(options) {
2807
+ return this.http.request({
2808
+ method: "GET",
2809
+ segments: [this.scope(options), "suppliers"],
2810
+ dataSchema: z.array(SupplierListItemSchema),
2811
+ options
2812
+ });
2813
+ }
2814
+ /** Retrieve a single supplier by id. Honors the configured scope. */
2815
+ get(supplierId, options) {
2816
+ return this.http.request({
2817
+ method: "GET",
2818
+ segments: [this.scope(options), "suppliers", supplierId],
2819
+ dataSchema: SupplierSchema,
2820
+ options
2821
+ });
2822
+ }
2823
+ /** Create a supplier (always `account` scope, admin only). */
2824
+ create(input, options) {
2825
+ const body = this.parseInput(SupplierInputSchema, input, "products.suppliers.create");
2826
+ return this.http.request({
2827
+ method: "POST",
2828
+ segments: ["account", "suppliers"],
2829
+ dataSchema: MutateSupplierResultSchema,
2830
+ body,
2831
+ options
2832
+ });
2833
+ }
2834
+ /** Update a supplier by id (always `account` scope, admin only). */
2835
+ update(supplierId, input, options) {
2836
+ const body = this.parseInput(SupplierInputSchema, input, "products.suppliers.update");
2837
+ return this.http.request({
2838
+ method: "PUT",
2839
+ segments: ["account", "suppliers", supplierId],
2840
+ dataSchema: MutateSupplierResultSchema,
2841
+ body,
2842
+ options
2843
+ });
2844
+ }
2845
+ /** Delete a supplier by id (always `account` scope, admin only). */
2846
+ delete(supplierId, options) {
2847
+ return this.http.request({
2848
+ method: "DELETE",
2849
+ segments: ["account", "suppliers", supplierId],
2850
+ dataSchema: MutateSupplierResultSchema,
2851
+ options
2852
+ });
2853
+ }
2854
+ };
2855
+ var ProductListItemSchema = loose({
2856
+ id: idSchema,
2857
+ name: nullish(z.string()),
2858
+ identifier: nullish(z.string()),
2859
+ supplier_id: nullish(idSchema),
2860
+ supplier_name: nullish(z.string()),
2861
+ supplier_identifier: nullish(z.string()),
2862
+ type: nullish(z.string()),
2863
+ usp: nullish(z.string()),
2864
+ description: nullish(z.string()),
2865
+ cart_info: nullish(z.string()),
2866
+ business: nullish(z.union([z.string(), z.number()])),
2867
+ active: nullish(boolishSchema),
2868
+ valid_from: nullish(z.string()),
2869
+ valid_till: nullish(z.string()),
2870
+ created_at: nullish(z.string()),
2871
+ updated_at: nullish(z.string())
2872
+ });
2873
+ var ProductDocumentSchema = loose({
2874
+ name: nullish(z.string()),
2875
+ location: nullish(z.string())
2876
+ });
2877
+ var ProductSchema = loose({
2878
+ id: idSchema,
2879
+ name: nullish(z.string()),
2880
+ identifier: nullish(z.string()),
2881
+ main: nullish(z.union([z.number(), z.string(), z.boolean()])),
2882
+ type: nullish(z.string()),
2883
+ image: nullish(MediaBlobSchema),
2884
+ usp: nullish(z.string()),
2885
+ description: nullish(z.string()),
2886
+ duration: nullish(z.union([z.string(), z.number()])),
2887
+ business: nullish(z.union([z.string(), z.number()])),
2888
+ retention: nullish(z.union([z.string(), z.number()])),
2889
+ confirmation_pdf_layout: nullish(z.string()),
2890
+ active: nullish(boolishSchema),
2891
+ price: nullish(z.union([z.string(), z.number()])),
2892
+ price_action: nullish(z.union([z.string(), z.number()])),
2893
+ price_action_type: nullish(z.string()),
2894
+ price_action_value: nullish(z.union([z.string(), z.number()])),
2895
+ price_monthly: nullish(z.union([z.string(), z.number()])),
2896
+ price_monthly_action: nullish(z.union([z.string(), z.number()])),
2897
+ price_monthly_action_type: nullish(z.string()),
2898
+ price_monthly_action_value: nullish(z.union([z.string(), z.number()])),
2899
+ valid_from: nullish(z.string()),
2900
+ valid_till: nullish(z.string()),
2901
+ created_at: nullish(z.string()),
2902
+ updated_at: nullish(z.string()),
2903
+ supplier_id: nullish(idSchema),
2904
+ supplier_name: nullish(z.string()),
2905
+ supplier_identifier: nullish(z.string()),
2906
+ customfields: z.record(z.string(), z.unknown()).optional(),
2907
+ documents: z.array(ProductDocumentSchema).optional()
2908
+ });
2909
+ var MutateProductResultSchema = loose({ product_id: idSchema });
2910
+ var ConnectOrganisationResultSchema = loose({
2911
+ organisation_id: idSchema,
2912
+ products: z.array(idSchema)
2913
+ });
2914
+ var ConnectProductResultSchema = loose({
2915
+ product_id: idSchema,
2916
+ organisations: z.array(idSchema)
2917
+ });
2918
+ var CreateProductInputSchema = z.object({
2919
+ /** Name of the product (required). */
2920
+ name: z.string(),
2921
+ /** Unique slug identifier for the product (required). */
2922
+ identifier: z.string(),
2923
+ /** Product type identifier (required). */
2924
+ type: z.string(),
2925
+ /** The supplier's id (required for main products). */
2926
+ supplier_id: idSchema.optional(),
2927
+ /** USP shown in the agent portal during a sale. */
2928
+ usp: z.string().optional(),
2929
+ description: z.string().optional(),
2930
+ /** Contract duration in months. */
2931
+ duration: z.union([z.string(), z.number()]).optional(),
2932
+ /** `1` = business, `0` = consumer, `2` = both (main products only). */
2933
+ business: z.union([z.string(), z.number()]).optional(),
2934
+ /** `0` = new customers, `1` = existing, `2` = both (required for main products). */
2935
+ retention: z.union([z.string(), z.number()]).optional(),
2936
+ /** `1` = active, `0` = inactive (required). */
2937
+ active: z.union([z.string(), z.number(), z.boolean()]),
2938
+ /** One-time price. */
2939
+ price: z.union([z.string(), z.number()]).optional(),
2940
+ /** One-time promotion price. */
2941
+ price_action: z.union([z.string(), z.number()]).optional(),
2942
+ /** Monthly price. */
2943
+ price_monthly: z.union([z.string(), z.number()]).optional(),
2944
+ /** Monthly promotion price. */
2945
+ price_monthly_action: z.union([z.string(), z.number()]).optional(),
2946
+ /** Number of months the promotion price applies. */
2947
+ price_monthly_action_value: z.union([z.string(), z.number()]).optional(),
2948
+ /** Start date from which the product can be sold. */
2949
+ valid_from: z.string().optional(),
2950
+ /** End date until which the product can be sold. */
2951
+ valid_till: z.string().optional(),
2952
+ /** Image as `{ content: base64, extension: "png"|"gif"|"jpg"|"jpeg" }`. */
2953
+ image: z.object({ content: z.string().optional(), extension: z.string().optional() }).passthrough().optional(),
2954
+ /** Product documents to attach, as an array. */
2955
+ attachments: z.array(z.unknown()).optional()
2956
+ }).passthrough();
2957
+ var UpdateProductInputSchema = z.object({
2958
+ name: z.string().optional(),
2959
+ identifier: z.string().optional(),
2960
+ type: z.string().optional(),
2961
+ supplier_id: idSchema.optional(),
2962
+ usp: z.string().optional(),
2963
+ description: z.string().optional(),
2964
+ duration: z.union([z.string(), z.number()]).optional(),
2965
+ business: z.union([z.string(), z.number()]).optional(),
2966
+ retention: z.union([z.string(), z.number()]).optional(),
2967
+ active: z.union([z.string(), z.number(), z.boolean()]).optional(),
2968
+ price: z.union([z.string(), z.number()]).optional(),
2969
+ price_action: z.union([z.string(), z.number()]).optional(),
2970
+ price_monthly: z.union([z.string(), z.number()]).optional(),
2971
+ price_monthly_action: z.union([z.string(), z.number()]).optional(),
2972
+ price_monthly_action_value: z.union([z.string(), z.number()]).optional(),
2973
+ valid_from: z.string().optional(),
2974
+ valid_till: z.string().optional(),
2975
+ image: z.object({ content: z.string().optional(), extension: z.string().optional() }).passthrough().optional(),
2976
+ attachments: z.array(z.unknown()).optional()
2977
+ }).passthrough();
2978
+ var ConnectOrganisationToProductsInputSchema = z.object({
2979
+ /**
2980
+ * Product ids to connect. Omit to connect all available products; send an
2981
+ * empty array to disconnect all.
2982
+ */
2983
+ products: z.array(idSchema).optional()
2984
+ }).passthrough();
2985
+ var ConnectProductToOrganisationsInputSchema = z.object({
2986
+ /**
2987
+ * Organisation ids to connect. Omit to connect all available organisations;
2988
+ * send an empty array to disconnect all.
2989
+ */
2990
+ organisations: z.array(idSchema).optional()
2991
+ }).passthrough();
2992
+ var ProductsClient = class extends BaseResource {
2993
+ constructor(http, config) {
2994
+ super(http, config);
2995
+ this.suppliers = new SuppliersClient(http, config);
2996
+ }
2997
+ /** List products with their basic details. Honors the configured scope. */
2998
+ list(params = {}, options) {
2999
+ return this.http.request({
3000
+ method: "GET",
3001
+ segments: [this.scope(options), "products"],
3002
+ dataSchema: z.array(ProductListItemSchema),
3003
+ query: params,
3004
+ options
3005
+ });
3006
+ }
3007
+ /** Retrieve a single product by id. Honors the configured scope. */
3008
+ get(productId, options) {
3009
+ return this.http.request({
3010
+ method: "GET",
3011
+ segments: [this.scope(options), "products", productId],
3012
+ dataSchema: ProductSchema,
3013
+ options
3014
+ });
3015
+ }
3016
+ /** Create a product (always `account` scope, admin only). */
3017
+ create(input, options) {
3018
+ const body = this.parseInput(CreateProductInputSchema, input, "products.create");
3019
+ return this.http.request({
3020
+ method: "POST",
3021
+ segments: ["account", "products"],
3022
+ dataSchema: MutateProductResultSchema,
3023
+ body,
3024
+ options
3025
+ });
3026
+ }
3027
+ /** Update a product by id (always `account` scope, admin only). */
3028
+ update(productId, input, options) {
3029
+ const body = this.parseInput(UpdateProductInputSchema, input, "products.update");
3030
+ return this.http.request({
3031
+ method: "PUT",
3032
+ segments: ["account", "products", productId],
3033
+ dataSchema: MutateProductResultSchema,
3034
+ body,
3035
+ options
3036
+ });
3037
+ }
3038
+ /** Delete a product by id (always `account` scope, admin only). */
3039
+ delete(productId, options) {
3040
+ return this.http.request({
3041
+ method: "DELETE",
3042
+ segments: ["account", "products", productId],
3043
+ dataSchema: MutateProductResultSchema,
3044
+ options
3045
+ });
3046
+ }
3047
+ /**
3048
+ * Connect a set of products to an organisation so its users can sell them.
3049
+ * Always `account` scope (admin only). Omit `products` to connect all; pass
3050
+ * an empty array to disconnect all. Returns the connected product ids.
3051
+ */
3052
+ connectOrganisationToProducts(organisationId, input = {}, options) {
3053
+ const body = this.parseInput(
3054
+ ConnectOrganisationToProductsInputSchema,
3055
+ input,
3056
+ "products.connectOrganisationToProducts"
3057
+ );
3058
+ return this.http.request({
3059
+ method: "POST",
3060
+ segments: ["account", "connect-organisation-to-products", organisationId],
3061
+ dataSchema: ConnectOrganisationResultSchema,
3062
+ body,
3063
+ options
3064
+ });
3065
+ }
3066
+ /**
3067
+ * Connect a set of organisations to a product so their users can sell it.
3068
+ * Always `account` scope (admin only). Omit `organisations` to connect all;
3069
+ * pass an empty array to disconnect all. Returns the connected organisation ids.
3070
+ */
3071
+ connectProductToOrganisations(productId, input = {}, options) {
3072
+ const body = this.parseInput(
3073
+ ConnectProductToOrganisationsInputSchema,
3074
+ input,
3075
+ "products.connectProductToOrganisations"
3076
+ );
3077
+ return this.http.request({
3078
+ method: "POST",
3079
+ segments: ["account", "connect-product-to-organisations", productId],
3080
+ dataSchema: ConnectProductResultSchema,
3081
+ body,
3082
+ options
3083
+ });
3084
+ }
3085
+ };
3086
+ var TaskUserRefSchema = loose({
3087
+ id: nullish(idSchema),
3088
+ name: nullish(z.string()),
3089
+ organisation: loose({
3090
+ id: nullish(idSchema),
3091
+ name: nullish(z.string())
3092
+ }).optional(),
3093
+ team: loose({
3094
+ id: nullish(idSchema),
3095
+ name: nullish(z.string())
3096
+ }).optional()
3097
+ });
3098
+ var TaskListItemSchema = loose({
3099
+ id: idSchema,
3100
+ title: nullish(z.string()),
3101
+ type: nullish(z.string()),
3102
+ status: nullish(z.string()),
3103
+ planned_date: nullish(z.string()),
3104
+ planned_time: nullish(z.string()),
3105
+ end_time: nullish(z.string()),
3106
+ assigned_user_id: nullish(idSchema),
3107
+ owner_user_id: nullish(idSchema),
3108
+ assigned_to: TaskUserRefSchema.optional(),
3109
+ owner: TaskUserRefSchema.optional(),
3110
+ description: nullish(z.string()),
3111
+ remarks: nullish(z.string()),
3112
+ location: nullish(z.string()),
3113
+ lead_id: nullish(idSchema),
3114
+ relation_id: nullish(idSchema),
3115
+ completed_at: nullish(z.string()),
3116
+ created_at: nullish(z.string()),
3117
+ updated_at: nullish(z.string())
3118
+ });
3119
+ var TaskSchema = loose({
3120
+ id: idSchema,
3121
+ title: nullish(z.string()),
3122
+ type: nullish(z.string()),
3123
+ status: nullish(z.string()),
3124
+ description: nullish(z.string()),
3125
+ remarks: nullish(z.string()),
3126
+ location: nullish(z.string()),
3127
+ planned_date: nullish(z.string()),
3128
+ planned_time: nullish(z.string()),
3129
+ end_time: nullish(z.string()),
3130
+ assigned_user_id: nullish(idSchema),
3131
+ assigned_user: nullish(z.string()),
3132
+ owner_user_id: nullish(idSchema),
3133
+ owner_user: nullish(z.string()),
3134
+ assigned_to: TaskUserRefSchema.optional(),
3135
+ owner: TaskUserRefSchema.optional(),
3136
+ lead_id: nullish(idSchema),
3137
+ relation_id: nullish(idSchema),
3138
+ completed_at: nullish(z.string()),
3139
+ created_at: nullish(z.string()),
3140
+ updated_at: nullish(z.string())
3141
+ });
3142
+ var MutateTaskResultSchema = loose({ task_id: idSchema });
3143
+ var TaskInputSchema = z.object({
3144
+ /** The title of the task (required). */
3145
+ title: z.string(),
3146
+ /** Task type: `default`, `appointment`, or `callback` (required). */
3147
+ type: z.string(),
3148
+ /** Description of the task. */
3149
+ description: z.string().optional(),
3150
+ /** Remarks (if any) for the task. */
3151
+ remarks: z.string().optional(),
3152
+ /** The location where the task is planned to take place. */
3153
+ location: z.string().optional(),
3154
+ /** The planned date of the task in `dd-mm-yyyy` format. */
3155
+ planned_date: z.string().optional(),
3156
+ /** The planned start time of the task in `hh:mm` format. */
3157
+ planned_start_time: z.string().optional(),
3158
+ /** The planned end time of the task in `hh:mm` format. */
3159
+ planned_end_time: z.string().optional(),
3160
+ /** The ID of the user to assign the task to. */
3161
+ user_id: idSchema.optional(),
3162
+ /** The ID of the relation to attach the task to. */
3163
+ relation_id: idSchema.optional(),
3164
+ /** Whether the task is completed: `yes` or `no`. */
3165
+ completed: z.union([z.literal("yes"), z.literal("no")]).optional()
3166
+ }).passthrough();
3167
+ var TasksClient = class extends BaseResource {
3168
+ /** List tasks (cursor-paginated). Honors the configured scope. */
3169
+ list(params = {}, options) {
3170
+ return fetchCursorPage(
3171
+ this.http,
3172
+ TaskListItemSchema,
3173
+ [this.scope(options), "tasks"],
3174
+ params,
3175
+ options
3176
+ );
3177
+ }
3178
+ /** Retrieve a single task by id. Honors the configured scope. */
3179
+ get(taskId, options) {
3180
+ return this.http.request({
3181
+ method: "GET",
3182
+ segments: [this.scope(options), "tasks", taskId],
3183
+ dataSchema: TaskSchema,
3184
+ options
3185
+ });
3186
+ }
3187
+ /** Create a task. Honors the configured scope. */
3188
+ create(input, options) {
3189
+ const body = this.parseInput(TaskInputSchema, input, "tasks.create");
3190
+ return this.http.request({
3191
+ method: "POST",
3192
+ segments: [this.scope(options), "tasks"],
3193
+ dataSchema: MutateTaskResultSchema,
3194
+ body,
3195
+ options
3196
+ });
3197
+ }
3198
+ /** Update a task by id. Honors the configured scope. */
3199
+ update(taskId, input, options) {
3200
+ const body = this.parseInput(TaskInputSchema, input, "tasks.update");
3201
+ return this.http.request({
3202
+ method: "PUT",
3203
+ segments: [this.scope(options), "tasks", taskId],
3204
+ dataSchema: MutateTaskResultSchema,
3205
+ body,
3206
+ options
3207
+ });
3208
+ }
3209
+ /** Delete a task by id (always `account` scope, admin only). */
3210
+ delete(taskId, options) {
3211
+ return this.http.request({
3212
+ method: "DELETE",
3213
+ segments: ["account", "tasks", taskId],
3214
+ dataSchema: MutateTaskResultSchema,
3215
+ options
3216
+ });
3217
+ }
3218
+ };
3219
+ var KNOWN_WEBHOOK_EVENTS = [
3220
+ "task.created",
3221
+ "offer.accepted",
3222
+ "offer.viewed",
3223
+ "sale.cancelled",
3224
+ "sale.deleted",
3225
+ "lead.created",
3226
+ "lead.updated",
3227
+ "lead.deleted",
3228
+ "lead.completed",
3229
+ "product.updated"
3230
+ ];
3231
+ var WebhookSubscriptionSchema = loose({
3232
+ uuid: z.string(),
3233
+ event: z.string(),
3234
+ target_url: z.string(),
3235
+ subscribed_at: z.string()
3236
+ });
3237
+ var SubscribeWebhookSchema = z.object({
3238
+ /** The event to subscribe to, e.g. `"offer.accepted"`. */
3239
+ event: z.string(),
3240
+ /** The URL Salesdock will POST the event payload to. */
3241
+ target_url: z.string().url()
3242
+ }).passthrough();
3243
+ var WebhooksClient = class extends BaseResource {
3244
+ /** List the webhook event types you can subscribe to. */
3245
+ listEvents(options) {
3246
+ return this.http.request({
3247
+ method: "GET",
3248
+ segments: ["account", "webhooks", "events"],
3249
+ dataSchema: z.array(z.string()),
3250
+ options
3251
+ });
3252
+ }
3253
+ /** Subscribe a `target_url` to an event. */
3254
+ subscribe(input, options) {
3255
+ const body = this.parseInput(SubscribeWebhookSchema, input, "webhooks.subscribe");
3256
+ return this.http.request({
3257
+ method: "POST",
3258
+ segments: ["account", "webhooks"],
3259
+ dataSchema: WebhookSubscriptionSchema,
3260
+ body,
3261
+ options
3262
+ });
3263
+ }
3264
+ /** List your current webhook subscriptions. */
3265
+ listSubscriptions(options) {
3266
+ return this.http.request({
3267
+ method: "GET",
3268
+ segments: ["account", "webhooks"],
3269
+ dataSchema: z.array(WebhookSubscriptionSchema),
3270
+ options
3271
+ });
3272
+ }
3273
+ /** Unsubscribe by subscription UUID. */
3274
+ unsubscribe(uuid, options) {
3275
+ return this.http.request({
3276
+ method: "DELETE",
3277
+ segments: ["account", "webhooks", uuid],
3278
+ dataSchema: z.unknown(),
3279
+ options
3280
+ });
3281
+ }
3282
+ };
3283
+
3284
+ // src/client.ts
3285
+ var Salesdock = class {
3286
+ constructor(config) {
3287
+ this.config = resolveConfig(config);
3288
+ this.http = new HttpClient(this.config);
3289
+ this.sales = new SalesClient(this.http, this.config);
3290
+ this.dialer = new DialerClient(this.http, this.config);
3291
+ this.users = new UsersClient(this.http, this.config);
3292
+ this.commissions = new CommissionsClient(this.http, this.config);
3293
+ this.leads = new LeadsClient(this.http, this.config);
3294
+ this.forms = new FormsClient(this.http, this.config);
3295
+ this.relations = new RelationsClient(this.http, this.config);
3296
+ this.products = new ProductsClient(this.http, this.config);
3297
+ this.tasks = new TasksClient(this.http, this.config);
3298
+ this.webhooks = new WebhooksClient(this.http, this.config);
3299
+ }
3300
+ /**
3301
+ * Low-level escape hatch for endpoints (or query/body shapes) not covered by
3302
+ * a typed method. `segments` are the path parts after
3303
+ * `/api/{domain}/{version}/` and must include the scope segment yourself
3304
+ * (e.g. `["account", "sales", 440]`). The response `data` is returned as-is.
3305
+ *
3306
+ * @example
3307
+ * ```ts
3308
+ * const data = await sd.request("GET", ["account", "commissions", "outgoing"]);
3309
+ * ```
3310
+ */
3311
+ request(method, segments, init = {}) {
3312
+ return this.http.request({
3313
+ method,
3314
+ segments,
3315
+ dataSchema: z.unknown(),
3316
+ query: init.query,
3317
+ body: init.body,
3318
+ options: init.options
3319
+ });
3320
+ }
3321
+ };
3322
+ /** Production base URL (`https://app.salesdock.nl`). */
3323
+ Salesdock.PRODUCTION_BASE_URL = PRODUCTION_BASE_URL;
3324
+ /** Staging base URL (`https://app-staging.salesdock.nl`). */
3325
+ Salesdock.STAGING_BASE_URL = STAGING_BASE_URL;
3326
+
3327
+ // src/core/base64.ts
3328
+ function decodeBase64(base64) {
3329
+ let normalized = base64.replace(/\s+/g, "").replace(/-/g, "+").replace(/_/g, "/");
3330
+ const remainder = normalized.length % 4;
3331
+ if (remainder === 2) normalized += "==";
3332
+ else if (remainder === 3) normalized += "=";
3333
+ const binary = atob(normalized);
3334
+ const len = binary.length;
3335
+ const bytes = new Uint8Array(len);
3336
+ for (let i = 0; i < len; i++) {
3337
+ bytes[i] = binary.charCodeAt(i);
3338
+ }
3339
+ return bytes;
3340
+ }
3341
+
3342
+ export { AgreementListItemSchema, AgreementSchema, BaseResource, CommissionListSchema, CommissionSchema, CommissionTotalsBreakdownSchema, CommissionTotalsSchema, CommissionsClient, ConceptFieldSchema, ConceptFieldsSchema, ConceptLeadResultSchema, ConceptTransactionResultSchema, ConceptTransactionSalesSchema, ConnectOrganisationResultSchema, ConnectOrganisationToProductsInputSchema, ConnectProductResultSchema, ConnectProductToOrganisationsInputSchema, CreateConceptLeadSchema, CreateConceptTransactionSchema, CreateConceptTransactionWithOptinSchema, CreateLeadAsAdminSchema, CreateLeadAsResellerSchema, CreateLeadFormInstanceResultSchema, CreateLeadFormInstanceSchema, CreateOptinInputSchema, CreateProductInputSchema, CreateSaleResultSchema, CursorPage, DEFAULT_VERSION, DefaultSaleInputSchema, DialerClient, EnergyBeClient, EnergyBeSaleInputSchema, EnergyClient, EnergyNlClient, EnergyNlSaleInputSchema, EnergyProductSchema, EnergyUsageEstimationSchema, FillFormFileSchema, FillFormInstanceResultSchema, FillFormInstanceSchema, FlowListItemSchema, FlowSchema, FormElementSchema, FormInstanceListItemSchema, FormInstancePdfSchema, FormInstanceRelationSchema, FormInstanceSchema, FormSchema, FormStatusSchema, FormsClient, HeatPumpSaleInputSchema, HeatPumpsClient, HostedVoiceClient, HostedVoiceSaleInputSchema, IncomingCommissionsClient, InviteUserInputSchema, KNOWN_WEBHOOK_EVENTS, LastSaleSchema, LeadActivitySchema, LeadFormElementSchema, LeadFormPdfSchema, LeadFormSchema, LeadHistoryEntrySchema, LeadLabelSchema, LeadListItemSchema, LeadResultSchema, LeadSchema, LeadSourceSchema, LeadStatusSchema, LeadsClient, MediaBlobSchema, MultiProductSaleInputSchema, MutateLeadResultSchema, MutateOrganisationResultSchema, MutateProductResultSchema, MutateRelationResultSchema, MutateSaleResultSchema, MutateSupplierResultSchema, MutateTaskResultSchema, OffsetPage, OptinChannelInputSchema, OrganisationInputSchema, OrganisationListItemSchema, OrganisationLogoInputSchema, OrganisationLogoSchema, OrganisationProductsSchema, OrganisationSchema, OrganisationsClient, OutgoingCommissionsClient, PRODUCTION_BASE_URL, PanelsEstimationSchema, ProductDocumentSchema, ProductListItemSchema, ProductQuestionListItemSchema, ProductQuestionSchema, ProductSchema, ProductsClient, RelationInputSchema, RelationListItemSchema, RelationSchema, RelationsClient, SDK_VERSION, STAGING_BASE_URL, SaleContractSchema, SaleDocumentSchema, SaleExportRowSchema, SaleHistoryEntrySchema, SaleListItemSchema, SaleOfLeadSchema, SaleProductsSchema, SaleSchema, SaleStatusSchema, SaleViewUrlSchema, SalesClient, Salesdock, SalesdockAuthenticationError, SalesdockConnectionError, SalesdockError, SalesdockForbiddenError, SalesdockInvalidRequestError, SalesdockMethodNotAllowedError, SalesdockNotFoundError, SalesdockRateLimitError, SalesdockResponseValidationError, SalesdockServerError, SalesdockTimeoutError, SalesdockValidationError, SolarClient, SolarComparePackageSchema, SolarSaleInputSchema, SubscribeWebhookSchema, SupplierInputSchema, SupplierListItemSchema, SupplierSchema, SuppliersClient, TaskInputSchema, TaskListItemSchema, TaskSchema, TaskUserRefSchema, TasksClient, TelecomClient, TelecomCompareSchema, TelecomSaleInputSchema, TownshipSchema, TownshipsClient, UpdateEnergyProductInputSchema, UpdateLeadAsAdminSchema, UpdateLeadAsResellerSchema, UpdateLeadStatusSchema, UpdateProductInputSchema, UpdateSaleFieldsInputSchema, UpdateSaleInputSchema, UserSchema, UsersClient, WebhookSubscriptionSchema, WebhooksClient, addressSchema, boolishSchema, cursorPaginatedSchema, customerSchema, dateTimeSchema, decodeBase64, envelopeSchema, extraFieldSchema, idSchema, loose, nullish, offsetPaginatedSchema, paginationLinkSchema, statusSchema };
3343
+ //# sourceMappingURL=index.js.map
3344
+ //# sourceMappingURL=index.js.map