@verentis/sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -8
- package/dist/index.cjs +571 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +527 -6
- package/dist/index.d.ts +527 -6
- package/dist/index.js +568 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,6 +28,14 @@ var BridgeAuth = class {
|
|
|
28
28
|
_refreshTimer = null;
|
|
29
29
|
_pendingRefresh = null;
|
|
30
30
|
_messageHandler;
|
|
31
|
+
_requestId = null;
|
|
32
|
+
_refreshReject = null;
|
|
33
|
+
_requestTimer = null;
|
|
34
|
+
_destroyed = false;
|
|
35
|
+
setHostOrigin(origin) {
|
|
36
|
+
if (!origin || origin === "*" || origin === "null") throw new Error("A trusted host origin is required.");
|
|
37
|
+
this.hostOrigin = origin;
|
|
38
|
+
}
|
|
31
39
|
/** Set the initial token received from the host's `verentis:init` message */
|
|
32
40
|
setToken(info) {
|
|
33
41
|
this._token = info.accessToken;
|
|
@@ -42,7 +50,9 @@ var BridgeAuth = class {
|
|
|
42
50
|
return `Bearer ${this._token}`;
|
|
43
51
|
}
|
|
44
52
|
destroy() {
|
|
53
|
+
this._destroyed = true;
|
|
45
54
|
if (this._refreshTimer) clearTimeout(this._refreshTimer);
|
|
55
|
+
this.failRefresh("Authentication has been destroyed.");
|
|
46
56
|
if (typeof window !== "undefined") {
|
|
47
57
|
window.removeEventListener("message", this._messageHandler);
|
|
48
58
|
}
|
|
@@ -52,11 +62,16 @@ var BridgeAuth = class {
|
|
|
52
62
|
}
|
|
53
63
|
_refreshResolve = null;
|
|
54
64
|
requestRefresh() {
|
|
65
|
+
if (this._destroyed || this.hostOrigin === "*")
|
|
66
|
+
return Promise.reject(new Error("Authentication is not initialized."));
|
|
55
67
|
if (this._pendingRefresh) return this._pendingRefresh;
|
|
56
68
|
const requestId = crypto.randomUUID();
|
|
57
|
-
this.
|
|
69
|
+
this._requestId = requestId;
|
|
70
|
+
this._pendingRefresh = new Promise((resolve, reject) => {
|
|
58
71
|
this._refreshResolve = resolve;
|
|
72
|
+
this._refreshReject = reject;
|
|
59
73
|
});
|
|
74
|
+
this._requestTimer = setTimeout(() => this.failRefresh("Token refresh timed out."), 2e4);
|
|
60
75
|
const message = {
|
|
61
76
|
type: "verentis:token:refresh",
|
|
62
77
|
version: 1,
|
|
@@ -66,21 +81,35 @@ var BridgeAuth = class {
|
|
|
66
81
|
return this._pendingRefresh;
|
|
67
82
|
}
|
|
68
83
|
handleMessage(event) {
|
|
69
|
-
if (event.origin !== this.hostOrigin) return;
|
|
84
|
+
if (this._destroyed || event.origin !== this.hostOrigin || event.source !== window.parent) return;
|
|
70
85
|
const data = event.data;
|
|
71
|
-
if (data?.type !== "verentis:token:refreshed") return;
|
|
86
|
+
if (data?.version !== 1 || data?.type !== "verentis:token:refreshed" || !this._requestId || data.requestId !== this._requestId || typeof data.token?.accessToken !== "string" || !Number.isFinite(Date.parse(data.token.expiresAt)) || Date.parse(data.token.expiresAt) <= Date.now() + SKEW_MS) return;
|
|
87
|
+
if (this._requestTimer) clearTimeout(this._requestTimer);
|
|
88
|
+
this._requestTimer = null;
|
|
89
|
+
this._requestId = null;
|
|
72
90
|
this._token = data.token.accessToken;
|
|
73
91
|
this._expiresAt = new Date(data.token.expiresAt).getTime();
|
|
74
92
|
this._pendingRefresh = null;
|
|
75
93
|
this._refreshResolve?.();
|
|
76
94
|
this._refreshResolve = null;
|
|
95
|
+
this._refreshReject = null;
|
|
77
96
|
this.scheduleRefresh();
|
|
78
97
|
}
|
|
79
98
|
scheduleRefresh() {
|
|
80
99
|
if (this._refreshTimer) clearTimeout(this._refreshTimer);
|
|
81
100
|
if (this._expiresAt === 0) return;
|
|
82
101
|
const delay2 = Math.max(0, this._expiresAt - Date.now() - SKEW_MS);
|
|
83
|
-
this._refreshTimer = setTimeout(() => void this.requestRefresh()
|
|
102
|
+
this._refreshTimer = setTimeout(() => void this.requestRefresh().catch(() => {
|
|
103
|
+
}), delay2);
|
|
104
|
+
}
|
|
105
|
+
failRefresh(message) {
|
|
106
|
+
if (this._requestTimer) clearTimeout(this._requestTimer);
|
|
107
|
+
this._requestTimer = null;
|
|
108
|
+
this._requestId = null;
|
|
109
|
+
this._pendingRefresh = null;
|
|
110
|
+
this._refreshReject?.(new Error(message));
|
|
111
|
+
this._refreshReject = null;
|
|
112
|
+
this._refreshResolve = null;
|
|
84
113
|
}
|
|
85
114
|
};
|
|
86
115
|
|
|
@@ -138,6 +167,8 @@ var ContextModule = class {
|
|
|
138
167
|
_file = null;
|
|
139
168
|
_entryPoint = null;
|
|
140
169
|
_apiUrl = null;
|
|
170
|
+
_application = null;
|
|
171
|
+
_installation = null;
|
|
141
172
|
/** The current workspace */
|
|
142
173
|
get workspace() {
|
|
143
174
|
if (!this._workspace) {
|
|
@@ -178,13 +209,24 @@ var ContextModule = class {
|
|
|
178
209
|
get hasEntryPoint() {
|
|
179
210
|
return this._entryPoint !== null;
|
|
180
211
|
}
|
|
212
|
+
get application() {
|
|
213
|
+
return this._application ? { ...this._application } : null;
|
|
214
|
+
}
|
|
215
|
+
get installation() {
|
|
216
|
+
return this._installation ? { ...this._installation } : null;
|
|
217
|
+
}
|
|
181
218
|
/** Update context from the host's init message */
|
|
182
219
|
setFromAppContext(ctx) {
|
|
220
|
+
if (ctx.application !== void 0 && (typeof ctx.application !== "object" || ctx.application === null || typeof ctx.application.manifestPath !== "string" || !ctx.application.manifestPath.startsWith("/") || typeof ctx.application.manifestNodeId !== "string" || !ctx.application.manifestNodeId.trim() || typeof ctx.application.branch !== "string" || !ctx.application.branch || ctx.application.branch !== ctx.application.branch.trim().toLowerCase() || /[\u0000-\u001f\u007f]/.test(ctx.application.branch))) {
|
|
221
|
+
throw new Error("Invalid application launch metadata");
|
|
222
|
+
}
|
|
183
223
|
this._workspace = ctx.workspace;
|
|
184
224
|
this._surface = ctx.surface ?? "file";
|
|
185
225
|
this._file = ctx.file ?? null;
|
|
186
226
|
this._entryPoint = ctx.entryPoint ?? null;
|
|
187
227
|
this._apiUrl = ctx.apiUrl;
|
|
228
|
+
this._application = ctx.application ? { ...ctx.application } : null;
|
|
229
|
+
this._installation = ctx.installation ? { ...ctx.installation } : null;
|
|
188
230
|
}
|
|
189
231
|
/** Set workspace info directly (standalone mode) */
|
|
190
232
|
setWorkspace(workspace) {
|
|
@@ -412,6 +454,49 @@ var FilesModule = class {
|
|
|
412
454
|
headers: this.workspaceHeaders()
|
|
413
455
|
});
|
|
414
456
|
}
|
|
457
|
+
/** Read metadata by stable node identity on an explicit branch. */
|
|
458
|
+
async getNode(nodeId, options) {
|
|
459
|
+
requireNonBlank(nodeId, "Node ID");
|
|
460
|
+
requireNonBlank(options.branch, "Branch");
|
|
461
|
+
return this.http.request("GET", `/nodes/${encodeURIComponent(nodeId)}/file`, {
|
|
462
|
+
headers: { ...this.workspaceHeaders(), "X-Branch": options.branch }
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
/** Read bytes and their matching content revision in the same response. */
|
|
466
|
+
async readNodeContent(nodeId, options) {
|
|
467
|
+
requireNonBlank(nodeId, "Node ID");
|
|
468
|
+
requireNonBlank(options.branch, "Branch");
|
|
469
|
+
const response = await this.http.requestRaw("GET", `/nodes/${encodeURIComponent(nodeId)}/content`, {
|
|
470
|
+
headers: { ...this.workspaceHeaders(), "X-Branch": options.branch, Accept: "*/*" }
|
|
471
|
+
});
|
|
472
|
+
await this.http.ensureSuccess(response);
|
|
473
|
+
const revision = response.headers.get("ETag");
|
|
474
|
+
if (!revision || !/^"[a-fA-F0-9]{32}"$/.test(revision)) {
|
|
475
|
+
throw new Error("Node-content response did not include a valid strong revision ETag.");
|
|
476
|
+
}
|
|
477
|
+
return { content: await response.blob(), revision };
|
|
478
|
+
}
|
|
479
|
+
/** Replace existing node bytes conditionally; never creates or changes path/MIME. */
|
|
480
|
+
async writeNodeContent(nodeId, options) {
|
|
481
|
+
requireNonBlank(nodeId, "Node ID");
|
|
482
|
+
requireNonBlank(options.branch, "Branch");
|
|
483
|
+
requireNonBlank(options.idempotencyKey, "Idempotency key");
|
|
484
|
+
const revision = /^[a-fA-F0-9]{32}$/.test(options.revision) ? `"${options.revision}"` : options.revision;
|
|
485
|
+
if (!/^"[a-fA-F0-9]{32}"$/.test(revision)) {
|
|
486
|
+
throw new Error("A single strong node-content revision is required.");
|
|
487
|
+
}
|
|
488
|
+
const content = typeof options.content === "string" ? new Blob([options.content]) : options.content instanceof ArrayBuffer ? new Blob([options.content]) : options.content;
|
|
489
|
+
return this.http.request("PUT", `/nodes/${encodeURIComponent(nodeId)}/content`, {
|
|
490
|
+
body: content,
|
|
491
|
+
headers: {
|
|
492
|
+
...this.workspaceHeaders(),
|
|
493
|
+
"X-Branch": options.branch,
|
|
494
|
+
"If-Match": revision,
|
|
495
|
+
"Idempotency-Key": options.idempotencyKey,
|
|
496
|
+
"Content-Type": "application/octet-stream"
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
415
500
|
/**
|
|
416
501
|
* Read the raw content of a file as a Blob.
|
|
417
502
|
*/
|
|
@@ -528,14 +613,19 @@ var FilesModule = class {
|
|
|
528
613
|
* Delete a file.
|
|
529
614
|
*/
|
|
530
615
|
async remove(options) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
616
|
+
const path = normalizePath(options.path);
|
|
617
|
+
requireNonBlank(path, "File path");
|
|
618
|
+
const branch = options.branch ?? "main";
|
|
619
|
+
requireNonBlank(branch, "Branch");
|
|
620
|
+
if (options.headStamp !== void 0) requireNonBlank(options.headStamp, "Path head stamp");
|
|
621
|
+
if (options.idempotencyKey !== void 0) requireNonBlank(options.idempotencyKey, "Idempotency key");
|
|
622
|
+
await this.http.request("DELETE", `/files/${path.split("/").map(encodeURIComponent).join("/")}`, {
|
|
623
|
+
params: { branch },
|
|
536
624
|
headers: {
|
|
537
625
|
...this.workspaceHeaders(),
|
|
538
|
-
"
|
|
626
|
+
...options.headStamp === void 0 ? {} : { "If-Match": options.headStamp },
|
|
627
|
+
...options.idempotencyKey === void 0 ? {} : { "Idempotency-Key": options.idempotencyKey },
|
|
628
|
+
...options.mode === void 0 ? {} : { "X-Delete-Mode": options.mode === "deep" ? "Deep" : "Shallow" }
|
|
539
629
|
}
|
|
540
630
|
});
|
|
541
631
|
}
|
|
@@ -547,6 +637,9 @@ var FilesModule = class {
|
|
|
547
637
|
return headers;
|
|
548
638
|
}
|
|
549
639
|
};
|
|
640
|
+
function requireNonBlank(value, name) {
|
|
641
|
+
if (value.trim().length === 0) throw new Error(`${name} is required.`);
|
|
642
|
+
}
|
|
550
643
|
function normalizePath(path) {
|
|
551
644
|
return path.replace(/\/+/g, "/").replace(/^\//, "").replace(/\/$/, "");
|
|
552
645
|
}
|
|
@@ -563,6 +656,52 @@ var InstallationsModule = class {
|
|
|
563
656
|
}
|
|
564
657
|
http;
|
|
565
658
|
workspaceId;
|
|
659
|
+
/** Resolve canonical publisher/package identity, never the installation's runtime display name. */
|
|
660
|
+
async resolvePackageId(identity, options) {
|
|
661
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*\/[a-z0-9]+(?:-[a-z0-9]+)*$/.test(identity)) {
|
|
662
|
+
throw new Error("A canonical publisher/package identity is required");
|
|
663
|
+
}
|
|
664
|
+
const result = await this.http.request("GET", `/packages/by-package-id/${identity}`, {
|
|
665
|
+
params: { workspaceId: this.requireWorkspaceId(options?.workspaceId) }
|
|
666
|
+
});
|
|
667
|
+
if (!result || typeof result.id !== "string" || !/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(result.id)) {
|
|
668
|
+
throw new Error("The catalog response omitted its stable package identity");
|
|
669
|
+
}
|
|
670
|
+
return result.id;
|
|
671
|
+
}
|
|
672
|
+
/** Resolves the complete required graph without installing anything or granting capabilities. */
|
|
673
|
+
async preview(packageId, options) {
|
|
674
|
+
return this.http.request("POST", "/installations/graphs/preview", {
|
|
675
|
+
body: JSON.stringify({
|
|
676
|
+
workspaceId: this.requireWorkspaceId(options?.workspaceId),
|
|
677
|
+
packageId,
|
|
678
|
+
packageVersion: options?.packageVersion,
|
|
679
|
+
installPath: options?.installPath,
|
|
680
|
+
branch: options?.branch,
|
|
681
|
+
installMode: options?.installMode
|
|
682
|
+
}),
|
|
683
|
+
headers: { "Content-Type": "application/json" }
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
/** Explicit, single-use consent to a displayed preview. Never automatically retries accepted installs. */
|
|
687
|
+
async install(preview, consent) {
|
|
688
|
+
if (consent !== true) throw new Error("Explicit consent to the installation graph is required");
|
|
689
|
+
return this.http.request("POST", "/installations/graphs", {
|
|
690
|
+
body: JSON.stringify({
|
|
691
|
+
workspaceId: preview.workspaceId,
|
|
692
|
+
operationId: preview.operationId,
|
|
693
|
+
fingerprint: preview.fingerprint,
|
|
694
|
+
consent
|
|
695
|
+
}),
|
|
696
|
+
headers: { "Content-Type": "application/json" }
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
/** Inspect durable outcomes after a failure or lost response instead of resubmitting consent. */
|
|
700
|
+
async graphResult(operationId, options) {
|
|
701
|
+
return this.http.request("GET", `/installations/graphs/${encodeURIComponent(operationId)}`, {
|
|
702
|
+
params: { workspaceId: this.requireWorkspaceId(options?.workspaceId) }
|
|
703
|
+
});
|
|
704
|
+
}
|
|
566
705
|
async list(options) {
|
|
567
706
|
return this.http.request("GET", "/installations", {
|
|
568
707
|
params: {
|
|
@@ -743,23 +882,212 @@ var SettingsModule = class {
|
|
|
743
882
|
}
|
|
744
883
|
};
|
|
745
884
|
|
|
885
|
+
// src/modules/email.ts
|
|
886
|
+
var EmailModule = class {
|
|
887
|
+
constructor(http, workspaceId) {
|
|
888
|
+
this.http = http;
|
|
889
|
+
this.workspaceId = workspaceId;
|
|
890
|
+
}
|
|
891
|
+
http;
|
|
892
|
+
workspaceId;
|
|
893
|
+
async preview(installationId, options) {
|
|
894
|
+
return this.http.request("GET", `/installations/${encodeURIComponent(installationId)}/email-consent-preview`, {
|
|
895
|
+
params: { workspaceId: this.workspace(options) }
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
async consents(options) {
|
|
899
|
+
return this.http.request("GET", "/email/consents", { params: { workspaceId: this.workspace(options) } });
|
|
900
|
+
}
|
|
901
|
+
/** Approve exactly the reviewed signed candidate; tracking stays off unless explicitly opted in. */
|
|
902
|
+
async consent(preview, approval, options) {
|
|
903
|
+
if (approval !== true) throw new Error("Explicit email consent is required");
|
|
904
|
+
if (!options?.senderGrants?.length) throw new Error("Explicit purpose/sender grants are required");
|
|
905
|
+
return this.http.request("PUT", `/email/consents/${encodeURIComponent(preview.installationId)}`, {
|
|
906
|
+
params: { workspaceId: preview.workspaceId },
|
|
907
|
+
body: JSON.stringify({
|
|
908
|
+
candidateDigest: preview.candidateDigest,
|
|
909
|
+
enabled: true,
|
|
910
|
+
allowOpenTracking: options?.allowOpenTracking ?? false,
|
|
911
|
+
allowClickTracking: options?.allowClickTracking ?? false,
|
|
912
|
+
senderGrants: options.senderGrants.map((grant) => ({ purpose: grant.purpose, senderId: grant.senderId }))
|
|
913
|
+
}),
|
|
914
|
+
headers: { "Content-Type": "application/json" }
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
async revoke(consent, options) {
|
|
918
|
+
return this.http.request("PUT", `/email/consents/${encodeURIComponent(consent.installationId)}`, {
|
|
919
|
+
params: { workspaceId: this.workspace(options) },
|
|
920
|
+
body: JSON.stringify({ candidateDigest: consent.candidateDigest, enabled: false, allowOpenTracking: false, allowClickTracking: false }),
|
|
921
|
+
headers: { "Content-Type": "application/json" }
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
async senders(options) {
|
|
925
|
+
return this.http.request("GET", "/email/senders", { params: { workspaceId: this.workspace(options) } });
|
|
926
|
+
}
|
|
927
|
+
async invoicePdf(recordId, installationId, options) {
|
|
928
|
+
this.mainBranch(options);
|
|
929
|
+
return this.http.request("POST", "/email/artifacts/invoice", {
|
|
930
|
+
body: JSON.stringify({ workspaceId: this.workspace(options), recordId, installationId }),
|
|
931
|
+
headers: { "Content-Type": "application/json" }
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
/** Authenticated immutable bytes; no public URL. The caller owns any local object URL it creates. */
|
|
935
|
+
async artifactContent(artifactId, options) {
|
|
936
|
+
this.mainBranch(options);
|
|
937
|
+
return this.http.request("GET", `/email/artifacts/${encodeURIComponent(artifactId)}/content`, {
|
|
938
|
+
params: { workspaceId: this.workspace(options), branch: "main" }
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
/** A stable key binds this exact request. After a lost response inspect status; never automatically resend. */
|
|
942
|
+
async dispatch(options) {
|
|
943
|
+
this.mainBranch(options);
|
|
944
|
+
return this.http.request("POST", "/email/dispatches", {
|
|
945
|
+
body: JSON.stringify({
|
|
946
|
+
workspaceId: this.workspace(options),
|
|
947
|
+
installationId: options.installationId,
|
|
948
|
+
recordId: options.recordId,
|
|
949
|
+
purpose: options.purpose,
|
|
950
|
+
templateId: options.templateId,
|
|
951
|
+
senderId: options.senderId,
|
|
952
|
+
recipients: options.recipients,
|
|
953
|
+
artifactIds: options.artifactIds,
|
|
954
|
+
idempotencyKey: options.idempotencyKey,
|
|
955
|
+
replyTo: options.replyTo
|
|
956
|
+
}),
|
|
957
|
+
headers: { "Content-Type": "application/json" }
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
async outcome(id, options) {
|
|
961
|
+
this.mainBranch(options);
|
|
962
|
+
return this.http.request("GET", `/email/dispatches/${encodeURIComponent(id)}`, {
|
|
963
|
+
params: { workspaceId: this.workspace(options) }
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
async history(options) {
|
|
967
|
+
this.mainBranch(options);
|
|
968
|
+
return this.http.request("GET", "/email/dispatches", {
|
|
969
|
+
params: { workspaceId: this.workspace(options), recordId: options?.recordId, installationId: options?.installationId }
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
async status(id, options) {
|
|
973
|
+
return this.outcome(id, options);
|
|
974
|
+
}
|
|
975
|
+
workspace(options) {
|
|
976
|
+
const value = options?.workspaceId ?? this.workspaceId;
|
|
977
|
+
if (!value) throw new Error("A workspace is required for transactional email");
|
|
978
|
+
return value;
|
|
979
|
+
}
|
|
980
|
+
mainBranch(options) {
|
|
981
|
+
if (options?.branch !== void 0 && options.branch !== "main")
|
|
982
|
+
throw new Error("Transactional email currently supports only the main business branch");
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
// src/modules/business.ts
|
|
987
|
+
var BusinessModule = class _BusinessModule {
|
|
988
|
+
constructor(http, branch = "main") {
|
|
989
|
+
this.http = http;
|
|
990
|
+
this.branch = branch;
|
|
991
|
+
}
|
|
992
|
+
http;
|
|
993
|
+
branch;
|
|
994
|
+
withBranch(branch) {
|
|
995
|
+
return new _BusinessModule(this.http, branch);
|
|
996
|
+
}
|
|
997
|
+
async context() {
|
|
998
|
+
return this.http.request("GET", "/business/context", { headers: this.headers() });
|
|
999
|
+
}
|
|
1000
|
+
async command(command) {
|
|
1001
|
+
if (!command.idempotencyKey?.trim() || command.idempotencyKey.length > 200 || /[\u0000-\u001f\u007f-\u009f]/.test(command.idempotencyKey)) {
|
|
1002
|
+
throw new Error("A bounded printable idempotency key is required");
|
|
1003
|
+
}
|
|
1004
|
+
if (command.expectedRevision !== void 0 && !/^"[a-f0-9]{32}"$/.test(command.expectedRevision)) {
|
|
1005
|
+
throw new Error("An exact strong quoted canonical revision is required");
|
|
1006
|
+
}
|
|
1007
|
+
return this.http.request("POST", "/business/commands", {
|
|
1008
|
+
headers: this.headers(),
|
|
1009
|
+
body: JSON.stringify(command)
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
async read(id) {
|
|
1013
|
+
return this.http.request("GET", `/business/records/${encodeURIComponent(id)}`, { headers: this.headers() });
|
|
1014
|
+
}
|
|
1015
|
+
async list(kind) {
|
|
1016
|
+
return this.http.request("GET", "/business/records", {
|
|
1017
|
+
headers: this.headers(),
|
|
1018
|
+
params: kind ? { kind } : {}
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
/** null means unresolved, not success; do not invent a new operation key. */
|
|
1022
|
+
async outcome(request) {
|
|
1023
|
+
return this.http.request("POST", "/business/outcomes", {
|
|
1024
|
+
headers: this.headers(),
|
|
1025
|
+
body: JSON.stringify(request)
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
/** Recover using the exact original command, without reproducing server fingerprint encoding. */
|
|
1029
|
+
async outcomeFor(command) {
|
|
1030
|
+
return this.outcome({ operation: command.operation, idempotencyKey: command.idempotencyKey, command });
|
|
1031
|
+
}
|
|
1032
|
+
async report(report, range = {}) {
|
|
1033
|
+
return this.http.request("GET", `/business/reports/${report}`, {
|
|
1034
|
+
headers: this.headers(),
|
|
1035
|
+
params: range
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
/** Retained historical expense receipt bytes, even after the original native file is removed. */
|
|
1039
|
+
async receipt(nodeId, revision) {
|
|
1040
|
+
const response = await this.http.requestRaw("GET", `/business/receipts/${encodeURIComponent(nodeId)}/content`, {
|
|
1041
|
+
headers: this.headers(),
|
|
1042
|
+
params: { revision }
|
|
1043
|
+
});
|
|
1044
|
+
await this.http.ensureSuccess(response);
|
|
1045
|
+
return response.blob();
|
|
1046
|
+
}
|
|
1047
|
+
headers() {
|
|
1048
|
+
if (!this.branch || this.branch.length > 128 || this.branch !== this.branch.trim().toLowerCase() || /[\u0000-\u001f\u007f-\u009f]/.test(this.branch)) {
|
|
1049
|
+
throw new Error("Business operations require a canonical branch");
|
|
1050
|
+
}
|
|
1051
|
+
return { "X-Branch": this.branch, "Content-Type": "application/json" };
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
// src/transport/header-actions.ts
|
|
1056
|
+
function isHeaderAction(value) {
|
|
1057
|
+
if (!value || typeof value !== "object") return false;
|
|
1058
|
+
const a = value;
|
|
1059
|
+
return typeof a.id === "string" && /^[a-z][a-z0-9.-]{0,63}$/.test(a.id) && typeof a.label === "string" && a.label.trim().length > 0 && a.label.length <= 100 && Array.isArray(a.scopes) && a.scopes.length <= 32 && a.scopes.every((s) => typeof s === "string" && /^[a-zA-Z0-9._:-]{1,128}$/.test(s)) && (a.icon === void 0 || typeof a.icon === "string" && /^lucide:[a-z0-9-]{1,64}$/.test(a.icon)) && (a.variant === void 0 || ["default", "outline", "destructive"].includes(String(a.variant))) && ["enabled", "visible", "busy"].every((key) => a[key] === void 0 || typeof a[key] === "boolean") && (a.disabledReason === void 0 || typeof a.disabledReason === "string" && a.disabledReason.length <= 200) && (a.kind === void 0 || a.kind === "clipboard");
|
|
1060
|
+
}
|
|
1061
|
+
|
|
746
1062
|
// src/transport/bridge.transport.ts
|
|
747
1063
|
var Bridge = class {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
_hostOrigin = null;
|
|
752
|
-
_messageHandler;
|
|
753
|
-
_destroyed = false;
|
|
754
|
-
constructor() {
|
|
755
|
-
this._initPromise = new Promise((resolve) => {
|
|
1064
|
+
constructor(expectedHostOrigin) {
|
|
1065
|
+
this.expectedHostOrigin = expectedHostOrigin;
|
|
1066
|
+
this._initPromise = new Promise((resolve, reject) => {
|
|
756
1067
|
this._initResolve = resolve;
|
|
1068
|
+
this._initReject = reject;
|
|
1069
|
+
});
|
|
1070
|
+
void this._initPromise.catch(() => {
|
|
757
1071
|
});
|
|
758
1072
|
this._messageHandler = this.handleMessage.bind(this);
|
|
759
1073
|
if (typeof window !== "undefined") {
|
|
760
1074
|
window.addEventListener("message", this._messageHandler);
|
|
761
1075
|
}
|
|
762
1076
|
}
|
|
1077
|
+
expectedHostOrigin;
|
|
1078
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1079
|
+
_initResolve;
|
|
1080
|
+
_initReject;
|
|
1081
|
+
_initTimer;
|
|
1082
|
+
_initPromise;
|
|
1083
|
+
_hostOrigin = null;
|
|
1084
|
+
_messageHandler;
|
|
1085
|
+
_destroyed = false;
|
|
1086
|
+
sessionId = null;
|
|
1087
|
+
actions = /* @__PURE__ */ new Map();
|
|
1088
|
+
requests = /* @__PURE__ */ new Set();
|
|
1089
|
+
backendRequests = /* @__PURE__ */ new Map();
|
|
1090
|
+
wopiRequests = /* @__PURE__ */ new Map();
|
|
763
1091
|
/** Post `verentis:ready` to the host to start the handshake */
|
|
764
1092
|
sendReady(capabilities) {
|
|
765
1093
|
console.info("[Verentis SDK] Sending verentis:ready to host");
|
|
@@ -768,10 +1096,16 @@ var Bridge = class {
|
|
|
768
1096
|
version: 1,
|
|
769
1097
|
capabilities
|
|
770
1098
|
};
|
|
771
|
-
window.parent.postMessage(message, "*");
|
|
1099
|
+
window.parent.postMessage(message, this.expectedHostOrigin ?? "*");
|
|
772
1100
|
}
|
|
773
1101
|
/** Wait for the host to send `verentis:init` with context and token */
|
|
774
1102
|
waitForInit() {
|
|
1103
|
+
if (!this._hostOrigin && !this._destroyed && !this._initTimer) {
|
|
1104
|
+
this._initTimer = setTimeout(() => {
|
|
1105
|
+
this._initReject(new Error("Workspace handshake timed out."));
|
|
1106
|
+
this.destroy();
|
|
1107
|
+
}, 2e4);
|
|
1108
|
+
}
|
|
775
1109
|
return this._initPromise;
|
|
776
1110
|
}
|
|
777
1111
|
/** Get the host origin (available after init) */
|
|
@@ -780,6 +1114,7 @@ var Bridge = class {
|
|
|
780
1114
|
}
|
|
781
1115
|
/** Send a message to the host */
|
|
782
1116
|
postToHost(message) {
|
|
1117
|
+
if (this._destroyed) throw new Error("Bridge has been destroyed.");
|
|
783
1118
|
if (!this._hostOrigin) {
|
|
784
1119
|
throw new Error("Bridge not initialized: host origin unknown. Wait for init first.");
|
|
785
1120
|
}
|
|
@@ -814,6 +1149,138 @@ var Bridge = class {
|
|
|
814
1149
|
setDirty(isDirty) {
|
|
815
1150
|
this.postToHost({ type: "verentis:dirty", version: 1, isDirty });
|
|
816
1151
|
}
|
|
1152
|
+
/** The host, not the app, selects the installation, file, branch and permission ceiling. */
|
|
1153
|
+
requestBackendCredential() {
|
|
1154
|
+
if (this._destroyed || !this.sessionId || !this._hostOrigin)
|
|
1155
|
+
return Promise.reject(new Error("An initialized workspace host is required."));
|
|
1156
|
+
if (this.backendRequests.size >= 4)
|
|
1157
|
+
return Promise.reject(new Error("A backend credential request is already pending."));
|
|
1158
|
+
const requestId = crypto.randomUUID();
|
|
1159
|
+
return new Promise((resolve, reject) => {
|
|
1160
|
+
const timer = setTimeout(() => {
|
|
1161
|
+
this.backendRequests.delete(requestId);
|
|
1162
|
+
reject(new Error("Backend authorization timed out."));
|
|
1163
|
+
}, 2e4);
|
|
1164
|
+
this.backendRequests.set(requestId, { resolve, reject, timer });
|
|
1165
|
+
try {
|
|
1166
|
+
this.postToHost({ type: "verentis:backend:request", version: 1, requestId, sessionId: this.sessionId });
|
|
1167
|
+
} catch {
|
|
1168
|
+
clearTimeout(timer);
|
|
1169
|
+
this.backendRequests.delete(requestId);
|
|
1170
|
+
reject(new Error("The workspace host is unavailable."));
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
/** The trusted parent selects the approved installation, document and action. */
|
|
1175
|
+
requestWopiLaunch() {
|
|
1176
|
+
return this.requestWopi("launch");
|
|
1177
|
+
}
|
|
1178
|
+
/** Recover only the target selected by a completed server-owned derived operation. */
|
|
1179
|
+
requestWopiContinuation() {
|
|
1180
|
+
return this.requestWopi("continue");
|
|
1181
|
+
}
|
|
1182
|
+
getWopiStatus() {
|
|
1183
|
+
return this.requestWopi("status");
|
|
1184
|
+
}
|
|
1185
|
+
requestWopiSave(generation) {
|
|
1186
|
+
if (!Number.isSafeInteger(generation) || generation < 0)
|
|
1187
|
+
return Promise.reject(new Error("Invalid edit generation."));
|
|
1188
|
+
return this.requestWopi("save", generation);
|
|
1189
|
+
}
|
|
1190
|
+
closeWopiSession() {
|
|
1191
|
+
return this.requestWopi("close");
|
|
1192
|
+
}
|
|
1193
|
+
requestWopi(operation, generation) {
|
|
1194
|
+
if (this._destroyed || !this.sessionId || !this._hostOrigin)
|
|
1195
|
+
return Promise.reject(new Error("An initialized workspace host is required."));
|
|
1196
|
+
if (this.wopiRequests.size >= 4)
|
|
1197
|
+
return Promise.reject(new Error("Too many collaboration requests."));
|
|
1198
|
+
const requestId = crypto.randomUUID();
|
|
1199
|
+
return new Promise((resolve, reject) => {
|
|
1200
|
+
const timer = setTimeout(() => {
|
|
1201
|
+
this.wopiRequests.delete(requestId);
|
|
1202
|
+
reject(new Error("Collaboration authorization timed out."));
|
|
1203
|
+
}, 3e4);
|
|
1204
|
+
this.wopiRequests.set(requestId, { resolve, reject, timer });
|
|
1205
|
+
try {
|
|
1206
|
+
this.postToHost({
|
|
1207
|
+
type: "verentis:wopi:request",
|
|
1208
|
+
version: 1,
|
|
1209
|
+
requestId,
|
|
1210
|
+
sessionId: this.sessionId,
|
|
1211
|
+
operation,
|
|
1212
|
+
...generation === void 0 ? {} : { generation }
|
|
1213
|
+
});
|
|
1214
|
+
} catch {
|
|
1215
|
+
clearTimeout(timer);
|
|
1216
|
+
this.wopiRequests.delete(requestId);
|
|
1217
|
+
reject(new Error("The workspace host is unavailable."));
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
registerAction(descriptor, handler) {
|
|
1222
|
+
if (!this.sessionId || this._destroyed) throw new Error("Header actions require an initialized workspace host.");
|
|
1223
|
+
if (!isHeaderAction(descriptor)) throw new Error("Invalid header action.");
|
|
1224
|
+
if (this.actions.has(descriptor.id)) throw new Error(`Action '${descriptor.id}' is already registered.`);
|
|
1225
|
+
if (this.actions.size >= 16) throw new Error("At most 16 header actions may be registered.");
|
|
1226
|
+
const action = { descriptor: { ...descriptor, scopes: [...descriptor.scopes] }, handler, busy: false };
|
|
1227
|
+
this.actions.set(descriptor.id, action);
|
|
1228
|
+
this.publishActions();
|
|
1229
|
+
return {
|
|
1230
|
+
update: (next) => {
|
|
1231
|
+
if (this.actions.get(descriptor.id) !== action) throw new Error("Action has been disposed.");
|
|
1232
|
+
if (!isHeaderAction(next) || next.id !== descriptor.id) throw new Error("Invalid header action update.");
|
|
1233
|
+
action.descriptor = { ...next, scopes: [...next.scopes] };
|
|
1234
|
+
this.publishActions();
|
|
1235
|
+
},
|
|
1236
|
+
dispose: () => {
|
|
1237
|
+
if (this.actions.get(descriptor.id) !== action) return;
|
|
1238
|
+
this.actions.delete(descriptor.id);
|
|
1239
|
+
this.publishActions();
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
publishActions() {
|
|
1244
|
+
if (!this.sessionId || this._destroyed) return;
|
|
1245
|
+
this.postToHost({
|
|
1246
|
+
type: "verentis:actions:set",
|
|
1247
|
+
version: 1,
|
|
1248
|
+
sessionId: this.sessionId,
|
|
1249
|
+
actions: [...this.actions.values()].map((a) => ({ ...a.descriptor, busy: a.busy || a.descriptor.busy }))
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
async invokeAction(message) {
|
|
1253
|
+
if (message.sessionId !== this.sessionId || typeof message.requestId !== "string" || message.requestId.length > 128 || !message.requestId || this.requests.has(message.requestId)) return;
|
|
1254
|
+
this.requests.add(message.requestId);
|
|
1255
|
+
if (this.requests.size > 1e3) this.requests.delete(this.requests.values().next().value);
|
|
1256
|
+
const action = this.actions.get(message.actionId);
|
|
1257
|
+
const reply = {
|
|
1258
|
+
type: "verentis:action:result",
|
|
1259
|
+
version: 1,
|
|
1260
|
+
sessionId: message.sessionId,
|
|
1261
|
+
requestId: message.requestId,
|
|
1262
|
+
actionId: message.actionId
|
|
1263
|
+
};
|
|
1264
|
+
if (!action || action.busy || action.descriptor.busy || action.descriptor.enabled === false || action.descriptor.visible === false) {
|
|
1265
|
+
this.postToHost({ ...reply, error: "Action is unavailable." });
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
action.busy = true;
|
|
1269
|
+
this.publishActions();
|
|
1270
|
+
try {
|
|
1271
|
+
const result = await action.handler();
|
|
1272
|
+
if (!this._destroyed && this.sessionId === message.sessionId) {
|
|
1273
|
+
this.postToHost({ ...reply, result: result || void 0 });
|
|
1274
|
+
}
|
|
1275
|
+
} catch (error) {
|
|
1276
|
+
if (!this._destroyed && this.sessionId === message.sessionId) {
|
|
1277
|
+
this.postToHost({ ...reply, error: (error instanceof Error ? error.message : "Action failed.").slice(0, 500) });
|
|
1278
|
+
}
|
|
1279
|
+
} finally {
|
|
1280
|
+
action.busy = false;
|
|
1281
|
+
this.publishActions();
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
817
1284
|
/** Subscribe to a specific message type from the host */
|
|
818
1285
|
on(type, listener) {
|
|
819
1286
|
if (!this.listeners.has(type)) {
|
|
@@ -827,7 +1294,22 @@ var Bridge = class {
|
|
|
827
1294
|
/** Clean up event listeners */
|
|
828
1295
|
destroy() {
|
|
829
1296
|
this._destroyed = true;
|
|
1297
|
+
clearTimeout(this._initTimer);
|
|
1298
|
+
this._initTimer = void 0;
|
|
1299
|
+
if (!this._hostOrigin) this._initReject(new Error("Bridge has been destroyed."));
|
|
1300
|
+
this.actions.clear();
|
|
1301
|
+
this.requests.clear();
|
|
830
1302
|
this.listeners.clear();
|
|
1303
|
+
for (const pending of this.backendRequests.values()) {
|
|
1304
|
+
clearTimeout(pending.timer);
|
|
1305
|
+
pending.reject(new Error("Bridge has been destroyed."));
|
|
1306
|
+
}
|
|
1307
|
+
this.backendRequests.clear();
|
|
1308
|
+
for (const pending of this.wopiRequests.values()) {
|
|
1309
|
+
clearTimeout(pending.timer);
|
|
1310
|
+
pending.reject(new Error("Bridge has been destroyed."));
|
|
1311
|
+
}
|
|
1312
|
+
this.wopiRequests.clear();
|
|
831
1313
|
if (typeof window !== "undefined") {
|
|
832
1314
|
window.removeEventListener("message", this._messageHandler);
|
|
833
1315
|
}
|
|
@@ -835,9 +1317,16 @@ var Bridge = class {
|
|
|
835
1317
|
handleMessage(event) {
|
|
836
1318
|
if (this._destroyed) return;
|
|
837
1319
|
const data = event.data;
|
|
838
|
-
if (
|
|
1320
|
+
if (event.source !== window.parent || data?.version !== 1 || typeof data?.type !== "string" || !data.type.startsWith("verentis:")) return;
|
|
1321
|
+
if (this._hostOrigin && event.origin !== this._hostOrigin) return;
|
|
1322
|
+
if (this.expectedHostOrigin && event.origin !== this.expectedHostOrigin) return;
|
|
839
1323
|
if (data.type === "verentis:init") {
|
|
1324
|
+
if (this._hostOrigin) return;
|
|
1325
|
+
if (!data.context?.workspace?.id || !data.token || event.origin === "null") return;
|
|
1326
|
+
clearTimeout(this._initTimer);
|
|
1327
|
+
this._initTimer = void 0;
|
|
840
1328
|
this._hostOrigin = event.origin;
|
|
1329
|
+
this.sessionId = typeof data.sessionId === "string" ? data.sessionId : null;
|
|
841
1330
|
console.info("[Verentis SDK] Received verentis:init from host", {
|
|
842
1331
|
origin: event.origin,
|
|
843
1332
|
workspaceId: data.context.workspace.id,
|
|
@@ -846,6 +1335,33 @@ var Bridge = class {
|
|
|
846
1335
|
const initData = data;
|
|
847
1336
|
this._initResolve({ context: initData.context, token: initData.token });
|
|
848
1337
|
}
|
|
1338
|
+
if (data.type === "verentis:backend:response") {
|
|
1339
|
+
if (!this._hostOrigin || data.sessionId !== this.sessionId) return;
|
|
1340
|
+
const pending = this.backendRequests.get(data.requestId);
|
|
1341
|
+
if (!pending) return;
|
|
1342
|
+
clearTimeout(pending.timer);
|
|
1343
|
+
this.backendRequests.delete(data.requestId);
|
|
1344
|
+
const value = data.credential;
|
|
1345
|
+
if (data.error || !value || typeof value.launchCredential !== "string" || value.launchCredential.length > 512 || !value.launchCredential || typeof value.delegationId !== "string" || typeof value.backendClientId !== "string" || !Number.isFinite(Date.parse(value.expiresAt)) || Date.parse(value.expiresAt) <= Date.now())
|
|
1346
|
+
pending.reject(new Error("Backend authorization was denied or is not configured."));
|
|
1347
|
+
else pending.resolve(value);
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
if (data.type === "verentis:wopi:response") {
|
|
1351
|
+
if (!this._hostOrigin || data.sessionId !== this.sessionId) return;
|
|
1352
|
+
const pending = this.wopiRequests.get(data.requestId);
|
|
1353
|
+
if (!pending) return;
|
|
1354
|
+
clearTimeout(pending.timer);
|
|
1355
|
+
this.wopiRequests.delete(data.requestId);
|
|
1356
|
+
if (data.error || !Object.hasOwn(data, "result"))
|
|
1357
|
+
pending.reject(new Error("Collaboration authorization is unavailable."));
|
|
1358
|
+
else pending.resolve(data.result);
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (data.type === "verentis:action:invoke") {
|
|
1362
|
+
void this.invokeAction(data);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
849
1365
|
const typeListeners = this.listeners.get(data.type);
|
|
850
1366
|
if (typeListeners) {
|
|
851
1367
|
for (const listener of typeListeners) {
|
|
@@ -857,16 +1373,18 @@ var Bridge = class {
|
|
|
857
1373
|
|
|
858
1374
|
// src/types.ts
|
|
859
1375
|
var ApiError = class extends Error {
|
|
860
|
-
constructor(status, detail, title) {
|
|
1376
|
+
constructor(status, detail, title, code) {
|
|
861
1377
|
super(title ?? `API error ${status}: ${detail}`);
|
|
862
1378
|
this.status = status;
|
|
863
1379
|
this.detail = detail;
|
|
864
1380
|
this.title = title;
|
|
1381
|
+
this.code = code;
|
|
865
1382
|
this.name = "ApiError";
|
|
866
1383
|
}
|
|
867
1384
|
status;
|
|
868
1385
|
detail;
|
|
869
1386
|
title;
|
|
1387
|
+
code;
|
|
870
1388
|
};
|
|
871
1389
|
|
|
872
1390
|
// src/transport/http.transport.ts
|
|
@@ -895,24 +1413,7 @@ var HttpTransport = class {
|
|
|
895
1413
|
headers,
|
|
896
1414
|
body: options?.body
|
|
897
1415
|
});
|
|
898
|
-
|
|
899
|
-
let detail = "";
|
|
900
|
-
let title;
|
|
901
|
-
try {
|
|
902
|
-
const body = await response.json();
|
|
903
|
-
detail = body.detail ?? body.message ?? JSON.stringify(body);
|
|
904
|
-
title = body.title;
|
|
905
|
-
} catch {
|
|
906
|
-
detail = await response.text().catch(() => response.statusText);
|
|
907
|
-
}
|
|
908
|
-
console.error("[Verentis SDK] Request failed", {
|
|
909
|
-
method,
|
|
910
|
-
path,
|
|
911
|
-
status: response.status,
|
|
912
|
-
detail
|
|
913
|
-
});
|
|
914
|
-
throw new ApiError(response.status, detail, title);
|
|
915
|
-
}
|
|
1416
|
+
await this.ensureSuccess(response);
|
|
916
1417
|
console.info("[Verentis SDK] Request succeeded", {
|
|
917
1418
|
method,
|
|
918
1419
|
path,
|
|
@@ -946,6 +1447,26 @@ var HttpTransport = class {
|
|
|
946
1447
|
});
|
|
947
1448
|
return response;
|
|
948
1449
|
}
|
|
1450
|
+
async ensureSuccess(response) {
|
|
1451
|
+
if (response.ok) return;
|
|
1452
|
+
const raw = await response.text();
|
|
1453
|
+
let detail = raw || response.statusText;
|
|
1454
|
+
let title;
|
|
1455
|
+
let code;
|
|
1456
|
+
try {
|
|
1457
|
+
const body = JSON.parse(raw);
|
|
1458
|
+
if (body !== null && typeof body === "object") {
|
|
1459
|
+
if ("detail" in body && typeof body.detail === "string") detail = body.detail;
|
|
1460
|
+
else if ("message" in body && typeof body.message === "string") detail = body.message;
|
|
1461
|
+
if ("title" in body && typeof body.title === "string") title = body.title;
|
|
1462
|
+
if ("code" in body && typeof body.code === "string") code = body.code;
|
|
1463
|
+
}
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
1466
|
+
}
|
|
1467
|
+
console.error("[Verentis SDK] Request failed", { status: response.status, code });
|
|
1468
|
+
throw new ApiError(response.status, detail, title, code);
|
|
1469
|
+
}
|
|
949
1470
|
buildUrl(path, params) {
|
|
950
1471
|
const base = `${this.baseUrl}/${this.apiVersion}${path}`;
|
|
951
1472
|
if (!params) return base;
|
|
@@ -975,6 +1496,8 @@ var VerentisClient = class {
|
|
|
975
1496
|
installations;
|
|
976
1497
|
resources;
|
|
977
1498
|
settings;
|
|
1499
|
+
email;
|
|
1500
|
+
business;
|
|
978
1501
|
context;
|
|
979
1502
|
bridge;
|
|
980
1503
|
_auth;
|
|
@@ -1006,6 +1529,8 @@ var VerentisClient = class {
|
|
|
1006
1529
|
this.installations = new InstallationsModule(this._http, options?.workspaceId);
|
|
1007
1530
|
this.resources = new ResourcesModule(this._http, options?.workspaceId);
|
|
1008
1531
|
this.settings = new SettingsModule(this._http, options?.workspaceId);
|
|
1532
|
+
this.email = new EmailModule(this._http, options?.workspaceId);
|
|
1533
|
+
this.business = new BusinessModule(this._http);
|
|
1009
1534
|
this._ready = Promise.resolve();
|
|
1010
1535
|
return;
|
|
1011
1536
|
}
|
|
@@ -1027,7 +1552,7 @@ var VerentisClient = class {
|
|
|
1027
1552
|
this.bridge.sendReady();
|
|
1028
1553
|
const { context, token } = await this.bridge.waitForInit();
|
|
1029
1554
|
const hostOrigin = this.bridge.hostOrigin;
|
|
1030
|
-
|
|
1555
|
+
bridgeAuth.setHostOrigin(hostOrigin);
|
|
1031
1556
|
bridgeAuth.setToken(token);
|
|
1032
1557
|
this.context.setFromAppContext(context);
|
|
1033
1558
|
const http = new HttpTransport(
|
|
@@ -1042,6 +1567,8 @@ var VerentisClient = class {
|
|
|
1042
1567
|
this.installations = new InstallationsModule(http, context.workspace.id);
|
|
1043
1568
|
this.resources = new ResourcesModule(http, context.workspace.id);
|
|
1044
1569
|
this.settings = new SettingsModule(http, context.workspace.id);
|
|
1570
|
+
this.email = new EmailModule(http, context.workspace.id);
|
|
1571
|
+
this.business = new BusinessModule(http);
|
|
1045
1572
|
}
|
|
1046
1573
|
};
|
|
1047
1574
|
function detectEnvironment() {
|
|
@@ -1099,6 +1626,6 @@ function createVerentisClient(options) {
|
|
|
1099
1626
|
return new VerentisClient(options);
|
|
1100
1627
|
}
|
|
1101
1628
|
|
|
1102
|
-
export { ApiKeyAuth, Bridge, BridgeAuth, ContextModule, EnginesModule, ExecutionsModule, FilesModule, HttpTransport, InstallationsModule, ResourcesModule, SettingsModule, TokenAuth, VerentisClient, createVerentisClient, findBestMatch, isTerminalStatus, matchMimeType };
|
|
1629
|
+
export { ApiError, ApiKeyAuth, Bridge, BridgeAuth, BusinessModule, ContextModule, EmailModule, EnginesModule, ExecutionsModule, FilesModule, HttpTransport, InstallationsModule, ResourcesModule, SettingsModule, TokenAuth, VerentisClient, createVerentisClient, findBestMatch, isHeaderAction, isTerminalStatus, matchMimeType };
|
|
1103
1630
|
//# sourceMappingURL=index.js.map
|
|
1104
1631
|
//# sourceMappingURL=index.js.map
|