@aletheia-dev/api-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/LICENSE +202 -0
- package/README.md +22 -0
- package/dist/index.cjs +948 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2215 -0
- package/dist/index.d.ts +2215 -0
- package/dist/index.js +1065 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,948 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
ActorType: () => import_core9.ActorType,
|
|
24
|
+
AddListEntriesInput: () => import_core13.AddListEntriesInput,
|
|
25
|
+
AggregationPolicy: () => import_core13.AggregationPolicy,
|
|
26
|
+
ApiError: () => ApiError,
|
|
27
|
+
ApprovalCommentInput: () => import_core9.ApprovalCommentInput,
|
|
28
|
+
ApprovalDecision: () => import_core9.ApprovalDecision,
|
|
29
|
+
ApprovalOutcome: () => ApprovalOutcome,
|
|
30
|
+
AssignCaseInput: () => import_core11.AssignCaseInput,
|
|
31
|
+
AuditEvent: () => import_core9.AuditEvent,
|
|
32
|
+
AuditExportFormat: () => import_core9.AuditExportFormat,
|
|
33
|
+
AuditFilter: () => import_core9.AuditFilter,
|
|
34
|
+
Backtest: () => import_core13.Backtest,
|
|
35
|
+
BacktestProgress: () => import_core13.BacktestProgress,
|
|
36
|
+
BacktestSample: () => import_core13.BacktestSample,
|
|
37
|
+
BacktestSampleFailure: () => import_core13.BacktestSampleFailure,
|
|
38
|
+
BacktestStatus: () => import_core13.BacktestStatus,
|
|
39
|
+
BacktestSummary: () => import_core13.BacktestSummary,
|
|
40
|
+
Case: () => import_core11.Case,
|
|
41
|
+
CaseDetail: () => CaseDetail,
|
|
42
|
+
CaseFilter: () => import_core11.CaseFilter,
|
|
43
|
+
CaseNote: () => import_core11.CaseNote,
|
|
44
|
+
CaseNoteInput: () => import_core11.CaseNoteInput,
|
|
45
|
+
CasePriority: () => import_core11.CasePriority,
|
|
46
|
+
CaseQueue: () => import_core11.CaseQueue,
|
|
47
|
+
CaseQueueCount: () => CaseQueueCount,
|
|
48
|
+
CaseSlaState: () => import_core11.CaseSlaState,
|
|
49
|
+
CaseSort: () => import_core11.CaseSort,
|
|
50
|
+
CaseStatus: () => import_core11.CaseStatus,
|
|
51
|
+
CaseView: () => import_core11.CaseView,
|
|
52
|
+
CloseCaseInput: () => import_core11.CloseCaseInput,
|
|
53
|
+
Condition: () => import_core10.Condition,
|
|
54
|
+
ConditionOp: () => import_core10.ConditionOp,
|
|
55
|
+
CreateDocumentInput: () => import_core12.CreateDocumentInput,
|
|
56
|
+
CreatedSubmission: () => CreatedSubmission,
|
|
57
|
+
DEFINITION_PATHS: () => import_core9.DEFINITION_PATHS,
|
|
58
|
+
DOCUMENT_CONTENT_TYPES: () => import_core12.DOCUMENT_CONTENT_TYPES,
|
|
59
|
+
DOCUMENT_MAX_BYTES: () => import_core12.DOCUMENT_MAX_BYTES,
|
|
60
|
+
DOCUMENT_OPEN_STATUSES: () => import_core12.DOCUMENT_OPEN_STATUSES,
|
|
61
|
+
DecideCaseResult: () => DecideCaseResult,
|
|
62
|
+
DefinitionApproval: () => import_core9.DefinitionApproval,
|
|
63
|
+
DefinitionDiff: () => import_core9.DefinitionDiff,
|
|
64
|
+
DefinitionIssue: () => import_core10.DefinitionIssue,
|
|
65
|
+
DefinitionKind: () => import_core9.DefinitionKind,
|
|
66
|
+
DefinitionVersionSummary: () => import_core9.DefinitionVersionSummary,
|
|
67
|
+
DiffChange: () => import_core9.DiffChange,
|
|
68
|
+
DiffOp: () => import_core9.DiffOp,
|
|
69
|
+
DirectoryUser: () => import_core11.DirectoryUser,
|
|
70
|
+
Document: () => import_core12.Document,
|
|
71
|
+
DocumentContentType: () => import_core12.DocumentContentType,
|
|
72
|
+
DocumentDownload: () => import_core12.DocumentDownload,
|
|
73
|
+
DocumentPollTimeoutError: () => DocumentPollTimeoutError,
|
|
74
|
+
DocumentScan: () => import_core12.DocumentScan,
|
|
75
|
+
DocumentStatus: () => import_core12.DocumentStatus,
|
|
76
|
+
DocumentUploadTicket: () => import_core12.DocumentUploadTicket,
|
|
77
|
+
DryRunResult: () => DryRunResult,
|
|
78
|
+
Event: () => import_core13.Event,
|
|
79
|
+
EventKey: () => import_core13.EventKey,
|
|
80
|
+
FORBIDDEN_CODES: () => FORBIDDEN_CODES,
|
|
81
|
+
FieldTypeDescription: () => import_core10.FieldTypeDescription,
|
|
82
|
+
FileFieldValue: () => import_core12.FileFieldValue,
|
|
83
|
+
FormUiHints: () => import_core10.FormUiHints,
|
|
84
|
+
HealthStatus: () => HealthStatus,
|
|
85
|
+
IngestEventsInput: () => import_core13.IngestEventsInput,
|
|
86
|
+
IngestEventsResult: () => import_core13.IngestEventsResult,
|
|
87
|
+
IssueSeverity: () => import_core10.IssueSeverity,
|
|
88
|
+
List: () => import_core13.List,
|
|
89
|
+
ListEntry: () => import_core13.ListEntry,
|
|
90
|
+
ListImportResult: () => import_core13.ListImportResult,
|
|
91
|
+
ListKind: () => import_core13.ListKind,
|
|
92
|
+
Me: () => Me,
|
|
93
|
+
MePrincipal: () => MePrincipal,
|
|
94
|
+
NewEvent: () => import_core13.NewEvent,
|
|
95
|
+
NewListEntry: () => import_core13.NewListEntry,
|
|
96
|
+
PluginSummary: () => PluginSummary,
|
|
97
|
+
RUNTIME_CONFIG_PATH: () => RUNTIME_CONFIG_PATH,
|
|
98
|
+
ReadyStatus: () => ReadyStatus,
|
|
99
|
+
RemoveListEntriesInput: () => import_core13.RemoveListEntriesInput,
|
|
100
|
+
RemovedCount: () => RemovedCount,
|
|
101
|
+
RuleSetBody: () => import_core13.RuleSetBody,
|
|
102
|
+
RuleSetDefinition: () => import_core13.RuleSetDefinition,
|
|
103
|
+
RuleSetRule: () => import_core13.RuleSetRule,
|
|
104
|
+
RuleSetUseCase: () => import_core13.RuleSetUseCase,
|
|
105
|
+
RuleTypeDescription: () => RuleTypeDescription,
|
|
106
|
+
RuleUiHints: () => RuleUiHints,
|
|
107
|
+
RuntimeConfig: () => RuntimeConfig,
|
|
108
|
+
ScoreBand: () => import_core13.ScoreBand,
|
|
109
|
+
ScoreClamp: () => import_core13.ScoreClamp,
|
|
110
|
+
SortOrder: () => import_core11.SortOrder,
|
|
111
|
+
StartBacktestInput: () => import_core13.StartBacktestInput,
|
|
112
|
+
StepTypeDescription: () => import_core10.StepTypeDescription,
|
|
113
|
+
Subject: () => import_core15.Subject,
|
|
114
|
+
SubjectKind: () => import_core15.SubjectKind,
|
|
115
|
+
SubjectListQuery: () => import_core15.SubjectListQuery,
|
|
116
|
+
SubjectStatus: () => import_core15.SubjectStatus,
|
|
117
|
+
SubmissionDetail: () => SubmissionDetail,
|
|
118
|
+
SubmissionEmbed: () => SubmissionEmbed,
|
|
119
|
+
SubmissionStatus: () => SubmissionStatus,
|
|
120
|
+
TenantSettings: () => import_core14.TenantSettings,
|
|
121
|
+
TimelineEntry: () => import_core15.TimelineEntry,
|
|
122
|
+
TimelineKind: () => import_core15.TimelineKind,
|
|
123
|
+
TimelineQuery: () => import_core15.TimelineQuery,
|
|
124
|
+
UploadError: () => UploadError,
|
|
125
|
+
UpsertCaseQueueInput: () => import_core11.UpsertCaseQueueInput,
|
|
126
|
+
UpsertListInput: () => import_core13.UpsertListInput,
|
|
127
|
+
UpsertRuleSetInput: () => import_core13.UpsertRuleSetInput,
|
|
128
|
+
ValidationReport: () => import_core10.ValidationReport,
|
|
129
|
+
WebOrigin: () => import_core14.WebOrigin,
|
|
130
|
+
auditFilterParams: () => auditFilterParams,
|
|
131
|
+
bandFor: () => import_core13.bandFor,
|
|
132
|
+
caseListParams: () => caseListParams,
|
|
133
|
+
caseSlaState: () => import_core11.caseSlaState,
|
|
134
|
+
checkFileBeforeUpload: () => checkFileBeforeUpload,
|
|
135
|
+
createApiClient: () => createApiClient,
|
|
136
|
+
isApiError: () => isApiError,
|
|
137
|
+
isApiErrorBody: () => isApiErrorBody,
|
|
138
|
+
isForbidden: () => isForbidden,
|
|
139
|
+
isTenantNotProvisioned: () => isTenantNotProvisioned,
|
|
140
|
+
isTerminalDocumentStatus: () => isTerminalDocumentStatus,
|
|
141
|
+
isUnauthenticated: () => isUnauthenticated,
|
|
142
|
+
loadRuntimeConfig: () => loadRuntimeConfig,
|
|
143
|
+
normalizeListValue: () => import_core13.normalizeListValue,
|
|
144
|
+
pollDocument: () => pollDocument,
|
|
145
|
+
resolveConfig: () => resolveConfig,
|
|
146
|
+
uploadToStorage: () => uploadToStorage,
|
|
147
|
+
verifyExport: () => verifyExport
|
|
148
|
+
});
|
|
149
|
+
module.exports = __toCommonJS(src_exports);
|
|
150
|
+
|
|
151
|
+
// src/errors.ts
|
|
152
|
+
var ApiError = class _ApiError extends Error {
|
|
153
|
+
constructor(message, status, code, details) {
|
|
154
|
+
super(message);
|
|
155
|
+
this.status = status;
|
|
156
|
+
this.code = code;
|
|
157
|
+
this.details = details;
|
|
158
|
+
this.name = "ApiError";
|
|
159
|
+
}
|
|
160
|
+
status;
|
|
161
|
+
code;
|
|
162
|
+
details;
|
|
163
|
+
/** Builds an ApiError from a response status and its (possibly non-JSON) body. */
|
|
164
|
+
static fromResponse(status, statusText, body) {
|
|
165
|
+
if (isApiErrorBody(body)) {
|
|
166
|
+
return new _ApiError(body.error.message, status, body.error.code, body.error.details);
|
|
167
|
+
}
|
|
168
|
+
const message = statusText ? `HTTP ${status} ${statusText}` : `HTTP ${status}`;
|
|
169
|
+
return new _ApiError(message, status, "http_error", body);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
function isApiErrorBody(value) {
|
|
173
|
+
if (typeof value !== "object" || value === null) return false;
|
|
174
|
+
const error = value.error;
|
|
175
|
+
if (typeof error !== "object" || error === null) return false;
|
|
176
|
+
const { code, message } = error;
|
|
177
|
+
return typeof code === "string" && typeof message === "string";
|
|
178
|
+
}
|
|
179
|
+
function isApiError(value) {
|
|
180
|
+
return value instanceof ApiError;
|
|
181
|
+
}
|
|
182
|
+
function isUnauthenticated(value) {
|
|
183
|
+
return isApiError(value) && value.code === "unauthenticated";
|
|
184
|
+
}
|
|
185
|
+
var FORBIDDEN_CODES = ["forbidden", "tenant_not_provisioned"];
|
|
186
|
+
function isForbidden(value) {
|
|
187
|
+
return isApiError(value) && FORBIDDEN_CODES.includes(value.code);
|
|
188
|
+
}
|
|
189
|
+
function isTenantNotProvisioned(value) {
|
|
190
|
+
return isApiError(value) && value.code === "tenant_not_provisioned";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/audit.ts
|
|
194
|
+
var import_core = require("@aletheia-dev/core");
|
|
195
|
+
var import_zod = require("zod");
|
|
196
|
+
|
|
197
|
+
// src/http.ts
|
|
198
|
+
function buildUrl(baseUrl, path, query) {
|
|
199
|
+
const url = `${baseUrl}${path}`;
|
|
200
|
+
if (!query) return url;
|
|
201
|
+
const params = new URLSearchParams();
|
|
202
|
+
for (const [key, value] of Object.entries(query)) {
|
|
203
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
204
|
+
if (typeof value === "object") {
|
|
205
|
+
for (const item of value) params.append(key, item);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
params.set(key, String(value));
|
|
209
|
+
}
|
|
210
|
+
const qs = params.toString();
|
|
211
|
+
return qs ? `${url}?${qs}` : url;
|
|
212
|
+
}
|
|
213
|
+
async function readBody(response) {
|
|
214
|
+
const text = await response.text();
|
|
215
|
+
if (!text) return void 0;
|
|
216
|
+
try {
|
|
217
|
+
return JSON.parse(text);
|
|
218
|
+
} catch {
|
|
219
|
+
return text;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
var Http = class {
|
|
223
|
+
constructor(options) {
|
|
224
|
+
this.options = options;
|
|
225
|
+
}
|
|
226
|
+
options;
|
|
227
|
+
async request(path, options = {}) {
|
|
228
|
+
const { baseUrl, getAccessToken, fetch: fetch2 } = this.options;
|
|
229
|
+
const method = options.method ?? "GET";
|
|
230
|
+
const headers = { accept: "application/json" };
|
|
231
|
+
const token = await getAccessToken();
|
|
232
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
233
|
+
const init = { method, headers };
|
|
234
|
+
if (options.raw !== void 0) {
|
|
235
|
+
headers["content-type"] = options.raw.contentType;
|
|
236
|
+
init.body = options.raw.content;
|
|
237
|
+
} else if (options.body !== void 0) {
|
|
238
|
+
headers["content-type"] = "application/json";
|
|
239
|
+
init.body = JSON.stringify(options.body);
|
|
240
|
+
}
|
|
241
|
+
const response = await fetch2(buildUrl(baseUrl, path, options.query), init);
|
|
242
|
+
const body = await readBody(response);
|
|
243
|
+
if (!response.ok) {
|
|
244
|
+
throw ApiError.fromResponse(response.status, response.statusText, body);
|
|
245
|
+
}
|
|
246
|
+
return body;
|
|
247
|
+
}
|
|
248
|
+
/** Requests and parses the body with `schema` (dates are coerced by the core schemas). */
|
|
249
|
+
async parsed(schema, path, options) {
|
|
250
|
+
const body = await this.request(path, options);
|
|
251
|
+
return schema.parse(body);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
function encodeSegment(value) {
|
|
255
|
+
return encodeURIComponent(value);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/audit.ts
|
|
259
|
+
var AuditEventList = import_zod.z.object({ items: import_zod.z.array(import_core.AuditEvent) });
|
|
260
|
+
function isoOf(value) {
|
|
261
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
262
|
+
}
|
|
263
|
+
function auditFilterParams(filter = {}) {
|
|
264
|
+
return {
|
|
265
|
+
action: filter.action,
|
|
266
|
+
actorId: filter.actorId,
|
|
267
|
+
actorType: filter.actorType,
|
|
268
|
+
resourceType: filter.resourceType,
|
|
269
|
+
resourceId: filter.resourceId,
|
|
270
|
+
from: isoOf(filter.from),
|
|
271
|
+
to: isoOf(filter.to)
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function auditDomain(http, transport) {
|
|
275
|
+
const exportUrl = (format, filter) => buildUrl(transport.baseUrl, "/audit-events/export", {
|
|
276
|
+
format,
|
|
277
|
+
...auditFilterParams(filter)
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
list: async (query = {}) => {
|
|
281
|
+
const { limit, offset, ...filter } = query;
|
|
282
|
+
const body = await http.parsed(AuditEventList, "/audit-events", {
|
|
283
|
+
query: { ...auditFilterParams(filter), limit, offset }
|
|
284
|
+
});
|
|
285
|
+
return body.items;
|
|
286
|
+
},
|
|
287
|
+
exportUrl,
|
|
288
|
+
export: async (format, filter) => {
|
|
289
|
+
const headers = { accept: "*/*" };
|
|
290
|
+
const token = await transport.getAccessToken();
|
|
291
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
292
|
+
const response = await transport.fetch(exportUrl(format, filter), {
|
|
293
|
+
method: "GET",
|
|
294
|
+
headers
|
|
295
|
+
});
|
|
296
|
+
if (!response.ok) {
|
|
297
|
+
const text = await response.text();
|
|
298
|
+
let body = text || void 0;
|
|
299
|
+
try {
|
|
300
|
+
body = text ? JSON.parse(text) : void 0;
|
|
301
|
+
} catch {
|
|
302
|
+
}
|
|
303
|
+
throw ApiError.fromResponse(response.status, response.statusText, body);
|
|
304
|
+
}
|
|
305
|
+
return response.blob();
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
var CSV_MANIFEST = /^#\s*sha256=([0-9a-fA-F]+)\s+rows=(\d+)\s*$/;
|
|
310
|
+
var JsonlManifest = import_zod.z.object({
|
|
311
|
+
_manifest: import_zod.z.object({ sha256: import_zod.z.string(), rows: import_zod.z.coerce.number().int().nonnegative() })
|
|
312
|
+
});
|
|
313
|
+
function parseManifest(line, format) {
|
|
314
|
+
const trimmed = line.replace(/\r$/, "");
|
|
315
|
+
if (format === "csv") {
|
|
316
|
+
const match = CSV_MANIFEST.exec(trimmed);
|
|
317
|
+
return match ? { sha256: match[1].toLowerCase(), rows: Number(match[2]) } : void 0;
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
const parsed = JsonlManifest.safeParse(JSON.parse(trimmed));
|
|
321
|
+
if (!parsed.success) return void 0;
|
|
322
|
+
return { sha256: parsed.data._manifest.sha256.toLowerCase(), rows: parsed.data._manifest.rows };
|
|
323
|
+
} catch {
|
|
324
|
+
return void 0;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
async function sha256Hex(text) {
|
|
328
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
|
|
329
|
+
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
|
|
330
|
+
}
|
|
331
|
+
async function verifyExport(text, format) {
|
|
332
|
+
const content = text.endsWith("\n") ? text.slice(0, -1) : text;
|
|
333
|
+
const cut = content.lastIndexOf("\n");
|
|
334
|
+
const body = cut === -1 ? "" : content.slice(0, cut + 1);
|
|
335
|
+
const manifest = parseManifest(content.slice(cut + 1), format);
|
|
336
|
+
if (!manifest) {
|
|
337
|
+
return { ok: false, rows: 0, actual: await sha256Hex(text) };
|
|
338
|
+
}
|
|
339
|
+
const actual = await sha256Hex(body);
|
|
340
|
+
return { ok: actual === manifest.sha256, rows: manifest.rows, expected: manifest.sha256, actual };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/governance.ts
|
|
344
|
+
var import_core2 = require("@aletheia-dev/core");
|
|
345
|
+
var import_zod2 = require("zod");
|
|
346
|
+
var itemsOf = (item) => import_zod2.z.union([import_zod2.z.object({ items: import_zod2.z.array(item) }).transform((body) => body.items), import_zod2.z.array(item)]);
|
|
347
|
+
var ApprovalOutcome = import_zod2.z.object({
|
|
348
|
+
approval: import_core2.DefinitionApproval,
|
|
349
|
+
definition: import_zod2.z.unknown()
|
|
350
|
+
});
|
|
351
|
+
function definitionPath(kind, key) {
|
|
352
|
+
return `${import_core2.DEFINITION_PATHS[kind]}/${encodeSegment(key)}`;
|
|
353
|
+
}
|
|
354
|
+
function versionPath(kind, key, version) {
|
|
355
|
+
return `${definitionPath(kind, key)}/versions/${encodeSegment(String(version))}`;
|
|
356
|
+
}
|
|
357
|
+
function governanceDomain(http) {
|
|
358
|
+
return {
|
|
359
|
+
versions: (kind, key) => http.parsed(itemsOf(import_core2.DefinitionVersionSummary), `${definitionPath(kind, key)}/versions`),
|
|
360
|
+
getVersion: (kind, key, version) => http.request(versionPath(kind, key, version)),
|
|
361
|
+
diff: (kind, key, query = {}) => http.parsed(import_core2.DefinitionDiff, `${definitionPath(kind, key)}/diff`, {
|
|
362
|
+
query: { from: query.from, to: query.to }
|
|
363
|
+
}),
|
|
364
|
+
requestApproval: (kind, key, version, body = {}) => http.parsed(import_core2.DefinitionApproval, `${versionPath(kind, key, version)}/request-approval`, {
|
|
365
|
+
method: "POST",
|
|
366
|
+
body
|
|
367
|
+
}),
|
|
368
|
+
approve: (kind, key, version, body = {}) => http.parsed(ApprovalOutcome, `${versionPath(kind, key, version)}/approve`, {
|
|
369
|
+
method: "POST",
|
|
370
|
+
body
|
|
371
|
+
}),
|
|
372
|
+
reject: (kind, key, version, body = {}) => http.parsed(ApprovalOutcome, `${versionPath(kind, key, version)}/reject`, {
|
|
373
|
+
method: "POST",
|
|
374
|
+
body
|
|
375
|
+
}),
|
|
376
|
+
approvals: {
|
|
377
|
+
listOpen: (query = {}) => http.parsed(itemsOf(import_core2.DefinitionApproval), "/approvals", { query: { kind: query.kind } })
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/index.ts
|
|
383
|
+
var import_core9 = require("@aletheia-dev/core");
|
|
384
|
+
var import_core10 = require("@aletheia-dev/core");
|
|
385
|
+
|
|
386
|
+
// src/cases.ts
|
|
387
|
+
var import_core3 = require("@aletheia-dev/core");
|
|
388
|
+
var import_zod3 = require("zod");
|
|
389
|
+
var CaseDetail = import_zod3.z.object({
|
|
390
|
+
case: import_core3.CaseView,
|
|
391
|
+
subject: import_core3.Subject,
|
|
392
|
+
run: import_core3.WorkflowRun.nullable(),
|
|
393
|
+
decisions: import_zod3.z.array(import_core3.Decision)
|
|
394
|
+
});
|
|
395
|
+
var DecideCaseResult = import_zod3.z.object({ case: import_core3.Case, decision: import_core3.Decision });
|
|
396
|
+
var CaseQueueCount = import_zod3.z.object({
|
|
397
|
+
queueId: import_zod3.z.string(),
|
|
398
|
+
count: import_zod3.z.number().int().nonnegative()
|
|
399
|
+
});
|
|
400
|
+
var listOf = (item) => import_zod3.z.object({ items: import_zod3.z.array(item) });
|
|
401
|
+
function arrayOf(value) {
|
|
402
|
+
if (value === void 0) return void 0;
|
|
403
|
+
return Array.isArray(value) ? value : [value];
|
|
404
|
+
}
|
|
405
|
+
function isoOf2(value) {
|
|
406
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
407
|
+
}
|
|
408
|
+
function caseListParams(query) {
|
|
409
|
+
return {
|
|
410
|
+
status: arrayOf(query.status),
|
|
411
|
+
priority: arrayOf(query.priority),
|
|
412
|
+
assignee: query.assignee,
|
|
413
|
+
type: query.type,
|
|
414
|
+
subjectId: query.subjectId,
|
|
415
|
+
slaState: arrayOf(query.slaState),
|
|
416
|
+
dueBefore: isoOf2(query.dueBefore),
|
|
417
|
+
search: query.search,
|
|
418
|
+
sort: query.sort,
|
|
419
|
+
order: query.order,
|
|
420
|
+
limit: query.limit,
|
|
421
|
+
offset: query.offset
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
function casesDomain(http) {
|
|
425
|
+
const casePath = (id, suffix = "") => `/cases/${encodeSegment(id)}${suffix}`;
|
|
426
|
+
const notePath = (id, noteId) => casePath(id, `/notes/${encodeSegment(noteId)}`);
|
|
427
|
+
const post = (path, body) => http.parsed(import_core3.CaseView, path, body === void 0 ? { method: "POST" } : { method: "POST", body });
|
|
428
|
+
return {
|
|
429
|
+
/** Cases matching `query`, in the requested order (`createdAt` desc by default). */
|
|
430
|
+
list: async (query = {}) => (await http.parsed(listOf(import_core3.CaseView), "/cases", { query: caseListParams(query) })).items,
|
|
431
|
+
get: (id) => http.parsed(CaseDetail, casePath(id)),
|
|
432
|
+
decide: (id, body) => http.parsed(DecideCaseResult, casePath(id, "/decide"), { method: "POST", body }),
|
|
433
|
+
/** Sets or clears (`assigneeId: null`) the assignee (`cases:assign`). */
|
|
434
|
+
assign: (id, body) => post(casePath(id, "/assign"), body),
|
|
435
|
+
/** Assigns the case to the caller (`cases:claim`). */
|
|
436
|
+
claim: (id) => post(casePath(id, "/claim")),
|
|
437
|
+
/**
|
|
438
|
+
* Closes the case (`cases:decide`). An undecided case gets a `reject` decision with reason
|
|
439
|
+
* code `case_closed` so its workflow run does not wait forever.
|
|
440
|
+
*/
|
|
441
|
+
close: (id, body = {}) => post(casePath(id, "/close"), body),
|
|
442
|
+
/** Analyst notes on a case (`cases:notes`); edits and deletes are limited to the author or an admin. */
|
|
443
|
+
notes: {
|
|
444
|
+
list: async (id) => (await http.parsed(listOf(import_core3.CaseNote), casePath(id, "/notes"))).items,
|
|
445
|
+
create: (id, body) => http.parsed(import_core3.CaseNote, casePath(id, "/notes"), { method: "POST", body }),
|
|
446
|
+
update: (id, noteId, body) => http.parsed(import_core3.CaseNote, notePath(id, noteId), { method: "PATCH", body }),
|
|
447
|
+
remove: async (id, noteId) => {
|
|
448
|
+
await http.request(notePath(id, noteId), { method: "DELETE" });
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function caseQueuesDomain(http) {
|
|
454
|
+
const queuePath = (id) => `/case-queues/${encodeSegment(id)}`;
|
|
455
|
+
return {
|
|
456
|
+
list: async () => (await http.parsed(listOf(import_core3.CaseQueue), "/case-queues")).items,
|
|
457
|
+
counts: async () => (await http.parsed(listOf(CaseQueueCount), "/case-queues/counts")).items,
|
|
458
|
+
create: (body) => http.parsed(import_core3.CaseQueue, "/case-queues", { method: "POST", body }),
|
|
459
|
+
update: (id, body) => http.parsed(import_core3.CaseQueue, queuePath(id), { method: "PUT", body }),
|
|
460
|
+
remove: async (id) => {
|
|
461
|
+
await http.request(queuePath(id), { method: "DELETE" });
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function usersDomain(http) {
|
|
466
|
+
return {
|
|
467
|
+
list: async (query = {}) => (await http.parsed(listOf(import_core3.DirectoryUser), "/users", { query: { role: query.role } })).items
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/index.ts
|
|
472
|
+
var import_core11 = require("@aletheia-dev/core");
|
|
473
|
+
|
|
474
|
+
// src/documents.ts
|
|
475
|
+
var import_core4 = require("@aletheia-dev/core");
|
|
476
|
+
var import_zod4 = require("zod");
|
|
477
|
+
var DocumentList = import_zod4.z.object({ items: import_zod4.z.array(import_core4.Document) });
|
|
478
|
+
function documentsDomain(http) {
|
|
479
|
+
const idPath = (id, suffix = "") => `/documents/${encodeSegment(id)}${suffix}`;
|
|
480
|
+
return {
|
|
481
|
+
/**
|
|
482
|
+
* Registers a pending document and returns the presigned POST to send the bytes with
|
|
483
|
+
* (`uploadToStorage`). Applicants pass their `submissionId` and the `fieldKey`.
|
|
484
|
+
*/
|
|
485
|
+
create: (input) => http.parsed(import_core4.DocumentUploadTicket, "/documents", { method: "POST", body: input }),
|
|
486
|
+
/**
|
|
487
|
+
* Verifies the uploaded object and starts the scan. Resolves with status `uploaded` or
|
|
488
|
+
* `rejected` (see `rejectionReason`); throws a 409 `ApiError` when nothing was uploaded.
|
|
489
|
+
*/
|
|
490
|
+
finalize: (id, opts = {}) => http.parsed(import_core4.Document, idPath(id, "/finalize"), { method: "POST", query: { ...opts } }),
|
|
491
|
+
get: (id, opts = {}) => http.parsed(import_core4.Document, idPath(id), { query: { ...opts } }),
|
|
492
|
+
list: (filters = {}) => http.parsed(DocumentList, "/documents", { query: { ...filters } }),
|
|
493
|
+
/** A 60-second presigned GET on the storage origin; open it directly, never via the API. */
|
|
494
|
+
download: (id, opts = {}) => http.parsed(import_core4.DocumentDownload, idPath(id, "/download"), { query: { ...opts } })
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
var UploadError = class extends Error {
|
|
498
|
+
constructor(message, status) {
|
|
499
|
+
super(message);
|
|
500
|
+
this.status = status;
|
|
501
|
+
this.name = "UploadError";
|
|
502
|
+
}
|
|
503
|
+
status;
|
|
504
|
+
};
|
|
505
|
+
function defaultXhr() {
|
|
506
|
+
const ctor = globalThis.XMLHttpRequest;
|
|
507
|
+
if (!ctor) throw new UploadError("XMLHttpRequest is not available in this environment", 0);
|
|
508
|
+
return new ctor();
|
|
509
|
+
}
|
|
510
|
+
function uploadToStorage(ticket, file, opts = {}) {
|
|
511
|
+
return new Promise((resolve, reject) => {
|
|
512
|
+
if (opts.signal?.aborted) {
|
|
513
|
+
reject(new UploadError("Upload aborted", 0));
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const xhr = (opts.xhr ?? defaultXhr)();
|
|
517
|
+
const form = new FormData();
|
|
518
|
+
for (const [name, value] of Object.entries(ticket.upload.fields)) form.append(name, value);
|
|
519
|
+
form.append("file", file);
|
|
520
|
+
const onAbort = () => xhr.abort();
|
|
521
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
522
|
+
const settle = (fn) => {
|
|
523
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
524
|
+
fn();
|
|
525
|
+
};
|
|
526
|
+
xhr.upload.addEventListener("progress", (event) => {
|
|
527
|
+
if (event.lengthComputable && event.total > 0) {
|
|
528
|
+
opts.onProgress?.(Math.min(1, event.loaded / event.total));
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
xhr.addEventListener(
|
|
532
|
+
"load",
|
|
533
|
+
() => settle(() => {
|
|
534
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
535
|
+
opts.onProgress?.(1);
|
|
536
|
+
resolve();
|
|
537
|
+
} else {
|
|
538
|
+
reject(new UploadError(`Storage refused the upload (HTTP ${xhr.status})`, xhr.status));
|
|
539
|
+
}
|
|
540
|
+
})
|
|
541
|
+
);
|
|
542
|
+
xhr.addEventListener(
|
|
543
|
+
"error",
|
|
544
|
+
() => settle(() => reject(new UploadError("Network error while uploading the file", 0)))
|
|
545
|
+
);
|
|
546
|
+
xhr.addEventListener("abort", () => settle(() => reject(new UploadError("Upload aborted", 0))));
|
|
547
|
+
xhr.addEventListener(
|
|
548
|
+
"timeout",
|
|
549
|
+
() => settle(() => reject(new UploadError("The upload timed out", 0)))
|
|
550
|
+
);
|
|
551
|
+
xhr.open("POST", ticket.upload.url);
|
|
552
|
+
xhr.send(form);
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
var TYPE_LABELS = "JPEG, PNG, WebP or PDF";
|
|
556
|
+
function checkFileBeforeUpload(file) {
|
|
557
|
+
if (!file.name.trim()) return { ok: false, reason: "The file has no name." };
|
|
558
|
+
if (!import_core4.DOCUMENT_CONTENT_TYPES.includes(file.type)) {
|
|
559
|
+
const got = file.type || "unknown type";
|
|
560
|
+
return { ok: false, reason: `Only ${TYPE_LABELS} files are accepted (this is ${got}).` };
|
|
561
|
+
}
|
|
562
|
+
if (file.size < 1) return { ok: false, reason: "The file is empty." };
|
|
563
|
+
if (file.size > import_core4.DOCUMENT_MAX_BYTES) {
|
|
564
|
+
const mib = Math.round(import_core4.DOCUMENT_MAX_BYTES / (1024 * 1024));
|
|
565
|
+
return { ok: false, reason: `The file is larger than ${mib} MiB.` };
|
|
566
|
+
}
|
|
567
|
+
return { ok: true };
|
|
568
|
+
}
|
|
569
|
+
var DocumentPollTimeoutError = class extends Error {
|
|
570
|
+
constructor(documentId) {
|
|
571
|
+
super("Timed out waiting for the document scan to finish");
|
|
572
|
+
this.documentId = documentId;
|
|
573
|
+
this.name = "DocumentPollTimeoutError";
|
|
574
|
+
}
|
|
575
|
+
documentId;
|
|
576
|
+
};
|
|
577
|
+
function isTerminalDocumentStatus(status) {
|
|
578
|
+
return !import_core4.DOCUMENT_OPEN_STATUSES.includes(status);
|
|
579
|
+
}
|
|
580
|
+
function sleep(ms, signal) {
|
|
581
|
+
return new Promise((resolve, reject) => {
|
|
582
|
+
const timer = setTimeout(() => {
|
|
583
|
+
signal?.removeEventListener("abort", onAbort);
|
|
584
|
+
resolve();
|
|
585
|
+
}, ms);
|
|
586
|
+
function onAbort() {
|
|
587
|
+
clearTimeout(timer);
|
|
588
|
+
reject(new Error("Polling aborted"));
|
|
589
|
+
}
|
|
590
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
async function pollDocument(client, id, opts = {}) {
|
|
594
|
+
const { intervalMs = 750, timeoutMs = 6e4, signal, submissionId } = opts;
|
|
595
|
+
const deadline = Date.now() + timeoutMs;
|
|
596
|
+
for (; ; ) {
|
|
597
|
+
const document = await client.documents.get(id, { submissionId });
|
|
598
|
+
if (isTerminalDocumentStatus(document.status)) return document;
|
|
599
|
+
const remaining = deadline - Date.now();
|
|
600
|
+
if (remaining <= 0) throw new DocumentPollTimeoutError(id);
|
|
601
|
+
await sleep(Math.min(intervalMs, remaining), signal);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// src/index.ts
|
|
606
|
+
var import_core12 = require("@aletheia-dev/core");
|
|
607
|
+
var import_core13 = require("@aletheia-dev/core");
|
|
608
|
+
var import_core14 = require("@aletheia-dev/core");
|
|
609
|
+
var import_core15 = require("@aletheia-dev/core");
|
|
610
|
+
|
|
611
|
+
// src/client.ts
|
|
612
|
+
var import_zod7 = require("zod");
|
|
613
|
+
var import_core8 = require("@aletheia-dev/core");
|
|
614
|
+
|
|
615
|
+
// src/builder.ts
|
|
616
|
+
var import_core5 = require("@aletheia-dev/core");
|
|
617
|
+
var import_zod5 = require("zod");
|
|
618
|
+
var itemsOf2 = (item) => import_zod5.z.object({ items: import_zod5.z.array(item) });
|
|
619
|
+
function builderDomain(http) {
|
|
620
|
+
return {
|
|
621
|
+
stepTypes: async () => (await http.parsed(itemsOf2(import_core5.StepTypeDescription), "/workflow-step-types")).items,
|
|
622
|
+
fieldTypes: async () => (await http.parsed(itemsOf2(import_core5.FieldTypeDescription), "/collection-field-types")).items
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function validateCall(http, path) {
|
|
626
|
+
return (body) => http.parsed(import_core5.ValidationReport, `${path}/validate`, { method: "POST", body });
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// src/tenants.ts
|
|
630
|
+
var import_core6 = require("@aletheia-dev/core");
|
|
631
|
+
function tenantsDomain(http) {
|
|
632
|
+
return {
|
|
633
|
+
getSettings: () => http.parsed(import_core6.TenantSettings, "/tenants/me/settings"),
|
|
634
|
+
updateSettings: (body) => http.parsed(import_core6.TenantSettings, "/tenants/me/settings", { method: "PUT", body })
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/workflow-runs.ts
|
|
639
|
+
var import_core7 = require("@aletheia-dev/core");
|
|
640
|
+
var import_zod6 = require("zod");
|
|
641
|
+
var RunList = import_zod6.z.object({ items: import_zod6.z.array(import_core7.WorkflowRun) });
|
|
642
|
+
function workflowRunsDomain(http) {
|
|
643
|
+
return {
|
|
644
|
+
start: (body) => http.parsed(import_core7.WorkflowRun, "/workflow-runs", { method: "POST", body }),
|
|
645
|
+
get: (id) => http.parsed(import_core7.WorkflowRun, `/workflow-runs/${encodeSegment(id)}`),
|
|
646
|
+
listBySubject: async (subjectId) => (await http.parsed(RunList, "/workflow-runs", { query: { subjectId } })).items,
|
|
647
|
+
history: (id) => http.request(`/workflow-runs/${encodeSegment(id)}/history`)
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// src/client.ts
|
|
652
|
+
var HealthStatus = import_zod7.z.object({ status: import_zod7.z.literal("ok") });
|
|
653
|
+
var MePrincipal = import_zod7.z.object({
|
|
654
|
+
kind: import_zod7.z.enum(["human", "machine", "applicant"]),
|
|
655
|
+
subject: import_zod7.z.string(),
|
|
656
|
+
name: import_zod7.z.string().optional(),
|
|
657
|
+
email: import_zod7.z.string().optional()
|
|
658
|
+
});
|
|
659
|
+
var Me = import_zod7.z.object({
|
|
660
|
+
principal: MePrincipal,
|
|
661
|
+
tenantId: import_zod7.z.string(),
|
|
662
|
+
orgId: import_zod7.z.string().optional(),
|
|
663
|
+
permissions: import_zod7.z.array(import_zod7.z.string())
|
|
664
|
+
});
|
|
665
|
+
var CheckStatus = import_zod7.z.enum(["ok", "error"]);
|
|
666
|
+
var ReadyStatus = import_zod7.z.object({
|
|
667
|
+
status: import_zod7.z.enum(["ok", "degraded"]),
|
|
668
|
+
checks: import_zod7.z.object({ db: CheckStatus, temporal: CheckStatus })
|
|
669
|
+
});
|
|
670
|
+
var PluginSummary = import_zod7.z.object({
|
|
671
|
+
name: import_zod7.z.string(),
|
|
672
|
+
version: import_zod7.z.string(),
|
|
673
|
+
description: import_zod7.z.string().optional(),
|
|
674
|
+
capabilities: import_zod7.z.array(import_zod7.z.string()),
|
|
675
|
+
secrets: import_zod7.z.array(import_zod7.z.string()),
|
|
676
|
+
actions: import_zod7.z.array(import_zod7.z.string()),
|
|
677
|
+
configSchema: import_zod7.z.unknown()
|
|
678
|
+
});
|
|
679
|
+
var RuleUiHints = import_zod7.z.object({
|
|
680
|
+
/** Config fields in display order; unlisted fields follow in schema order. */
|
|
681
|
+
fieldOrder: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
682
|
+
labels: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional(),
|
|
683
|
+
help: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional(),
|
|
684
|
+
/** Config fields that hold a list key; the builder renders a list picker for them. */
|
|
685
|
+
listPicker: import_zod7.z.array(import_zod7.z.string()).optional()
|
|
686
|
+
});
|
|
687
|
+
var RuleTypeDescription = import_zod7.z.object({
|
|
688
|
+
type: import_core8.RuleType,
|
|
689
|
+
description: import_zod7.z.string(),
|
|
690
|
+
/** JSON Schema of the rule config, produced by `z.toJSONSchema` on the API. */
|
|
691
|
+
configSchema: import_zod7.z.unknown(),
|
|
692
|
+
/** Dot-path namespaces a rule config may reference, e.g. `subject.<field>`. */
|
|
693
|
+
dataPaths: import_zod7.z.array(import_zod7.z.string()).default([]),
|
|
694
|
+
uiHints: RuleUiHints.optional()
|
|
695
|
+
});
|
|
696
|
+
var DryRunResult = import_zod7.z.object({
|
|
697
|
+
result: import_core8.RuleEvaluationResult,
|
|
698
|
+
rule: import_zod7.z.object({
|
|
699
|
+
key: import_zod7.z.string(),
|
|
700
|
+
version: import_zod7.z.number().int(),
|
|
701
|
+
status: import_core8.DefinitionStatus,
|
|
702
|
+
type: import_core8.RuleType
|
|
703
|
+
}),
|
|
704
|
+
/** Data namespaces the rule may reference, a hint for composing inline test data. */
|
|
705
|
+
dataPaths: import_zod7.z.array(import_zod7.z.string()).default([])
|
|
706
|
+
});
|
|
707
|
+
var RemovedCount = import_zod7.z.object({ removed: import_zod7.z.number().int().nonnegative() });
|
|
708
|
+
var SubmissionDetail = import_zod7.z.object({
|
|
709
|
+
submission: import_core8.CollectionSubmission,
|
|
710
|
+
flow: import_core8.CollectionFlowDefinition
|
|
711
|
+
});
|
|
712
|
+
var SubmissionStatus = import_zod7.z.object({
|
|
713
|
+
submission: import_zod7.z.object({
|
|
714
|
+
id: import_core8.Id,
|
|
715
|
+
status: import_core8.SubmissionStatus,
|
|
716
|
+
submittedAt: import_zod7.z.coerce.date().nullable()
|
|
717
|
+
}),
|
|
718
|
+
run: import_zod7.z.object({
|
|
719
|
+
id: import_core8.Id,
|
|
720
|
+
status: import_core8.WorkflowRunStatus,
|
|
721
|
+
currentStepId: import_zod7.z.string().nullable(),
|
|
722
|
+
decision: import_zod7.z.object({ outcome: import_core8.DecisionOutcome }).nullable()
|
|
723
|
+
}).nullable()
|
|
724
|
+
});
|
|
725
|
+
var CreatedSubmission = import_zod7.z.object({
|
|
726
|
+
submission: import_core8.CollectionSubmission,
|
|
727
|
+
link: import_zod7.z.string().nullable()
|
|
728
|
+
});
|
|
729
|
+
var SubmissionEmbed = import_zod7.z.object({
|
|
730
|
+
embedOrigins: import_zod7.z.array(import_zod7.z.string()),
|
|
731
|
+
flowName: import_zod7.z.string()
|
|
732
|
+
});
|
|
733
|
+
var listOf2 = (item) => import_zod7.z.object({ items: import_zod7.z.array(item) });
|
|
734
|
+
function isoOf3(value) {
|
|
735
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
736
|
+
}
|
|
737
|
+
function timelineParams(query) {
|
|
738
|
+
return {
|
|
739
|
+
from: isoOf3(query.from),
|
|
740
|
+
to: isoOf3(query.to),
|
|
741
|
+
kinds: query.kinds,
|
|
742
|
+
limit: query.limit,
|
|
743
|
+
offset: query.offset
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function createApiClient(options) {
|
|
747
|
+
const fetchImpl = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
748
|
+
const transport = {
|
|
749
|
+
baseUrl: options.baseUrl.replace(/\/+$/, ""),
|
|
750
|
+
getAccessToken: options.getAccessToken,
|
|
751
|
+
fetch: fetchImpl
|
|
752
|
+
};
|
|
753
|
+
const http = new Http(transport);
|
|
754
|
+
const audit = auditDomain(http, transport);
|
|
755
|
+
const list = async (item, path, query) => (await http.parsed(listOf2(item), path, { query })).items;
|
|
756
|
+
const definitions = (entity, path) => ({
|
|
757
|
+
list: () => list(entity, path),
|
|
758
|
+
get: (key) => http.parsed(entity, `${path}/${encodeSegment(key)}`),
|
|
759
|
+
upsert: (key, body) => http.parsed(entity, `${path}/${encodeSegment(key)}`, { method: "PUT", body }),
|
|
760
|
+
publish: (key) => http.parsed(entity, `${path}/${encodeSegment(key)}/publish`, { method: "POST" })
|
|
761
|
+
});
|
|
762
|
+
return {
|
|
763
|
+
health: {
|
|
764
|
+
check: () => http.parsed(HealthStatus, "/health"),
|
|
765
|
+
ready: () => http.parsed(ReadyStatus, "/health/ready")
|
|
766
|
+
},
|
|
767
|
+
/** The caller's principal, tenant and permissions as the API sees the bearer token. */
|
|
768
|
+
me: () => http.parsed(Me, "/me"),
|
|
769
|
+
subjects: {
|
|
770
|
+
create: (body) => http.parsed(import_core8.Subject, "/subjects", { method: "POST", body }),
|
|
771
|
+
/**
|
|
772
|
+
* Subjects matching `query`: `search` matches the external id and `data.name` /
|
|
773
|
+
* `data.legalName`; `riskScoreMin`/`riskScoreMax` bound the risk score (`subjects:read`).
|
|
774
|
+
*/
|
|
775
|
+
list: (query = {}) => list(import_core8.Subject, "/subjects", query),
|
|
776
|
+
get: (id) => http.parsed(import_core8.Subject, `/subjects/${encodeSegment(id)}`),
|
|
777
|
+
/**
|
|
778
|
+
* The subject's history, newest first (`subjects:read`). Entries of kinds the caller may
|
|
779
|
+
* not read are omitted by the API; page with `offset`.
|
|
780
|
+
*/
|
|
781
|
+
timeline: (id, query = {}) => list(import_core8.TimelineEntry, `/subjects/${encodeSegment(id)}/timeline`, timelineParams(query))
|
|
782
|
+
},
|
|
783
|
+
workflowRuns: workflowRunsDomain(http),
|
|
784
|
+
/** Review cases: filtered lists, detail, decide, assign/claim/close and notes. See `cases.ts`. */
|
|
785
|
+
cases: casesDomain(http),
|
|
786
|
+
/** Saved case filters shown in the workbench rail, with live counts. */
|
|
787
|
+
caseQueues: caseQueuesDomain(http),
|
|
788
|
+
/** The reviewer directory, for assignment and resolving assignee names. */
|
|
789
|
+
users: usersDomain(http),
|
|
790
|
+
workflowDefinitions: {
|
|
791
|
+
...definitions(
|
|
792
|
+
import_core8.WorkflowDefinition,
|
|
793
|
+
"/workflow-definitions"
|
|
794
|
+
),
|
|
795
|
+
/** Validates a draft body without saving; issues carry step ids. */
|
|
796
|
+
validate: validateCall(http, "/workflow-definitions")
|
|
797
|
+
},
|
|
798
|
+
/** Step and field type schemas behind the builder's forms. */
|
|
799
|
+
builder: builderDomain(http),
|
|
800
|
+
ruleDefinitions: {
|
|
801
|
+
...definitions(
|
|
802
|
+
import_core8.RuleDefinition,
|
|
803
|
+
"/rule-definitions"
|
|
804
|
+
),
|
|
805
|
+
/** Evaluates one rule version against a subject or inline data; nothing is recorded. */
|
|
806
|
+
dryRun: (key, body) => http.parsed(DryRunResult, `/rule-definitions/${encodeSegment(key)}/dry-run`, {
|
|
807
|
+
method: "POST",
|
|
808
|
+
body
|
|
809
|
+
})
|
|
810
|
+
},
|
|
811
|
+
ruleTypes: {
|
|
812
|
+
list: () => list(RuleTypeDescription, "/rule-types")
|
|
813
|
+
},
|
|
814
|
+
/** Versioned, ordered groups of rules with an aggregation policy (`/rule-sets`). */
|
|
815
|
+
ruleSets: definitions(
|
|
816
|
+
import_core8.RuleSetDefinition,
|
|
817
|
+
"/rule-sets"
|
|
818
|
+
),
|
|
819
|
+
collectionFlows: {
|
|
820
|
+
...definitions(
|
|
821
|
+
import_core8.CollectionFlowDefinition,
|
|
822
|
+
"/collection-flows"
|
|
823
|
+
),
|
|
824
|
+
/** Validates a draft flow body without saving; issues carry step / field keys. */
|
|
825
|
+
validate: validateCall(http, "/collection-flows")
|
|
826
|
+
},
|
|
827
|
+
collectionSubmissions: {
|
|
828
|
+
/** Creates the submission and returns the applicant link alongside it. */
|
|
829
|
+
create: (body) => http.parsed(CreatedSubmission, "/collection-submissions", { method: "POST", body }),
|
|
830
|
+
get: (id) => http.parsed(SubmissionDetail, `/collection-submissions/${encodeSegment(id)}`),
|
|
831
|
+
save: (id, body) => http.parsed(import_core8.CollectionSubmission, `/collection-submissions/${encodeSegment(id)}`, {
|
|
832
|
+
method: "PATCH",
|
|
833
|
+
body
|
|
834
|
+
}),
|
|
835
|
+
submit: (id) => http.parsed(import_core8.CollectionSubmission, `/collection-submissions/${encodeSegment(id)}/submit`, {
|
|
836
|
+
method: "POST"
|
|
837
|
+
}),
|
|
838
|
+
/** Where the submission's workflow run is; readable with the applicant's token. */
|
|
839
|
+
status: (id) => http.parsed(SubmissionStatus, `/collection-submissions/${encodeSegment(id)}/status`),
|
|
840
|
+
/** Embed allow-list and flow name for the submission; readable with the applicant's token. */
|
|
841
|
+
embed: (id) => http.parsed(SubmissionEmbed, `/collection-submissions/${encodeSegment(id)}/embed`)
|
|
842
|
+
},
|
|
843
|
+
/** Subject events: the facts velocity rules aggregate over. */
|
|
844
|
+
events: {
|
|
845
|
+
/** Inserts events; re-sent idempotency keys are counted as `duplicates`, not errors. */
|
|
846
|
+
ingest: (body) => http.parsed(import_core8.IngestEventsResult, "/events", { method: "POST", body }),
|
|
847
|
+
/** Newest first. */
|
|
848
|
+
list: (query = {}) => list(import_core8.Event, "/events", { ...query, from: isoOf3(query.from), to: isoOf3(query.to) })
|
|
849
|
+
},
|
|
850
|
+
/**
|
|
851
|
+
* Replays recorded evaluations against a rule version (`backtests:run`). `start` returns the
|
|
852
|
+
* queued job; poll `get` until its status is `completed` (with `summary`) or `failed`.
|
|
853
|
+
*/
|
|
854
|
+
backtests: {
|
|
855
|
+
start: (body) => http.parsed(import_core8.Backtest, "/backtests", { method: "POST", body }),
|
|
856
|
+
/** Newest first. */
|
|
857
|
+
list: (query = {}) => list(import_core8.Backtest, "/backtests", query),
|
|
858
|
+
get: (id) => http.parsed(import_core8.Backtest, `/backtests/${encodeSegment(id)}`)
|
|
859
|
+
},
|
|
860
|
+
decisions: {
|
|
861
|
+
listBySubject: (subjectId) => list(import_core8.Decision, "/decisions", { subjectId })
|
|
862
|
+
},
|
|
863
|
+
/** Filtered audit trail, exports and manifest verification (`audit:read`). See `audit.ts`. */
|
|
864
|
+
audit,
|
|
865
|
+
/** @deprecated Alias of `audit`, kept for existing callers. */
|
|
866
|
+
auditEvents: {
|
|
867
|
+
list: (query = {}) => audit.list(query)
|
|
868
|
+
},
|
|
869
|
+
/** Version history, diffs and the approval workflow of definitions. See `governance.ts`. */
|
|
870
|
+
governance: governanceDomain(http),
|
|
871
|
+
plugins: {
|
|
872
|
+
list: () => list(import_core8.PluginDefinition, "/plugins"),
|
|
873
|
+
available: () => list(PluginSummary, "/plugins/available"),
|
|
874
|
+
configure: (name, body) => http.parsed(import_core8.PluginDefinition, `/plugins/${encodeSegment(name)}`, { method: "PUT", body })
|
|
875
|
+
},
|
|
876
|
+
pluginInvocations: {
|
|
877
|
+
list: (query = {}) => list(import_core8.PluginInvocation, "/plugin-invocations", query)
|
|
878
|
+
},
|
|
879
|
+
/**
|
|
880
|
+
* Uploaded files: `create` -> `uploadToStorage` (helper) -> `finalize` -> `pollDocument`
|
|
881
|
+
* (helper) until the scan settles. See `documents.ts`.
|
|
882
|
+
*/
|
|
883
|
+
documents: documentsDomain(http),
|
|
884
|
+
/** Tenant settings such as the embed origin allow-list (`tenants:settings`). */
|
|
885
|
+
tenants: tenantsDomain(http),
|
|
886
|
+
/** Tenant lists (blocklists / allowlists) and their entries. Lists are keyed, not versioned. */
|
|
887
|
+
lists: {
|
|
888
|
+
list: () => list(import_core8.List, "/lists"),
|
|
889
|
+
get: (key) => http.parsed(import_core8.List, `/lists/${encodeSegment(key)}`),
|
|
890
|
+
/** Creates the list or updates its metadata; entries are untouched. */
|
|
891
|
+
upsert: (key, body) => http.parsed(import_core8.List, `/lists/${encodeSegment(key)}`, { method: "PUT", body }),
|
|
892
|
+
remove: async (key) => {
|
|
893
|
+
await http.request(`/lists/${encodeSegment(key)}`, { method: "DELETE" });
|
|
894
|
+
},
|
|
895
|
+
entries: (key, query = {}) => list(import_core8.ListEntry, `/lists/${encodeSegment(key)}/entries`, query),
|
|
896
|
+
addEntries: (key, body) => http.parsed(import_core8.ListImportResult, `/lists/${encodeSegment(key)}/entries`, {
|
|
897
|
+
method: "POST",
|
|
898
|
+
body
|
|
899
|
+
}),
|
|
900
|
+
removeEntries: (key, body) => http.parsed(RemovedCount, `/lists/${encodeSegment(key)}/entries`, {
|
|
901
|
+
method: "DELETE",
|
|
902
|
+
body
|
|
903
|
+
}),
|
|
904
|
+
/** Uploads a CSV (one value per line, optional `value,reason,expires_at` header). */
|
|
905
|
+
importCsv: (key, csv) => http.parsed(import_core8.ListImportResult, `/lists/${encodeSegment(key)}/import`, {
|
|
906
|
+
method: "POST",
|
|
907
|
+
raw: { content: csv, contentType: "text/csv" }
|
|
908
|
+
})
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// src/runtime-config.ts
|
|
914
|
+
var import_zod8 = require("zod");
|
|
915
|
+
var RuntimeConfig = import_zod8.z.object({
|
|
916
|
+
apiUrl: import_zod8.z.string(),
|
|
917
|
+
zitadelIssuer: import_zod8.z.string(),
|
|
918
|
+
zitadelProjectId: import_zod8.z.string(),
|
|
919
|
+
zitadelClientId: import_zod8.z.string(),
|
|
920
|
+
zitadelOrgDomain: import_zod8.z.string(),
|
|
921
|
+
collectionFlowUrl: import_zod8.z.string()
|
|
922
|
+
}).partial();
|
|
923
|
+
var RUNTIME_CONFIG_PATH = "/config.json";
|
|
924
|
+
async function loadRuntimeConfig(fetchImpl = fetch) {
|
|
925
|
+
try {
|
|
926
|
+
const init = { cache: "no-store", headers: { accept: "application/json" } };
|
|
927
|
+
const response = await fetchImpl(RUNTIME_CONFIG_PATH, init);
|
|
928
|
+
if (!response.ok) return {};
|
|
929
|
+
const parsed = RuntimeConfig.safeParse(await response.json());
|
|
930
|
+
return parsed.success ? parsed.data : {};
|
|
931
|
+
} catch {
|
|
932
|
+
return {};
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
function present(value) {
|
|
936
|
+
return value !== void 0 && value !== "";
|
|
937
|
+
}
|
|
938
|
+
function resolveConfig(runtime, env, defaults) {
|
|
939
|
+
const resolved = { ...defaults };
|
|
940
|
+
for (const key of Object.keys(defaults)) {
|
|
941
|
+
const fromRuntime = runtime[key];
|
|
942
|
+
const fromEnv = env[key];
|
|
943
|
+
if (present(fromRuntime)) resolved[key] = fromRuntime;
|
|
944
|
+
else if (present(fromEnv)) resolved[key] = fromEnv;
|
|
945
|
+
}
|
|
946
|
+
return resolved;
|
|
947
|
+
}
|
|
948
|
+
//# sourceMappingURL=index.cjs.map
|