optropic 2.0.0 → 2.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/dist/index.cjs +247 -0
- package/dist/index.d.cts +232 -1
- package/dist/index.d.ts +232 -1
- package/dist/index.js +244 -0
- package/package.json +5 -2
package/dist/index.cjs
CHANGED
|
@@ -31,9 +31,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AssetsResource: () => AssetsResource,
|
|
34
|
+
AuditResource: () => AuditResource,
|
|
34
35
|
AuthenticationError: () => AuthenticationError,
|
|
35
36
|
BatchNotFoundError: () => BatchNotFoundError,
|
|
36
37
|
CodeNotFoundError: () => CodeNotFoundError,
|
|
38
|
+
ComplianceResource: () => ComplianceResource,
|
|
37
39
|
InvalidCodeError: () => InvalidCodeError,
|
|
38
40
|
InvalidGTINError: () => InvalidGTINError,
|
|
39
41
|
InvalidSerialError: () => InvalidSerialError,
|
|
@@ -46,6 +48,7 @@ __export(index_exports, {
|
|
|
46
48
|
RateLimitedError: () => RateLimitedError,
|
|
47
49
|
RevokedCodeError: () => RevokedCodeError,
|
|
48
50
|
SDK_VERSION: () => SDK_VERSION2,
|
|
51
|
+
SchemasResource: () => SchemasResource,
|
|
49
52
|
ServiceUnavailableError: () => ServiceUnavailableError,
|
|
50
53
|
TimeoutError: () => TimeoutError,
|
|
51
54
|
createClient: () => createClient,
|
|
@@ -482,6 +485,117 @@ var AssetsResource = class {
|
|
|
482
485
|
}
|
|
483
486
|
};
|
|
484
487
|
|
|
488
|
+
// src/resources/audit.ts
|
|
489
|
+
var AuditResource = class {
|
|
490
|
+
constructor(request) {
|
|
491
|
+
this.request = request;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* List audit events with optional filtering and pagination.
|
|
495
|
+
*/
|
|
496
|
+
async list(params) {
|
|
497
|
+
const query = params ? this.buildQuery(params) : "";
|
|
498
|
+
return this.request({ method: "GET", path: `/v1/audit${query}` });
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Retrieve a single audit event by ID.
|
|
502
|
+
*/
|
|
503
|
+
async get(eventId) {
|
|
504
|
+
return this.request({
|
|
505
|
+
method: "GET",
|
|
506
|
+
path: `/v1/audit/${encodeURIComponent(eventId)}`
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Record a custom audit event.
|
|
511
|
+
*/
|
|
512
|
+
async create(params) {
|
|
513
|
+
return this.request({
|
|
514
|
+
method: "POST",
|
|
515
|
+
path: "/v1/audit",
|
|
516
|
+
body: {
|
|
517
|
+
event_type: params.eventType,
|
|
518
|
+
...params.resourceId !== void 0 && { resource_id: params.resourceId },
|
|
519
|
+
...params.resourceType !== void 0 && { resource_type: params.resourceType },
|
|
520
|
+
...params.details !== void 0 && { details: params.details }
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
buildQuery(params) {
|
|
525
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
526
|
+
if (entries.length === 0) return "";
|
|
527
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
// src/resources/compliance.ts
|
|
532
|
+
var ComplianceResource = class {
|
|
533
|
+
constructor(request) {
|
|
534
|
+
this.request = request;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Verify the integrity of the full audit chain.
|
|
538
|
+
*/
|
|
539
|
+
async verifyChain() {
|
|
540
|
+
return this.request({
|
|
541
|
+
method: "POST",
|
|
542
|
+
path: "/v1/compliance/verify-chain"
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Return all Merkle roots.
|
|
547
|
+
*/
|
|
548
|
+
async listMerkleRoots() {
|
|
549
|
+
return this.request({
|
|
550
|
+
method: "GET",
|
|
551
|
+
path: "/v1/compliance/merkle-roots"
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Return a Merkle inclusion proof for a specific audit event.
|
|
556
|
+
*/
|
|
557
|
+
async getMerkleProof(eventId) {
|
|
558
|
+
return this.request({
|
|
559
|
+
method: "GET",
|
|
560
|
+
path: `/v1/compliance/merkle-proof/${encodeURIComponent(eventId)}`
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Export audit data as a signed CSV.
|
|
565
|
+
*/
|
|
566
|
+
async exportAudit(params) {
|
|
567
|
+
const query = params ? this.buildQuery(params) : "";
|
|
568
|
+
return this.request({
|
|
569
|
+
method: "GET",
|
|
570
|
+
path: `/v1/compliance/export${query}`
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Retrieve the current compliance configuration.
|
|
575
|
+
*/
|
|
576
|
+
async getConfig() {
|
|
577
|
+
return this.request({
|
|
578
|
+
method: "GET",
|
|
579
|
+
path: "/v1/compliance/config"
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Update the compliance mode.
|
|
584
|
+
*/
|
|
585
|
+
async updateConfig(mode) {
|
|
586
|
+
return this.request({
|
|
587
|
+
method: "POST",
|
|
588
|
+
path: "/v1/compliance/config",
|
|
589
|
+
body: { compliance_mode: mode }
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
buildQuery(params) {
|
|
593
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
594
|
+
if (entries.length === 0) return "";
|
|
595
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
|
|
485
599
|
// src/resources/keys.ts
|
|
486
600
|
var KeysResource = class {
|
|
487
601
|
constructor(request) {
|
|
@@ -518,6 +632,130 @@ var KeysetsResource = class {
|
|
|
518
632
|
}
|
|
519
633
|
};
|
|
520
634
|
|
|
635
|
+
// src/resources/schemas.ts
|
|
636
|
+
function checkType(value, expected) {
|
|
637
|
+
switch (expected) {
|
|
638
|
+
case "string":
|
|
639
|
+
return typeof value === "string";
|
|
640
|
+
case "number":
|
|
641
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
642
|
+
case "boolean":
|
|
643
|
+
return typeof value === "boolean";
|
|
644
|
+
case "date":
|
|
645
|
+
return typeof value === "string";
|
|
646
|
+
// ISO 8601 string
|
|
647
|
+
case "array":
|
|
648
|
+
return Array.isArray(value);
|
|
649
|
+
default:
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
var SchemasResource = class {
|
|
654
|
+
constructor(request) {
|
|
655
|
+
this.request = request;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Register or update a vertical config schema.
|
|
659
|
+
* If a schema already exists for the verticalId, it will be updated.
|
|
660
|
+
*/
|
|
661
|
+
async create(params) {
|
|
662
|
+
const body = this.stripUndefined({
|
|
663
|
+
vertical_id: params.verticalId,
|
|
664
|
+
metadata_schema: params.metadataSchema,
|
|
665
|
+
version: params.version,
|
|
666
|
+
export_formats: params.exportFormats,
|
|
667
|
+
description: params.description
|
|
668
|
+
});
|
|
669
|
+
return this.request({ method: "POST", path: "/v1/schemas", body });
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* List registered vertical schemas with pagination.
|
|
673
|
+
*/
|
|
674
|
+
async list(params) {
|
|
675
|
+
const query = params ? this.buildQuery(params) : "";
|
|
676
|
+
return this.request({ method: "GET", path: `/v1/schemas${query}` });
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Get the active schema for a specific vertical.
|
|
680
|
+
*/
|
|
681
|
+
async get(verticalId) {
|
|
682
|
+
return this.request({
|
|
683
|
+
method: "GET",
|
|
684
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Update an existing vertical schema.
|
|
689
|
+
*/
|
|
690
|
+
async update(verticalId, params) {
|
|
691
|
+
const body = this.stripUndefined({
|
|
692
|
+
version: params.version,
|
|
693
|
+
metadata_schema: params.metadataSchema,
|
|
694
|
+
export_formats: params.exportFormats,
|
|
695
|
+
description: params.description,
|
|
696
|
+
is_active: params.isActive
|
|
697
|
+
});
|
|
698
|
+
return this.request({
|
|
699
|
+
method: "PUT",
|
|
700
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`,
|
|
701
|
+
body
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Deactivate a vertical schema (soft delete).
|
|
706
|
+
*/
|
|
707
|
+
async delete(verticalId) {
|
|
708
|
+
await this.request({
|
|
709
|
+
method: "DELETE",
|
|
710
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Pre-flight validation: check if assetConfig matches the registered schema.
|
|
715
|
+
*
|
|
716
|
+
* This is a client-side convenience that fetches the schema and validates locally.
|
|
717
|
+
* The server also validates on asset creation.
|
|
718
|
+
*/
|
|
719
|
+
async validate(verticalId, assetConfig) {
|
|
720
|
+
let schema;
|
|
721
|
+
try {
|
|
722
|
+
schema = await this.get(verticalId);
|
|
723
|
+
} catch {
|
|
724
|
+
return { valid: true, errors: [] };
|
|
725
|
+
}
|
|
726
|
+
const errors = [];
|
|
727
|
+
const metadataSchema = schema.metadataSchema ?? {};
|
|
728
|
+
for (const [fieldName, fieldDef] of Object.entries(metadataSchema)) {
|
|
729
|
+
if (typeof fieldDef !== "object" || fieldDef === null) continue;
|
|
730
|
+
const def = fieldDef;
|
|
731
|
+
const value = assetConfig[fieldName];
|
|
732
|
+
if (def.required && (value === void 0 || value === null || value === "")) {
|
|
733
|
+
const label = def.label ?? fieldName;
|
|
734
|
+
errors.push({ field: fieldName, message: `Required field "${label}" is missing` });
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
if (value === void 0 || value === null) continue;
|
|
738
|
+
const expectedType = def.type ?? "string";
|
|
739
|
+
if (!checkType(value, expectedType)) {
|
|
740
|
+
errors.push({
|
|
741
|
+
field: fieldName,
|
|
742
|
+
message: `"${def.label ?? fieldName}" must be a ${expectedType}`,
|
|
743
|
+
received: typeof value
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return { valid: errors.length === 0, errors };
|
|
748
|
+
}
|
|
749
|
+
buildQuery(params) {
|
|
750
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
751
|
+
if (entries.length === 0) return "";
|
|
752
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
753
|
+
}
|
|
754
|
+
stripUndefined(obj) {
|
|
755
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
|
|
521
759
|
// src/client.ts
|
|
522
760
|
var DEFAULT_BASE_URL = "https://api.optropic.com";
|
|
523
761
|
var DEFAULT_TIMEOUT = 3e4;
|
|
@@ -534,8 +772,11 @@ var OptropicClient = class {
|
|
|
534
772
|
retryConfig;
|
|
535
773
|
_sandbox;
|
|
536
774
|
assets;
|
|
775
|
+
audit;
|
|
776
|
+
compliance;
|
|
537
777
|
keys;
|
|
538
778
|
keysets;
|
|
779
|
+
schemas;
|
|
539
780
|
constructor(config) {
|
|
540
781
|
if (!config.apiKey || !this.isValidApiKey(config.apiKey)) {
|
|
541
782
|
throw new AuthenticationError(
|
|
@@ -562,8 +803,11 @@ var OptropicClient = class {
|
|
|
562
803
|
};
|
|
563
804
|
const boundRequest = this.request.bind(this);
|
|
564
805
|
this.assets = new AssetsResource(boundRequest, this);
|
|
806
|
+
this.audit = new AuditResource(boundRequest);
|
|
807
|
+
this.compliance = new ComplianceResource(boundRequest);
|
|
565
808
|
this.keys = new KeysResource(boundRequest);
|
|
566
809
|
this.keysets = new KeysetsResource(boundRequest);
|
|
810
|
+
this.schemas = new SchemasResource(boundRequest);
|
|
567
811
|
}
|
|
568
812
|
// ─────────────────────────────────────────────────────────────────────────
|
|
569
813
|
// ENVIRONMENT DETECTION
|
|
@@ -759,9 +1003,11 @@ var SDK_VERSION2 = "2.0.0";
|
|
|
759
1003
|
// Annotate the CommonJS export names for ESM import in node:
|
|
760
1004
|
0 && (module.exports = {
|
|
761
1005
|
AssetsResource,
|
|
1006
|
+
AuditResource,
|
|
762
1007
|
AuthenticationError,
|
|
763
1008
|
BatchNotFoundError,
|
|
764
1009
|
CodeNotFoundError,
|
|
1010
|
+
ComplianceResource,
|
|
765
1011
|
InvalidCodeError,
|
|
766
1012
|
InvalidGTINError,
|
|
767
1013
|
InvalidSerialError,
|
|
@@ -774,6 +1020,7 @@ var SDK_VERSION2 = "2.0.0";
|
|
|
774
1020
|
RateLimitedError,
|
|
775
1021
|
RevokedCodeError,
|
|
776
1022
|
SDK_VERSION,
|
|
1023
|
+
SchemasResource,
|
|
777
1024
|
ServiceUnavailableError,
|
|
778
1025
|
TimeoutError,
|
|
779
1026
|
createClient,
|
package/dist/index.d.cts
CHANGED
|
@@ -166,6 +166,144 @@ declare class AssetsResource {
|
|
|
166
166
|
private buildQuery;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Audit Resource
|
|
171
|
+
*
|
|
172
|
+
* Immutable audit log operations — list, get, and create custom audit events.
|
|
173
|
+
* Mirrors the Python SDK's `optropic.resources.audit` module.
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
interface AuditEvent {
|
|
177
|
+
readonly id: string;
|
|
178
|
+
readonly tenantId: string;
|
|
179
|
+
readonly eventType: string;
|
|
180
|
+
readonly actor: string;
|
|
181
|
+
readonly createdAt: string;
|
|
182
|
+
readonly resourceId?: string;
|
|
183
|
+
readonly resourceType?: string;
|
|
184
|
+
readonly details?: Record<string, unknown>;
|
|
185
|
+
readonly eventHash?: string;
|
|
186
|
+
readonly chainSequence?: number;
|
|
187
|
+
}
|
|
188
|
+
interface ListAuditParams {
|
|
189
|
+
readonly page?: number;
|
|
190
|
+
readonly limit?: number;
|
|
191
|
+
readonly event_type?: string;
|
|
192
|
+
readonly resource_id?: string;
|
|
193
|
+
readonly from_date?: string;
|
|
194
|
+
readonly to_date?: string;
|
|
195
|
+
}
|
|
196
|
+
interface ListAuditResponse {
|
|
197
|
+
readonly data: AuditEvent[];
|
|
198
|
+
readonly pagination: {
|
|
199
|
+
readonly total: number;
|
|
200
|
+
readonly page: number;
|
|
201
|
+
readonly perPage: number;
|
|
202
|
+
readonly totalPages: number;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
interface CreateAuditEventParams {
|
|
206
|
+
readonly eventType: string;
|
|
207
|
+
readonly resourceId?: string;
|
|
208
|
+
readonly resourceType?: string;
|
|
209
|
+
readonly details?: Record<string, unknown>;
|
|
210
|
+
}
|
|
211
|
+
declare class AuditResource {
|
|
212
|
+
private readonly request;
|
|
213
|
+
constructor(request: RequestFn);
|
|
214
|
+
/**
|
|
215
|
+
* List audit events with optional filtering and pagination.
|
|
216
|
+
*/
|
|
217
|
+
list(params?: ListAuditParams): Promise<ListAuditResponse>;
|
|
218
|
+
/**
|
|
219
|
+
* Retrieve a single audit event by ID.
|
|
220
|
+
*/
|
|
221
|
+
get(eventId: string): Promise<AuditEvent>;
|
|
222
|
+
/**
|
|
223
|
+
* Record a custom audit event.
|
|
224
|
+
*/
|
|
225
|
+
create(params: CreateAuditEventParams): Promise<AuditEvent>;
|
|
226
|
+
private buildQuery;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Compliance Resource
|
|
231
|
+
*
|
|
232
|
+
* Chain verification, Merkle proofs, audit export, and compliance configuration.
|
|
233
|
+
* Mirrors the Python SDK's `optropic.resources.compliance` module.
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
interface ChainVerifyResult {
|
|
237
|
+
readonly tenantId: string;
|
|
238
|
+
readonly chainValid: boolean;
|
|
239
|
+
readonly eventsChecked: number;
|
|
240
|
+
readonly verifiedAt: string;
|
|
241
|
+
readonly brokenAtSequence?: number;
|
|
242
|
+
}
|
|
243
|
+
interface MerkleRoot {
|
|
244
|
+
readonly id: string;
|
|
245
|
+
readonly rootHash: string;
|
|
246
|
+
readonly eventCount: number;
|
|
247
|
+
readonly periodStart: string;
|
|
248
|
+
readonly periodEnd: string;
|
|
249
|
+
readonly createdAt: string;
|
|
250
|
+
}
|
|
251
|
+
interface MerkleProof {
|
|
252
|
+
readonly eventId: string;
|
|
253
|
+
readonly eventHash: string;
|
|
254
|
+
readonly merkleRoot: string;
|
|
255
|
+
readonly proof: string[];
|
|
256
|
+
readonly verified: boolean;
|
|
257
|
+
readonly period: string;
|
|
258
|
+
}
|
|
259
|
+
interface ExportParams {
|
|
260
|
+
readonly from_date?: string;
|
|
261
|
+
readonly to_date?: string;
|
|
262
|
+
readonly limit?: number;
|
|
263
|
+
}
|
|
264
|
+
interface ExportResult {
|
|
265
|
+
readonly filename: string;
|
|
266
|
+
readonly eventCount: number;
|
|
267
|
+
readonly csv: string;
|
|
268
|
+
readonly signature?: string;
|
|
269
|
+
readonly publicKeyHex?: string;
|
|
270
|
+
readonly keyId?: string;
|
|
271
|
+
readonly algorithm?: string;
|
|
272
|
+
}
|
|
273
|
+
interface ComplianceConfig {
|
|
274
|
+
readonly complianceMode: string;
|
|
275
|
+
readonly retentionPolicy: Record<string, unknown>;
|
|
276
|
+
}
|
|
277
|
+
declare class ComplianceResource {
|
|
278
|
+
private readonly request;
|
|
279
|
+
constructor(request: RequestFn);
|
|
280
|
+
/**
|
|
281
|
+
* Verify the integrity of the full audit chain.
|
|
282
|
+
*/
|
|
283
|
+
verifyChain(): Promise<ChainVerifyResult>;
|
|
284
|
+
/**
|
|
285
|
+
* Return all Merkle roots.
|
|
286
|
+
*/
|
|
287
|
+
listMerkleRoots(): Promise<MerkleRoot[]>;
|
|
288
|
+
/**
|
|
289
|
+
* Return a Merkle inclusion proof for a specific audit event.
|
|
290
|
+
*/
|
|
291
|
+
getMerkleProof(eventId: string): Promise<MerkleProof>;
|
|
292
|
+
/**
|
|
293
|
+
* Export audit data as a signed CSV.
|
|
294
|
+
*/
|
|
295
|
+
exportAudit(params?: ExportParams): Promise<ExportResult>;
|
|
296
|
+
/**
|
|
297
|
+
* Retrieve the current compliance configuration.
|
|
298
|
+
*/
|
|
299
|
+
getConfig(): Promise<ComplianceConfig>;
|
|
300
|
+
/**
|
|
301
|
+
* Update the compliance mode.
|
|
302
|
+
*/
|
|
303
|
+
updateConfig(mode: string): Promise<ComplianceConfig>;
|
|
304
|
+
private buildQuery;
|
|
305
|
+
}
|
|
306
|
+
|
|
169
307
|
/**
|
|
170
308
|
* Keys Resource
|
|
171
309
|
*
|
|
@@ -238,6 +376,96 @@ declare class KeysetsResource {
|
|
|
238
376
|
private buildQuery;
|
|
239
377
|
}
|
|
240
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Schemas Resource
|
|
381
|
+
*
|
|
382
|
+
* Schema Registry operations — register and manage vertical config schemas.
|
|
383
|
+
* Mirrors the Python SDK's `optropic.resources.schemas` module.
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
interface VerticalSchema {
|
|
387
|
+
readonly id: string;
|
|
388
|
+
readonly tenantId: string;
|
|
389
|
+
readonly verticalId: string;
|
|
390
|
+
readonly version: string;
|
|
391
|
+
readonly metadataSchema: Record<string, unknown>;
|
|
392
|
+
readonly exportFormats: string[];
|
|
393
|
+
readonly isActive: boolean;
|
|
394
|
+
readonly createdAt: string;
|
|
395
|
+
readonly updatedAt: string;
|
|
396
|
+
readonly description?: string;
|
|
397
|
+
}
|
|
398
|
+
interface CreateSchemaParams {
|
|
399
|
+
readonly verticalId: string;
|
|
400
|
+
readonly metadataSchema: Record<string, unknown>;
|
|
401
|
+
readonly version?: string;
|
|
402
|
+
readonly exportFormats?: string[];
|
|
403
|
+
readonly description?: string;
|
|
404
|
+
}
|
|
405
|
+
interface UpdateSchemaParams {
|
|
406
|
+
readonly version?: string;
|
|
407
|
+
readonly metadataSchema?: Record<string, unknown>;
|
|
408
|
+
readonly exportFormats?: string[];
|
|
409
|
+
readonly description?: string;
|
|
410
|
+
readonly isActive?: boolean;
|
|
411
|
+
}
|
|
412
|
+
interface ListSchemasParams {
|
|
413
|
+
readonly page?: number;
|
|
414
|
+
readonly per_page?: number;
|
|
415
|
+
readonly include_inactive?: boolean;
|
|
416
|
+
}
|
|
417
|
+
interface ListSchemasResponse {
|
|
418
|
+
readonly data: VerticalSchema[];
|
|
419
|
+
readonly pagination: {
|
|
420
|
+
readonly total: number;
|
|
421
|
+
readonly page: number;
|
|
422
|
+
readonly perPage: number;
|
|
423
|
+
readonly totalPages: number;
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
interface SchemaValidationResult {
|
|
427
|
+
readonly valid: boolean;
|
|
428
|
+
readonly errors: Array<{
|
|
429
|
+
field: string;
|
|
430
|
+
message: string;
|
|
431
|
+
received?: string;
|
|
432
|
+
}>;
|
|
433
|
+
}
|
|
434
|
+
declare class SchemasResource {
|
|
435
|
+
private readonly request;
|
|
436
|
+
constructor(request: RequestFn);
|
|
437
|
+
/**
|
|
438
|
+
* Register or update a vertical config schema.
|
|
439
|
+
* If a schema already exists for the verticalId, it will be updated.
|
|
440
|
+
*/
|
|
441
|
+
create(params: CreateSchemaParams): Promise<VerticalSchema>;
|
|
442
|
+
/**
|
|
443
|
+
* List registered vertical schemas with pagination.
|
|
444
|
+
*/
|
|
445
|
+
list(params?: ListSchemasParams): Promise<ListSchemasResponse>;
|
|
446
|
+
/**
|
|
447
|
+
* Get the active schema for a specific vertical.
|
|
448
|
+
*/
|
|
449
|
+
get(verticalId: string): Promise<VerticalSchema>;
|
|
450
|
+
/**
|
|
451
|
+
* Update an existing vertical schema.
|
|
452
|
+
*/
|
|
453
|
+
update(verticalId: string, params: UpdateSchemaParams): Promise<VerticalSchema>;
|
|
454
|
+
/**
|
|
455
|
+
* Deactivate a vertical schema (soft delete).
|
|
456
|
+
*/
|
|
457
|
+
delete(verticalId: string): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Pre-flight validation: check if assetConfig matches the registered schema.
|
|
460
|
+
*
|
|
461
|
+
* This is a client-side convenience that fetches the schema and validates locally.
|
|
462
|
+
* The server also validates on asset creation.
|
|
463
|
+
*/
|
|
464
|
+
validate(verticalId: string, assetConfig: Record<string, unknown>): Promise<SchemaValidationResult>;
|
|
465
|
+
private buildQuery;
|
|
466
|
+
private stripUndefined;
|
|
467
|
+
}
|
|
468
|
+
|
|
241
469
|
/**
|
|
242
470
|
* optropic - OptropicClient
|
|
243
471
|
*
|
|
@@ -281,8 +509,11 @@ declare class OptropicClient {
|
|
|
281
509
|
private readonly retryConfig;
|
|
282
510
|
private readonly _sandbox;
|
|
283
511
|
readonly assets: AssetsResource;
|
|
512
|
+
readonly audit: AuditResource;
|
|
513
|
+
readonly compliance: ComplianceResource;
|
|
284
514
|
readonly keys: KeysResource;
|
|
285
515
|
readonly keysets: KeysetsResource;
|
|
516
|
+
readonly schemas: SchemasResource;
|
|
286
517
|
constructor(config: OptropicConfig);
|
|
287
518
|
/** True when the client is in sandbox mode (test API key or explicit override). */
|
|
288
519
|
get isSandbox(): boolean;
|
|
@@ -614,4 +845,4 @@ declare class ServiceUnavailableError extends OptropicError {
|
|
|
614
845
|
|
|
615
846
|
declare const SDK_VERSION = "2.0.0";
|
|
616
847
|
|
|
617
|
-
export { type ApiKey, type Asset, AssetsResource, AuthenticationError, type BatchCreateParams, type BatchCreateResult, BatchNotFoundError, CodeNotFoundError, type CreateAssetParams, type CreateKeyParams, type CreateKeyResult, type CreateKeysetParams, type ErrorCode, InvalidCodeError, InvalidGTINError, InvalidSerialError, KeysResource, type Keyset, KeysetsResource, type ListAssetsParams, type ListAssetsResponse, type ListKeysetsParams, type ListKeysetsResponse, NetworkError, OptropicClient, type OptropicConfig, OptropicError, QuotaExceededError, RateLimitedError, type RequestFn, type RetryConfig, RevokedCodeError, SDK_VERSION, ServiceUnavailableError, TimeoutError, type VerifyResult, type WebhookVerifyOptions, type WebhookVerifyResult, createClient, verifyWebhookSignature };
|
|
848
|
+
export { type ApiKey, type Asset, AssetsResource, type AuditEvent, AuditResource, AuthenticationError, type BatchCreateParams, type BatchCreateResult, BatchNotFoundError, type ChainVerifyResult, CodeNotFoundError, type ComplianceConfig, ComplianceResource, type CreateAssetParams, type CreateAuditEventParams, type CreateKeyParams, type CreateKeyResult, type CreateKeysetParams, type CreateSchemaParams, type ErrorCode, type ExportParams, type ExportResult, InvalidCodeError, InvalidGTINError, InvalidSerialError, KeysResource, type Keyset, KeysetsResource, type ListAssetsParams, type ListAssetsResponse, type ListAuditParams, type ListAuditResponse, type ListKeysetsParams, type ListKeysetsResponse, type ListSchemasParams, type ListSchemasResponse, type MerkleProof, type MerkleRoot, NetworkError, OptropicClient, type OptropicConfig, OptropicError, QuotaExceededError, RateLimitedError, type RequestFn, type RetryConfig, RevokedCodeError, SDK_VERSION, type SchemaValidationResult, SchemasResource, ServiceUnavailableError, TimeoutError, type UpdateSchemaParams, type VerifyResult, type VerticalSchema, type WebhookVerifyOptions, type WebhookVerifyResult, createClient, verifyWebhookSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -166,6 +166,144 @@ declare class AssetsResource {
|
|
|
166
166
|
private buildQuery;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Audit Resource
|
|
171
|
+
*
|
|
172
|
+
* Immutable audit log operations — list, get, and create custom audit events.
|
|
173
|
+
* Mirrors the Python SDK's `optropic.resources.audit` module.
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
interface AuditEvent {
|
|
177
|
+
readonly id: string;
|
|
178
|
+
readonly tenantId: string;
|
|
179
|
+
readonly eventType: string;
|
|
180
|
+
readonly actor: string;
|
|
181
|
+
readonly createdAt: string;
|
|
182
|
+
readonly resourceId?: string;
|
|
183
|
+
readonly resourceType?: string;
|
|
184
|
+
readonly details?: Record<string, unknown>;
|
|
185
|
+
readonly eventHash?: string;
|
|
186
|
+
readonly chainSequence?: number;
|
|
187
|
+
}
|
|
188
|
+
interface ListAuditParams {
|
|
189
|
+
readonly page?: number;
|
|
190
|
+
readonly limit?: number;
|
|
191
|
+
readonly event_type?: string;
|
|
192
|
+
readonly resource_id?: string;
|
|
193
|
+
readonly from_date?: string;
|
|
194
|
+
readonly to_date?: string;
|
|
195
|
+
}
|
|
196
|
+
interface ListAuditResponse {
|
|
197
|
+
readonly data: AuditEvent[];
|
|
198
|
+
readonly pagination: {
|
|
199
|
+
readonly total: number;
|
|
200
|
+
readonly page: number;
|
|
201
|
+
readonly perPage: number;
|
|
202
|
+
readonly totalPages: number;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
interface CreateAuditEventParams {
|
|
206
|
+
readonly eventType: string;
|
|
207
|
+
readonly resourceId?: string;
|
|
208
|
+
readonly resourceType?: string;
|
|
209
|
+
readonly details?: Record<string, unknown>;
|
|
210
|
+
}
|
|
211
|
+
declare class AuditResource {
|
|
212
|
+
private readonly request;
|
|
213
|
+
constructor(request: RequestFn);
|
|
214
|
+
/**
|
|
215
|
+
* List audit events with optional filtering and pagination.
|
|
216
|
+
*/
|
|
217
|
+
list(params?: ListAuditParams): Promise<ListAuditResponse>;
|
|
218
|
+
/**
|
|
219
|
+
* Retrieve a single audit event by ID.
|
|
220
|
+
*/
|
|
221
|
+
get(eventId: string): Promise<AuditEvent>;
|
|
222
|
+
/**
|
|
223
|
+
* Record a custom audit event.
|
|
224
|
+
*/
|
|
225
|
+
create(params: CreateAuditEventParams): Promise<AuditEvent>;
|
|
226
|
+
private buildQuery;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Compliance Resource
|
|
231
|
+
*
|
|
232
|
+
* Chain verification, Merkle proofs, audit export, and compliance configuration.
|
|
233
|
+
* Mirrors the Python SDK's `optropic.resources.compliance` module.
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
interface ChainVerifyResult {
|
|
237
|
+
readonly tenantId: string;
|
|
238
|
+
readonly chainValid: boolean;
|
|
239
|
+
readonly eventsChecked: number;
|
|
240
|
+
readonly verifiedAt: string;
|
|
241
|
+
readonly brokenAtSequence?: number;
|
|
242
|
+
}
|
|
243
|
+
interface MerkleRoot {
|
|
244
|
+
readonly id: string;
|
|
245
|
+
readonly rootHash: string;
|
|
246
|
+
readonly eventCount: number;
|
|
247
|
+
readonly periodStart: string;
|
|
248
|
+
readonly periodEnd: string;
|
|
249
|
+
readonly createdAt: string;
|
|
250
|
+
}
|
|
251
|
+
interface MerkleProof {
|
|
252
|
+
readonly eventId: string;
|
|
253
|
+
readonly eventHash: string;
|
|
254
|
+
readonly merkleRoot: string;
|
|
255
|
+
readonly proof: string[];
|
|
256
|
+
readonly verified: boolean;
|
|
257
|
+
readonly period: string;
|
|
258
|
+
}
|
|
259
|
+
interface ExportParams {
|
|
260
|
+
readonly from_date?: string;
|
|
261
|
+
readonly to_date?: string;
|
|
262
|
+
readonly limit?: number;
|
|
263
|
+
}
|
|
264
|
+
interface ExportResult {
|
|
265
|
+
readonly filename: string;
|
|
266
|
+
readonly eventCount: number;
|
|
267
|
+
readonly csv: string;
|
|
268
|
+
readonly signature?: string;
|
|
269
|
+
readonly publicKeyHex?: string;
|
|
270
|
+
readonly keyId?: string;
|
|
271
|
+
readonly algorithm?: string;
|
|
272
|
+
}
|
|
273
|
+
interface ComplianceConfig {
|
|
274
|
+
readonly complianceMode: string;
|
|
275
|
+
readonly retentionPolicy: Record<string, unknown>;
|
|
276
|
+
}
|
|
277
|
+
declare class ComplianceResource {
|
|
278
|
+
private readonly request;
|
|
279
|
+
constructor(request: RequestFn);
|
|
280
|
+
/**
|
|
281
|
+
* Verify the integrity of the full audit chain.
|
|
282
|
+
*/
|
|
283
|
+
verifyChain(): Promise<ChainVerifyResult>;
|
|
284
|
+
/**
|
|
285
|
+
* Return all Merkle roots.
|
|
286
|
+
*/
|
|
287
|
+
listMerkleRoots(): Promise<MerkleRoot[]>;
|
|
288
|
+
/**
|
|
289
|
+
* Return a Merkle inclusion proof for a specific audit event.
|
|
290
|
+
*/
|
|
291
|
+
getMerkleProof(eventId: string): Promise<MerkleProof>;
|
|
292
|
+
/**
|
|
293
|
+
* Export audit data as a signed CSV.
|
|
294
|
+
*/
|
|
295
|
+
exportAudit(params?: ExportParams): Promise<ExportResult>;
|
|
296
|
+
/**
|
|
297
|
+
* Retrieve the current compliance configuration.
|
|
298
|
+
*/
|
|
299
|
+
getConfig(): Promise<ComplianceConfig>;
|
|
300
|
+
/**
|
|
301
|
+
* Update the compliance mode.
|
|
302
|
+
*/
|
|
303
|
+
updateConfig(mode: string): Promise<ComplianceConfig>;
|
|
304
|
+
private buildQuery;
|
|
305
|
+
}
|
|
306
|
+
|
|
169
307
|
/**
|
|
170
308
|
* Keys Resource
|
|
171
309
|
*
|
|
@@ -238,6 +376,96 @@ declare class KeysetsResource {
|
|
|
238
376
|
private buildQuery;
|
|
239
377
|
}
|
|
240
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Schemas Resource
|
|
381
|
+
*
|
|
382
|
+
* Schema Registry operations — register and manage vertical config schemas.
|
|
383
|
+
* Mirrors the Python SDK's `optropic.resources.schemas` module.
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
interface VerticalSchema {
|
|
387
|
+
readonly id: string;
|
|
388
|
+
readonly tenantId: string;
|
|
389
|
+
readonly verticalId: string;
|
|
390
|
+
readonly version: string;
|
|
391
|
+
readonly metadataSchema: Record<string, unknown>;
|
|
392
|
+
readonly exportFormats: string[];
|
|
393
|
+
readonly isActive: boolean;
|
|
394
|
+
readonly createdAt: string;
|
|
395
|
+
readonly updatedAt: string;
|
|
396
|
+
readonly description?: string;
|
|
397
|
+
}
|
|
398
|
+
interface CreateSchemaParams {
|
|
399
|
+
readonly verticalId: string;
|
|
400
|
+
readonly metadataSchema: Record<string, unknown>;
|
|
401
|
+
readonly version?: string;
|
|
402
|
+
readonly exportFormats?: string[];
|
|
403
|
+
readonly description?: string;
|
|
404
|
+
}
|
|
405
|
+
interface UpdateSchemaParams {
|
|
406
|
+
readonly version?: string;
|
|
407
|
+
readonly metadataSchema?: Record<string, unknown>;
|
|
408
|
+
readonly exportFormats?: string[];
|
|
409
|
+
readonly description?: string;
|
|
410
|
+
readonly isActive?: boolean;
|
|
411
|
+
}
|
|
412
|
+
interface ListSchemasParams {
|
|
413
|
+
readonly page?: number;
|
|
414
|
+
readonly per_page?: number;
|
|
415
|
+
readonly include_inactive?: boolean;
|
|
416
|
+
}
|
|
417
|
+
interface ListSchemasResponse {
|
|
418
|
+
readonly data: VerticalSchema[];
|
|
419
|
+
readonly pagination: {
|
|
420
|
+
readonly total: number;
|
|
421
|
+
readonly page: number;
|
|
422
|
+
readonly perPage: number;
|
|
423
|
+
readonly totalPages: number;
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
interface SchemaValidationResult {
|
|
427
|
+
readonly valid: boolean;
|
|
428
|
+
readonly errors: Array<{
|
|
429
|
+
field: string;
|
|
430
|
+
message: string;
|
|
431
|
+
received?: string;
|
|
432
|
+
}>;
|
|
433
|
+
}
|
|
434
|
+
declare class SchemasResource {
|
|
435
|
+
private readonly request;
|
|
436
|
+
constructor(request: RequestFn);
|
|
437
|
+
/**
|
|
438
|
+
* Register or update a vertical config schema.
|
|
439
|
+
* If a schema already exists for the verticalId, it will be updated.
|
|
440
|
+
*/
|
|
441
|
+
create(params: CreateSchemaParams): Promise<VerticalSchema>;
|
|
442
|
+
/**
|
|
443
|
+
* List registered vertical schemas with pagination.
|
|
444
|
+
*/
|
|
445
|
+
list(params?: ListSchemasParams): Promise<ListSchemasResponse>;
|
|
446
|
+
/**
|
|
447
|
+
* Get the active schema for a specific vertical.
|
|
448
|
+
*/
|
|
449
|
+
get(verticalId: string): Promise<VerticalSchema>;
|
|
450
|
+
/**
|
|
451
|
+
* Update an existing vertical schema.
|
|
452
|
+
*/
|
|
453
|
+
update(verticalId: string, params: UpdateSchemaParams): Promise<VerticalSchema>;
|
|
454
|
+
/**
|
|
455
|
+
* Deactivate a vertical schema (soft delete).
|
|
456
|
+
*/
|
|
457
|
+
delete(verticalId: string): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Pre-flight validation: check if assetConfig matches the registered schema.
|
|
460
|
+
*
|
|
461
|
+
* This is a client-side convenience that fetches the schema and validates locally.
|
|
462
|
+
* The server also validates on asset creation.
|
|
463
|
+
*/
|
|
464
|
+
validate(verticalId: string, assetConfig: Record<string, unknown>): Promise<SchemaValidationResult>;
|
|
465
|
+
private buildQuery;
|
|
466
|
+
private stripUndefined;
|
|
467
|
+
}
|
|
468
|
+
|
|
241
469
|
/**
|
|
242
470
|
* optropic - OptropicClient
|
|
243
471
|
*
|
|
@@ -281,8 +509,11 @@ declare class OptropicClient {
|
|
|
281
509
|
private readonly retryConfig;
|
|
282
510
|
private readonly _sandbox;
|
|
283
511
|
readonly assets: AssetsResource;
|
|
512
|
+
readonly audit: AuditResource;
|
|
513
|
+
readonly compliance: ComplianceResource;
|
|
284
514
|
readonly keys: KeysResource;
|
|
285
515
|
readonly keysets: KeysetsResource;
|
|
516
|
+
readonly schemas: SchemasResource;
|
|
286
517
|
constructor(config: OptropicConfig);
|
|
287
518
|
/** True when the client is in sandbox mode (test API key or explicit override). */
|
|
288
519
|
get isSandbox(): boolean;
|
|
@@ -614,4 +845,4 @@ declare class ServiceUnavailableError extends OptropicError {
|
|
|
614
845
|
|
|
615
846
|
declare const SDK_VERSION = "2.0.0";
|
|
616
847
|
|
|
617
|
-
export { type ApiKey, type Asset, AssetsResource, AuthenticationError, type BatchCreateParams, type BatchCreateResult, BatchNotFoundError, CodeNotFoundError, type CreateAssetParams, type CreateKeyParams, type CreateKeyResult, type CreateKeysetParams, type ErrorCode, InvalidCodeError, InvalidGTINError, InvalidSerialError, KeysResource, type Keyset, KeysetsResource, type ListAssetsParams, type ListAssetsResponse, type ListKeysetsParams, type ListKeysetsResponse, NetworkError, OptropicClient, type OptropicConfig, OptropicError, QuotaExceededError, RateLimitedError, type RequestFn, type RetryConfig, RevokedCodeError, SDK_VERSION, ServiceUnavailableError, TimeoutError, type VerifyResult, type WebhookVerifyOptions, type WebhookVerifyResult, createClient, verifyWebhookSignature };
|
|
848
|
+
export { type ApiKey, type Asset, AssetsResource, type AuditEvent, AuditResource, AuthenticationError, type BatchCreateParams, type BatchCreateResult, BatchNotFoundError, type ChainVerifyResult, CodeNotFoundError, type ComplianceConfig, ComplianceResource, type CreateAssetParams, type CreateAuditEventParams, type CreateKeyParams, type CreateKeyResult, type CreateKeysetParams, type CreateSchemaParams, type ErrorCode, type ExportParams, type ExportResult, InvalidCodeError, InvalidGTINError, InvalidSerialError, KeysResource, type Keyset, KeysetsResource, type ListAssetsParams, type ListAssetsResponse, type ListAuditParams, type ListAuditResponse, type ListKeysetsParams, type ListKeysetsResponse, type ListSchemasParams, type ListSchemasResponse, type MerkleProof, type MerkleRoot, NetworkError, OptropicClient, type OptropicConfig, OptropicError, QuotaExceededError, RateLimitedError, type RequestFn, type RetryConfig, RevokedCodeError, SDK_VERSION, type SchemaValidationResult, SchemasResource, ServiceUnavailableError, TimeoutError, type UpdateSchemaParams, type VerifyResult, type VerticalSchema, type WebhookVerifyOptions, type WebhookVerifyResult, createClient, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -427,6 +427,117 @@ var AssetsResource = class {
|
|
|
427
427
|
}
|
|
428
428
|
};
|
|
429
429
|
|
|
430
|
+
// src/resources/audit.ts
|
|
431
|
+
var AuditResource = class {
|
|
432
|
+
constructor(request) {
|
|
433
|
+
this.request = request;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* List audit events with optional filtering and pagination.
|
|
437
|
+
*/
|
|
438
|
+
async list(params) {
|
|
439
|
+
const query = params ? this.buildQuery(params) : "";
|
|
440
|
+
return this.request({ method: "GET", path: `/v1/audit${query}` });
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Retrieve a single audit event by ID.
|
|
444
|
+
*/
|
|
445
|
+
async get(eventId) {
|
|
446
|
+
return this.request({
|
|
447
|
+
method: "GET",
|
|
448
|
+
path: `/v1/audit/${encodeURIComponent(eventId)}`
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Record a custom audit event.
|
|
453
|
+
*/
|
|
454
|
+
async create(params) {
|
|
455
|
+
return this.request({
|
|
456
|
+
method: "POST",
|
|
457
|
+
path: "/v1/audit",
|
|
458
|
+
body: {
|
|
459
|
+
event_type: params.eventType,
|
|
460
|
+
...params.resourceId !== void 0 && { resource_id: params.resourceId },
|
|
461
|
+
...params.resourceType !== void 0 && { resource_type: params.resourceType },
|
|
462
|
+
...params.details !== void 0 && { details: params.details }
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
buildQuery(params) {
|
|
467
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
468
|
+
if (entries.length === 0) return "";
|
|
469
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
// src/resources/compliance.ts
|
|
474
|
+
var ComplianceResource = class {
|
|
475
|
+
constructor(request) {
|
|
476
|
+
this.request = request;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Verify the integrity of the full audit chain.
|
|
480
|
+
*/
|
|
481
|
+
async verifyChain() {
|
|
482
|
+
return this.request({
|
|
483
|
+
method: "POST",
|
|
484
|
+
path: "/v1/compliance/verify-chain"
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Return all Merkle roots.
|
|
489
|
+
*/
|
|
490
|
+
async listMerkleRoots() {
|
|
491
|
+
return this.request({
|
|
492
|
+
method: "GET",
|
|
493
|
+
path: "/v1/compliance/merkle-roots"
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Return a Merkle inclusion proof for a specific audit event.
|
|
498
|
+
*/
|
|
499
|
+
async getMerkleProof(eventId) {
|
|
500
|
+
return this.request({
|
|
501
|
+
method: "GET",
|
|
502
|
+
path: `/v1/compliance/merkle-proof/${encodeURIComponent(eventId)}`
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Export audit data as a signed CSV.
|
|
507
|
+
*/
|
|
508
|
+
async exportAudit(params) {
|
|
509
|
+
const query = params ? this.buildQuery(params) : "";
|
|
510
|
+
return this.request({
|
|
511
|
+
method: "GET",
|
|
512
|
+
path: `/v1/compliance/export${query}`
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Retrieve the current compliance configuration.
|
|
517
|
+
*/
|
|
518
|
+
async getConfig() {
|
|
519
|
+
return this.request({
|
|
520
|
+
method: "GET",
|
|
521
|
+
path: "/v1/compliance/config"
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Update the compliance mode.
|
|
526
|
+
*/
|
|
527
|
+
async updateConfig(mode) {
|
|
528
|
+
return this.request({
|
|
529
|
+
method: "POST",
|
|
530
|
+
path: "/v1/compliance/config",
|
|
531
|
+
body: { compliance_mode: mode }
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
buildQuery(params) {
|
|
535
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
536
|
+
if (entries.length === 0) return "";
|
|
537
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
430
541
|
// src/resources/keys.ts
|
|
431
542
|
var KeysResource = class {
|
|
432
543
|
constructor(request) {
|
|
@@ -463,6 +574,130 @@ var KeysetsResource = class {
|
|
|
463
574
|
}
|
|
464
575
|
};
|
|
465
576
|
|
|
577
|
+
// src/resources/schemas.ts
|
|
578
|
+
function checkType(value, expected) {
|
|
579
|
+
switch (expected) {
|
|
580
|
+
case "string":
|
|
581
|
+
return typeof value === "string";
|
|
582
|
+
case "number":
|
|
583
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
584
|
+
case "boolean":
|
|
585
|
+
return typeof value === "boolean";
|
|
586
|
+
case "date":
|
|
587
|
+
return typeof value === "string";
|
|
588
|
+
// ISO 8601 string
|
|
589
|
+
case "array":
|
|
590
|
+
return Array.isArray(value);
|
|
591
|
+
default:
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
var SchemasResource = class {
|
|
596
|
+
constructor(request) {
|
|
597
|
+
this.request = request;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Register or update a vertical config schema.
|
|
601
|
+
* If a schema already exists for the verticalId, it will be updated.
|
|
602
|
+
*/
|
|
603
|
+
async create(params) {
|
|
604
|
+
const body = this.stripUndefined({
|
|
605
|
+
vertical_id: params.verticalId,
|
|
606
|
+
metadata_schema: params.metadataSchema,
|
|
607
|
+
version: params.version,
|
|
608
|
+
export_formats: params.exportFormats,
|
|
609
|
+
description: params.description
|
|
610
|
+
});
|
|
611
|
+
return this.request({ method: "POST", path: "/v1/schemas", body });
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* List registered vertical schemas with pagination.
|
|
615
|
+
*/
|
|
616
|
+
async list(params) {
|
|
617
|
+
const query = params ? this.buildQuery(params) : "";
|
|
618
|
+
return this.request({ method: "GET", path: `/v1/schemas${query}` });
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Get the active schema for a specific vertical.
|
|
622
|
+
*/
|
|
623
|
+
async get(verticalId) {
|
|
624
|
+
return this.request({
|
|
625
|
+
method: "GET",
|
|
626
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Update an existing vertical schema.
|
|
631
|
+
*/
|
|
632
|
+
async update(verticalId, params) {
|
|
633
|
+
const body = this.stripUndefined({
|
|
634
|
+
version: params.version,
|
|
635
|
+
metadata_schema: params.metadataSchema,
|
|
636
|
+
export_formats: params.exportFormats,
|
|
637
|
+
description: params.description,
|
|
638
|
+
is_active: params.isActive
|
|
639
|
+
});
|
|
640
|
+
return this.request({
|
|
641
|
+
method: "PUT",
|
|
642
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`,
|
|
643
|
+
body
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Deactivate a vertical schema (soft delete).
|
|
648
|
+
*/
|
|
649
|
+
async delete(verticalId) {
|
|
650
|
+
await this.request({
|
|
651
|
+
method: "DELETE",
|
|
652
|
+
path: `/v1/schemas/${encodeURIComponent(verticalId)}`
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Pre-flight validation: check if assetConfig matches the registered schema.
|
|
657
|
+
*
|
|
658
|
+
* This is a client-side convenience that fetches the schema and validates locally.
|
|
659
|
+
* The server also validates on asset creation.
|
|
660
|
+
*/
|
|
661
|
+
async validate(verticalId, assetConfig) {
|
|
662
|
+
let schema;
|
|
663
|
+
try {
|
|
664
|
+
schema = await this.get(verticalId);
|
|
665
|
+
} catch {
|
|
666
|
+
return { valid: true, errors: [] };
|
|
667
|
+
}
|
|
668
|
+
const errors = [];
|
|
669
|
+
const metadataSchema = schema.metadataSchema ?? {};
|
|
670
|
+
for (const [fieldName, fieldDef] of Object.entries(metadataSchema)) {
|
|
671
|
+
if (typeof fieldDef !== "object" || fieldDef === null) continue;
|
|
672
|
+
const def = fieldDef;
|
|
673
|
+
const value = assetConfig[fieldName];
|
|
674
|
+
if (def.required && (value === void 0 || value === null || value === "")) {
|
|
675
|
+
const label = def.label ?? fieldName;
|
|
676
|
+
errors.push({ field: fieldName, message: `Required field "${label}" is missing` });
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if (value === void 0 || value === null) continue;
|
|
680
|
+
const expectedType = def.type ?? "string";
|
|
681
|
+
if (!checkType(value, expectedType)) {
|
|
682
|
+
errors.push({
|
|
683
|
+
field: fieldName,
|
|
684
|
+
message: `"${def.label ?? fieldName}" must be a ${expectedType}`,
|
|
685
|
+
received: typeof value
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return { valid: errors.length === 0, errors };
|
|
690
|
+
}
|
|
691
|
+
buildQuery(params) {
|
|
692
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
693
|
+
if (entries.length === 0) return "";
|
|
694
|
+
return "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&");
|
|
695
|
+
}
|
|
696
|
+
stripUndefined(obj) {
|
|
697
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
466
701
|
// src/client.ts
|
|
467
702
|
var DEFAULT_BASE_URL = "https://api.optropic.com";
|
|
468
703
|
var DEFAULT_TIMEOUT = 3e4;
|
|
@@ -479,8 +714,11 @@ var OptropicClient = class {
|
|
|
479
714
|
retryConfig;
|
|
480
715
|
_sandbox;
|
|
481
716
|
assets;
|
|
717
|
+
audit;
|
|
718
|
+
compliance;
|
|
482
719
|
keys;
|
|
483
720
|
keysets;
|
|
721
|
+
schemas;
|
|
484
722
|
constructor(config) {
|
|
485
723
|
if (!config.apiKey || !this.isValidApiKey(config.apiKey)) {
|
|
486
724
|
throw new AuthenticationError(
|
|
@@ -507,8 +745,11 @@ var OptropicClient = class {
|
|
|
507
745
|
};
|
|
508
746
|
const boundRequest = this.request.bind(this);
|
|
509
747
|
this.assets = new AssetsResource(boundRequest, this);
|
|
748
|
+
this.audit = new AuditResource(boundRequest);
|
|
749
|
+
this.compliance = new ComplianceResource(boundRequest);
|
|
510
750
|
this.keys = new KeysResource(boundRequest);
|
|
511
751
|
this.keysets = new KeysetsResource(boundRequest);
|
|
752
|
+
this.schemas = new SchemasResource(boundRequest);
|
|
512
753
|
}
|
|
513
754
|
// ─────────────────────────────────────────────────────────────────────────
|
|
514
755
|
// ENVIRONMENT DETECTION
|
|
@@ -703,9 +944,11 @@ async function verifyWebhookSignature(options) {
|
|
|
703
944
|
var SDK_VERSION2 = "2.0.0";
|
|
704
945
|
export {
|
|
705
946
|
AssetsResource,
|
|
947
|
+
AuditResource,
|
|
706
948
|
AuthenticationError,
|
|
707
949
|
BatchNotFoundError,
|
|
708
950
|
CodeNotFoundError,
|
|
951
|
+
ComplianceResource,
|
|
709
952
|
InvalidCodeError,
|
|
710
953
|
InvalidGTINError,
|
|
711
954
|
InvalidSerialError,
|
|
@@ -718,6 +961,7 @@ export {
|
|
|
718
961
|
RateLimitedError,
|
|
719
962
|
RevokedCodeError,
|
|
720
963
|
SDK_VERSION2 as SDK_VERSION,
|
|
964
|
+
SchemasResource,
|
|
721
965
|
ServiceUnavailableError,
|
|
722
966
|
TimeoutError,
|
|
723
967
|
createClient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "optropic",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Official Optropic SDK for TypeScript and JavaScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,7 +32,10 @@
|
|
|
32
32
|
"gtin",
|
|
33
33
|
"serialization"
|
|
34
34
|
],
|
|
35
|
-
"author":
|
|
35
|
+
"author": {
|
|
36
|
+
"name": "Virtrex GmbH",
|
|
37
|
+
"url": "https://optropic.com"
|
|
38
|
+
},
|
|
36
39
|
"license": "MIT",
|
|
37
40
|
"repository": {
|
|
38
41
|
"type": "git",
|