@uns-kit/api 2.0.45 → 2.0.46
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/LICENSE +21 -21
- package/README.md +317 -172
- package/dist/api-event-routing.d.ts +39 -0
- package/dist/api-event-routing.js +88 -0
- package/dist/api-interfaces.d.ts +185 -1
- package/dist/api-interfaces.js +311 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/parquet.d.ts +8 -0
- package/dist/parquet.js +61 -0
- package/dist/uns-api-plugin.js +9 -0
- package/dist/uns-api-proxy.d.ts +18 -8
- package/dist/uns-api-proxy.js +227 -17
- package/package.json +6 -4
package/dist/uns-api-proxy.js
CHANGED
|
@@ -31,6 +31,21 @@ const buildSwaggerPath = (base, processName, instanceName) => {
|
|
|
31
31
|
}
|
|
32
32
|
return `${baseWithProcess}/${instanceName}/swagger.json`.replace(/\/{2,}/g, "/");
|
|
33
33
|
};
|
|
34
|
+
const normalizeStringArray = (value) => Array.isArray(value)
|
|
35
|
+
? Array.from(new Set(value
|
|
36
|
+
.map((entry) => (typeof entry === "string" ? entry.trim() : ""))
|
|
37
|
+
.filter((entry) => entry.length > 0)))
|
|
38
|
+
: [];
|
|
39
|
+
const normalizePathValue = (value) => {
|
|
40
|
+
if (typeof value !== "string") {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const trimmed = value.trim();
|
|
44
|
+
if (!trimmed) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
48
|
+
};
|
|
34
49
|
export default class UnsApiProxy extends UnsProxy {
|
|
35
50
|
instanceName;
|
|
36
51
|
topicBuilder;
|
|
@@ -45,6 +60,7 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
45
60
|
startedAt;
|
|
46
61
|
statusInterval = null;
|
|
47
62
|
statusIntervalMs = 10_000;
|
|
63
|
+
dataCatalogOffers = new Map();
|
|
48
64
|
constructor(processName, instanceName, options) {
|
|
49
65
|
super();
|
|
50
66
|
this.options = options;
|
|
@@ -76,6 +92,9 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
76
92
|
setTimeout(() => this.emitStatusMetrics(), 0);
|
|
77
93
|
this.statusInterval = setInterval(() => this.emitStatusMetrics(), this.statusIntervalMs);
|
|
78
94
|
}
|
|
95
|
+
getProcessName() {
|
|
96
|
+
return this.processName;
|
|
97
|
+
}
|
|
79
98
|
/**
|
|
80
99
|
* Unregister endpoint
|
|
81
100
|
* @param topic - The API topic
|
|
@@ -138,11 +157,15 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
138
157
|
timestamp: time,
|
|
139
158
|
topic: topic,
|
|
140
159
|
attribute: attribute,
|
|
160
|
+
routeOnly: options?.routeOnly === true,
|
|
161
|
+
registryTopic: options?.registryTopic ??
|
|
162
|
+
"api-endpoints",
|
|
141
163
|
apiHost: `http://${ip}:${port}`,
|
|
142
164
|
apiEndpoint: apiPath,
|
|
143
165
|
apiMethod: "GET",
|
|
144
166
|
apiQueryParams: options.queryParams,
|
|
145
167
|
apiDescription: options?.apiDescription,
|
|
168
|
+
serviceApi: options?.serviceApi ?? null,
|
|
146
169
|
attributeType: UnsAttributeType.Api,
|
|
147
170
|
apiSwaggerEndpoint: swaggerPath,
|
|
148
171
|
asset,
|
|
@@ -383,15 +406,19 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
383
406
|
swaggerPath,
|
|
384
407
|
});
|
|
385
408
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Register a POST endpoint.
|
|
388
|
-
* @param topic - The API topic
|
|
389
|
-
* @param attribute - The attribute for the topic.
|
|
390
|
-
* @param options.apiDescription - Optional description.
|
|
391
|
-
* @param options.tags - Optional tags.
|
|
392
|
-
* @param options.requestBody - Optional request body schema for Swagger.
|
|
393
|
-
*/
|
|
394
409
|
async post(topic, asset, objectType, objectId, attribute, options) {
|
|
410
|
+
await this.registerMutationEndpoint("POST", topic, asset, objectType, objectId, attribute, options);
|
|
411
|
+
}
|
|
412
|
+
async put(topic, asset, objectType, objectId, attribute, options) {
|
|
413
|
+
await this.registerMutationEndpoint("PUT", topic, asset, objectType, objectId, attribute, options);
|
|
414
|
+
}
|
|
415
|
+
async patch(topic, asset, objectType, objectId, attribute, options) {
|
|
416
|
+
await this.registerMutationEndpoint("PATCH", topic, asset, objectType, objectId, attribute, options);
|
|
417
|
+
}
|
|
418
|
+
async delete(topic, asset, objectType, objectId, attribute, options) {
|
|
419
|
+
await this.registerMutationEndpoint("DELETE", topic, asset, objectType, objectId, attribute, options);
|
|
420
|
+
}
|
|
421
|
+
async registerMutationEndpoint(method, topic, asset, objectType, objectId, attribute, options) {
|
|
395
422
|
while (this.app.server.listening === false) {
|
|
396
423
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
397
424
|
}
|
|
@@ -399,6 +426,7 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
399
426
|
const fullPath = buildUnsRoutePath(topic, asset, objectType, objectId, attribute);
|
|
400
427
|
const apiPath = `${this.apiBasePrefix}${fullPath}`.replace(/\/{2,}/g, "/");
|
|
401
428
|
const swaggerPath = buildSwaggerPath(this.swaggerBasePrefix, this.processName, this.instanceName);
|
|
429
|
+
const methodKey = method.toLowerCase();
|
|
402
430
|
try {
|
|
403
431
|
const addressInfo = this.app.server.address();
|
|
404
432
|
let ip;
|
|
@@ -415,11 +443,15 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
415
443
|
timestamp: time,
|
|
416
444
|
topic,
|
|
417
445
|
attribute,
|
|
446
|
+
routeOnly: options?.routeOnly === true,
|
|
447
|
+
registryTopic: options?.registryTopic ??
|
|
448
|
+
"api-endpoints",
|
|
418
449
|
apiHost: `http://${ip}:${port}`,
|
|
419
450
|
apiEndpoint: apiPath,
|
|
420
|
-
apiMethod:
|
|
451
|
+
apiMethod: method,
|
|
421
452
|
apiQueryParams: [],
|
|
422
453
|
apiDescription: options?.apiDescription,
|
|
454
|
+
serviceApi: options?.serviceApi ?? null,
|
|
423
455
|
attributeType: UnsAttributeType.Api,
|
|
424
456
|
apiSwaggerEndpoint: swaggerPath,
|
|
425
457
|
asset,
|
|
@@ -427,10 +459,11 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
427
459
|
objectId,
|
|
428
460
|
});
|
|
429
461
|
const handler = (req, res) => {
|
|
430
|
-
this.event.emit(
|
|
462
|
+
this.event.emit(this.getApiEventName(method), { req, res });
|
|
431
463
|
};
|
|
464
|
+
const routerMethod = this.app.router[methodKey].bind(this.app.router);
|
|
432
465
|
if (this.options?.jwks?.wellKnownJwksUrl) {
|
|
433
|
-
|
|
466
|
+
routerMethod(fullPath, async (req, res) => {
|
|
434
467
|
try {
|
|
435
468
|
const token = this.extractBearerToken(req, res);
|
|
436
469
|
if (!token)
|
|
@@ -451,13 +484,13 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
451
484
|
}
|
|
452
485
|
handler(req, res);
|
|
453
486
|
}
|
|
454
|
-
catch (
|
|
487
|
+
catch (_err) {
|
|
455
488
|
return res.status(401).json({ error: "Invalid token" });
|
|
456
489
|
}
|
|
457
490
|
});
|
|
458
491
|
}
|
|
459
492
|
else if (this.options?.jwtSecret) {
|
|
460
|
-
|
|
493
|
+
routerMethod(fullPath, (req, res) => {
|
|
461
494
|
const authHeader = req.headers["authorization"];
|
|
462
495
|
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
463
496
|
return res.status(401).json({ error: "Missing or invalid Authorization header" });
|
|
@@ -478,19 +511,19 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
478
511
|
}
|
|
479
512
|
handler(req, res);
|
|
480
513
|
}
|
|
481
|
-
catch (
|
|
514
|
+
catch (_err) {
|
|
482
515
|
return res.status(401).json({ error: "Invalid token" });
|
|
483
516
|
}
|
|
484
517
|
});
|
|
485
518
|
}
|
|
486
519
|
else {
|
|
487
|
-
|
|
520
|
+
routerMethod(fullPath, handler);
|
|
488
521
|
}
|
|
489
522
|
if (this.app.swaggerSpec) {
|
|
490
523
|
const requestBody = options?.requestBody;
|
|
491
524
|
this.app.swaggerSpec.paths = this.app.swaggerSpec.paths || {};
|
|
492
525
|
this.app.swaggerSpec.paths[apiPath] = this.app.swaggerSpec.paths[apiPath] || {};
|
|
493
|
-
this.app.swaggerSpec.paths[apiPath]
|
|
526
|
+
this.app.swaggerSpec.paths[apiPath][methodKey] = {
|
|
494
527
|
summary: options?.apiDescription || "No description",
|
|
495
528
|
tags: options?.tags || [],
|
|
496
529
|
...(requestBody
|
|
@@ -516,9 +549,58 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
516
549
|
}
|
|
517
550
|
}
|
|
518
551
|
catch (error) {
|
|
519
|
-
logger.error(`${this.instanceNameWithSuffix} - Error registering
|
|
552
|
+
logger.error(`${this.instanceNameWithSuffix} - Error registering ${method} route ${fullPath}: ${error.message}`);
|
|
520
553
|
}
|
|
521
554
|
}
|
|
555
|
+
registerDataOffer(input) {
|
|
556
|
+
const offerId = typeof input.offerId === "string" ? input.offerId.trim() : "";
|
|
557
|
+
const displayName = typeof input.displayName === "string" ? input.displayName.trim() : "";
|
|
558
|
+
if (!offerId || !displayName) {
|
|
559
|
+
throw new Error("Data catalog offer requires non-empty offerId and displayName.");
|
|
560
|
+
}
|
|
561
|
+
const offerSchemas = (Array.isArray(input.schemas) ? input.schemas : []).map((schema) => this.normalizeDataOfferSchema(schema));
|
|
562
|
+
const offerSchemaIndex = new Map(offerSchemas.map((schema) => [schema.id, schema]));
|
|
563
|
+
const normalizedOperations = (Array.isArray(input.operations) ? input.operations : [])
|
|
564
|
+
.map((operation, index) => this.normalizeDataOfferOperation(operation, offerId, index, offerSchemaIndex))
|
|
565
|
+
.filter((operation) => Boolean(operation));
|
|
566
|
+
if (!normalizedOperations.length) {
|
|
567
|
+
throw new Error(`Data catalog offer ${offerId} requires at least one operation.`);
|
|
568
|
+
}
|
|
569
|
+
const basePaths = Array.from(new Set([
|
|
570
|
+
...(Array.isArray(input.basePaths) ? input.basePaths.map((entry) => normalizePathValue(entry)) : []),
|
|
571
|
+
...normalizedOperations.map((operation) => {
|
|
572
|
+
const segments = operation.path.split("/").filter(Boolean);
|
|
573
|
+
if (segments.length <= 1) {
|
|
574
|
+
return operation.path;
|
|
575
|
+
}
|
|
576
|
+
return `/${segments.slice(0, -1).join("/")}`;
|
|
577
|
+
}),
|
|
578
|
+
].filter((value) => Boolean(value))));
|
|
579
|
+
this.publishDataCatalogOffer({
|
|
580
|
+
offerId,
|
|
581
|
+
displayName,
|
|
582
|
+
description: typeof input.description === "string" ? input.description.trim() || null : null,
|
|
583
|
+
owner: typeof input.owner === "string" ? input.owner.trim() || null : null,
|
|
584
|
+
status: typeof input.status === "string" && input.status.trim() ? input.status.trim() : "available",
|
|
585
|
+
tags: normalizeStringArray(input.tags),
|
|
586
|
+
categories: normalizeStringArray(input.categories),
|
|
587
|
+
microserviceName: typeof input.microserviceName === "string" && input.microserviceName.trim()
|
|
588
|
+
? input.microserviceName.trim()
|
|
589
|
+
: this.processName,
|
|
590
|
+
version: typeof input.version === "string" && input.version.trim() ? input.version.trim() : packageJson.version,
|
|
591
|
+
swaggerPath: normalizePathValue(input.swaggerPath),
|
|
592
|
+
basePaths,
|
|
593
|
+
operations: normalizedOperations,
|
|
594
|
+
schemas: offerSchemas,
|
|
595
|
+
metadata: input.metadata ?? null,
|
|
596
|
+
packageName: packageJson.name,
|
|
597
|
+
processName: this.processName,
|
|
598
|
+
processVersion: packageJson.version,
|
|
599
|
+
instanceName: this.instanceName,
|
|
600
|
+
controllerName: process.env["UNS_CONTROLLER_NAME"] ?? null,
|
|
601
|
+
controllerPublicBase: process.env["UNS_CONTROLLER_PUBLIC_BASE"] ?? process.env["UNS_PUBLIC_BASE"] ?? null,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
522
604
|
emitStatusMetrics() {
|
|
523
605
|
const uptimeMinutes = Math.round((Date.now() - this.startedAt) / 60000);
|
|
524
606
|
// Process-level status
|
|
@@ -547,6 +629,7 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
547
629
|
uom: DataSizeMeasurements.Bit,
|
|
548
630
|
statusTopic: this.instanceStatusTopic + "alive",
|
|
549
631
|
});
|
|
632
|
+
this.emitDataCatalogOffers();
|
|
550
633
|
}
|
|
551
634
|
registerHealthEndpoint() {
|
|
552
635
|
const routePath = "/status";
|
|
@@ -575,6 +658,20 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
575
658
|
};
|
|
576
659
|
}
|
|
577
660
|
}
|
|
661
|
+
getApiEventName(method) {
|
|
662
|
+
switch (method) {
|
|
663
|
+
case "GET":
|
|
664
|
+
return "apiGetEvent";
|
|
665
|
+
case "POST":
|
|
666
|
+
return "apiPostEvent";
|
|
667
|
+
case "PUT":
|
|
668
|
+
return "apiPutEvent";
|
|
669
|
+
case "PATCH":
|
|
670
|
+
return "apiPatchEvent";
|
|
671
|
+
case "DELETE":
|
|
672
|
+
return "apiDeleteEvent";
|
|
673
|
+
}
|
|
674
|
+
}
|
|
578
675
|
extractBearerToken(req, res) {
|
|
579
676
|
const authHeader = req.headers["authorization"];
|
|
580
677
|
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
@@ -647,4 +744,117 @@ export default class UnsApiProxy extends UnsProxy {
|
|
|
647
744
|
}
|
|
648
745
|
await super.stop();
|
|
649
746
|
}
|
|
747
|
+
publishDataCatalogOffer(offer) {
|
|
748
|
+
const offerId = typeof offer.offerId === "string" ? offer.offerId.trim() : "";
|
|
749
|
+
if (!offerId) {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
this.dataCatalogOffers.set(offerId, offer);
|
|
753
|
+
this.emitDataCatalogOffers();
|
|
754
|
+
logger.info(`${this.instanceNameWithSuffix} - Registered data catalog offer: ${offerId}`);
|
|
755
|
+
}
|
|
756
|
+
emitDataCatalogOffers() {
|
|
757
|
+
if (this.instanceStatusTopic === "" || this.dataCatalogOffers.size === 0) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
this.event.emit("unsProxyProducedDataCatalogOffers", {
|
|
761
|
+
producedDataCatalogOffers: [...this.dataCatalogOffers.values()],
|
|
762
|
+
statusTopic: this.instanceStatusTopic + "data-catalog-offers",
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
normalizeDataOfferOperation(operation, offerId, index, offerSchemaIndex) {
|
|
766
|
+
const method = typeof operation.method === "string" ? operation.method.trim().toUpperCase() : "";
|
|
767
|
+
const path = normalizePathValue(operation.path);
|
|
768
|
+
if (!method || !path) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
return {
|
|
772
|
+
id: typeof operation.id === "string" && operation.id.trim() ? operation.id.trim() : `${offerId}-${method.toLowerCase()}-${index + 1}`,
|
|
773
|
+
method,
|
|
774
|
+
path,
|
|
775
|
+
summary: typeof operation.summary === "string" ? operation.summary.trim() || null : null,
|
|
776
|
+
description: typeof operation.description === "string" ? operation.description.trim() || null : null,
|
|
777
|
+
tags: normalizeStringArray(operation.tags),
|
|
778
|
+
deprecated: operation.deprecated === true,
|
|
779
|
+
parameters: (Array.isArray(operation.parameters) ? operation.parameters : []).map((parameter) => this.normalizeDataOfferParameter(parameter)),
|
|
780
|
+
headers: (Array.isArray(operation.headers) ? operation.headers : []).map((parameter) => this.normalizeDataOfferParameter(parameter)),
|
|
781
|
+
requestBody: operation.requestBody ? this.normalizeDataOfferRequestBody(operation.requestBody, offerSchemaIndex) : null,
|
|
782
|
+
responses: (Array.isArray(operation.responses) ? operation.responses : []).map((response) => this.normalizeDataOfferResponse(response, offerSchemaIndex)),
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
normalizeDataOfferParameter(parameter) {
|
|
786
|
+
return {
|
|
787
|
+
name: typeof parameter.name === "string" ? parameter.name.trim() : "",
|
|
788
|
+
in: typeof parameter.in === "string" ? parameter.in.trim() : "query",
|
|
789
|
+
required: parameter.required === true,
|
|
790
|
+
description: typeof parameter.description === "string" ? parameter.description.trim() || null : null,
|
|
791
|
+
type: typeof parameter.type === "string" && parameter.type.trim() ? parameter.type.trim() : "string",
|
|
792
|
+
format: typeof parameter.format === "string" ? parameter.format.trim() || null : null,
|
|
793
|
+
nullable: parameter.nullable === true,
|
|
794
|
+
example: parameter.example ?? null,
|
|
795
|
+
enumValues: normalizeStringArray(parameter.enumValues),
|
|
796
|
+
schema: parameter.schema ?? null,
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
normalizeDataOfferRequestBody(requestBody, offerSchemaIndex) {
|
|
800
|
+
return {
|
|
801
|
+
required: requestBody.required === true,
|
|
802
|
+
description: typeof requestBody.description === "string" ? requestBody.description.trim() || null : null,
|
|
803
|
+
contentType: typeof requestBody.contentType === "string" ? requestBody.contentType.trim() || null : null,
|
|
804
|
+
schemas: this.resolveOfferSchemas(requestBody.schemas, requestBody.schemaIds, offerSchemaIndex),
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
normalizeDataOfferResponse(response, offerSchemaIndex) {
|
|
808
|
+
return {
|
|
809
|
+
statusCode: typeof response.statusCode === "string" ? response.statusCode.trim() : "",
|
|
810
|
+
description: typeof response.description === "string" ? response.description.trim() || null : null,
|
|
811
|
+
contentType: typeof response.contentType === "string" ? response.contentType.trim() || null : null,
|
|
812
|
+
schemas: this.resolveOfferSchemas(response.schemas, response.schemaIds, offerSchemaIndex),
|
|
813
|
+
examplePayloads: Array.isArray(response.examplePayloads) ? response.examplePayloads : [],
|
|
814
|
+
headers: (Array.isArray(response.headers) ? response.headers : []).map((parameter) => this.normalizeDataOfferParameter(parameter)),
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
normalizeDataOfferSchema(schema) {
|
|
818
|
+
return {
|
|
819
|
+
id: typeof schema.id === "string" ? schema.id.trim() : "",
|
|
820
|
+
title: typeof schema.title === "string" ? schema.title.trim() : "",
|
|
821
|
+
kind: typeof schema.kind === "string" && schema.kind.trim() ? schema.kind.trim() : "schema",
|
|
822
|
+
source: typeof schema.source === "string" && schema.source.trim() ? schema.source.trim() : "registered",
|
|
823
|
+
contentType: typeof schema.contentType === "string" ? schema.contentType.trim() || null : null,
|
|
824
|
+
rootType: typeof schema.rootType === "string" && schema.rootType.trim() ? schema.rootType.trim() : "object",
|
|
825
|
+
nullable: schema.nullable === true,
|
|
826
|
+
description: typeof schema.description === "string" ? schema.description.trim() || null : null,
|
|
827
|
+
fields: (Array.isArray(schema.fields) ? schema.fields : []).map((field) => this.normalizeDataOfferSchemaField(field)),
|
|
828
|
+
examplePayloads: Array.isArray(schema.examplePayloads) ? schema.examplePayloads : [],
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
normalizeDataOfferSchemaField(field) {
|
|
832
|
+
const defaultName = typeof field.name === "string" ? field.name.trim() : "";
|
|
833
|
+
const path = typeof field.path === "string" && field.path.trim() ? field.path.trim() : defaultName;
|
|
834
|
+
return {
|
|
835
|
+
path,
|
|
836
|
+
name: defaultName || (path.split(".").at(-1) ?? path),
|
|
837
|
+
type: typeof field.type === "string" && field.type.trim() ? field.type.trim() : "string",
|
|
838
|
+
format: typeof field.format === "string" ? field.format.trim() || null : null,
|
|
839
|
+
nullable: field.nullable === true,
|
|
840
|
+
required: field.required === true,
|
|
841
|
+
description: typeof field.description === "string" ? field.description.trim() || null : null,
|
|
842
|
+
enumValues: normalizeStringArray(field.enumValues),
|
|
843
|
+
example: field.example ?? null,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
resolveOfferSchemas(inlineSchemas, schemaIds, offerSchemaIndex) {
|
|
847
|
+
const result = (Array.isArray(inlineSchemas) ? inlineSchemas : []).map((schema) => this.normalizeDataOfferSchema(schema));
|
|
848
|
+
for (const schemaId of Array.isArray(schemaIds) ? schemaIds : []) {
|
|
849
|
+
const normalizedId = typeof schemaId === "string" ? schemaId.trim() : "";
|
|
850
|
+
if (!normalizedId) {
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
const resolved = offerSchemaIndex.get(normalizedId);
|
|
854
|
+
if (resolved && !result.some((schema) => schema.id === resolved.id)) {
|
|
855
|
+
result.push(resolved);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return result;
|
|
859
|
+
}
|
|
650
860
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uns-kit/api",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.46",
|
|
4
4
|
"description": "Express-powered API gateway plugin for UnsProxyProcess with JWT/JWKS support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,16 +31,18 @@
|
|
|
31
31
|
"main": "dist/index.js",
|
|
32
32
|
"types": "dist/index.d.ts",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"jsonwebtoken": "^9.0.2",
|
|
35
34
|
"cookie-parser": "^1.4.7",
|
|
36
35
|
"express": "^5.1.0",
|
|
36
|
+
"jsonwebtoken": "^9.0.2",
|
|
37
37
|
"multer": "^2.0.2",
|
|
38
|
-
"
|
|
38
|
+
"parquets": "^0.10.10",
|
|
39
|
+
"uuid": "^14.0.0",
|
|
40
|
+
"@uns-kit/core": "2.0.46"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
42
43
|
"@types/cookie-parser": "^1.4.9",
|
|
43
44
|
"@types/express": "^5.0.3",
|
|
45
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
44
46
|
"@types/multer": "^2.0.0"
|
|
45
47
|
},
|
|
46
48
|
"scripts": {
|