@suveren/gateway 0.33.0 → 0.34.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/content/integrations/erp.json +83 -1
- package/content/integrations/mollie.json +336 -80
- package/dist/mcp-server/http.mjs +77 -29
- package/dist/ui/assets/{index-Bev2H2zu.js → index-DKBwi4Yw.js} +26 -26
- package/dist/ui/index.html +1 -1
- package/package.json +1 -1
- package/profiles/charge/0.7.profile.json +232 -0
- package/profiles/index.json +3 -1
- package/profiles/invoicing/0.1.profile.json +259 -0
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -4316,11 +4316,45 @@ function invalidManifestContextReason(manifest) {
|
|
|
4316
4316
|
}
|
|
4317
4317
|
return null;
|
|
4318
4318
|
}
|
|
4319
|
-
function
|
|
4320
|
-
|
|
4321
|
-
|
|
4319
|
+
function overrideProfile(entry) {
|
|
4320
|
+
if (entry === null || typeof entry !== "object") return void 0;
|
|
4321
|
+
const p = entry.profile;
|
|
4322
|
+
return typeof p === "string" ? p : void 0;
|
|
4323
|
+
}
|
|
4324
|
+
function distinctProfilesOf(manifest) {
|
|
4325
|
+
const out = [manifest.profile];
|
|
4326
|
+
for (const entry of Object.values(manifest.toolGating?.overrides ?? {})) {
|
|
4327
|
+
const p = overrideProfile(entry);
|
|
4328
|
+
if (p && !out.includes(p)) out.push(p);
|
|
4329
|
+
}
|
|
4330
|
+
return out;
|
|
4331
|
+
}
|
|
4332
|
+
function invalidManifestOverrideProfilesReason(manifest) {
|
|
4322
4333
|
const overrides = manifest.toolGating?.overrides ?? {};
|
|
4323
|
-
|
|
4334
|
+
for (const [toolName, entry] of Object.entries(overrides)) {
|
|
4335
|
+
const profile = overrideProfile(entry);
|
|
4336
|
+
if (!profile) continue;
|
|
4337
|
+
if (!getProfile2(manifest.profile) && !getProfile2(profile)) continue;
|
|
4338
|
+
if (!getProfile2(profile)) {
|
|
4339
|
+
return `override "${toolName}".profile "${profile}" does not resolve to a known profile (full id or short name) \u2014 area-per-tool overrides must name a real profile, same as the manifest's own "profile"`;
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
return null;
|
|
4343
|
+
}
|
|
4344
|
+
function invalidManifestReadGateReason(manifest) {
|
|
4345
|
+
const allOverrides = manifest.toolGating?.overrides ?? {};
|
|
4346
|
+
for (const profileId of distinctProfilesOf(manifest)) {
|
|
4347
|
+
const profileDef = getProfile2(profileId);
|
|
4348
|
+
if (!profileDef) continue;
|
|
4349
|
+
const ownOverrides = {};
|
|
4350
|
+
for (const [toolName, entry] of Object.entries(allOverrides)) {
|
|
4351
|
+
const resolved = overrideProfile(entry) ?? manifest.profile;
|
|
4352
|
+
if (resolved === profileId) ownOverrides[toolName] = entry;
|
|
4353
|
+
}
|
|
4354
|
+
const reason = uncoveredReadSwitchReason(ownOverrides, profileDef.boundsSchema);
|
|
4355
|
+
if (reason) return reason;
|
|
4356
|
+
}
|
|
4357
|
+
return null;
|
|
4324
4358
|
}
|
|
4325
4359
|
var manifests = /* @__PURE__ */ new Map();
|
|
4326
4360
|
function loadManifests(integrationsDir) {
|
|
@@ -4359,6 +4393,11 @@ function loadManifests(integrationsDir) {
|
|
|
4359
4393
|
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${contextReason}`);
|
|
4360
4394
|
continue;
|
|
4361
4395
|
}
|
|
4396
|
+
const overrideProfilesReason = invalidManifestOverrideProfilesReason(manifest);
|
|
4397
|
+
if (overrideProfilesReason) {
|
|
4398
|
+
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${overrideProfilesReason}`);
|
|
4399
|
+
continue;
|
|
4400
|
+
}
|
|
4362
4401
|
const readGateReason = invalidManifestReadGateReason(manifest);
|
|
4363
4402
|
if (readGateReason) {
|
|
4364
4403
|
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${readGateReason}`);
|
|
@@ -6716,29 +6755,30 @@ function listIntegrationsHandler(state2, integrationManager2) {
|
|
|
6716
6755
|
}
|
|
6717
6756
|
const auths = state2.getEnrichedAuthorizations();
|
|
6718
6757
|
const statuses = integrationManager2.getStatus();
|
|
6719
|
-
const integrations = statuses.filter((s) => s.running).
|
|
6758
|
+
const integrations = statuses.filter((s) => s.running).flatMap((s) => {
|
|
6720
6759
|
const tools = integrationManager2.getAllTools().filter((t) => t.integrationId === s.id);
|
|
6721
|
-
const
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6760
|
+
const profiles = [...new Set(tools.map((t) => t.gating?.profile).filter((p) => !!p))];
|
|
6761
|
+
if (profiles.length === 0) {
|
|
6762
|
+
return [{ id: s.id, profile: null, status: "no authorization" }];
|
|
6763
|
+
}
|
|
6764
|
+
return profiles.map((profile) => {
|
|
6765
|
+
const matchingAuths = auths.filter((a) => a.complete && profileMatches(a.profileId, profile));
|
|
6766
|
+
let status;
|
|
6767
|
+
if (matchingAuths.length > 0) {
|
|
6768
|
+
const soonestExpiry = Math.min(
|
|
6769
|
+
...matchingAuths.flatMap(
|
|
6770
|
+
(a) => a.attestations.map((att) => att.expiresAt)
|
|
6771
|
+
)
|
|
6772
|
+
);
|
|
6773
|
+
const remainingMs = soonestExpiry * 1e3 - Date.now();
|
|
6774
|
+
const remainingMin = Math.ceil(remainingMs / 6e4);
|
|
6775
|
+
status = `authorized (${matchingAuths.length} path${matchingAuths.length > 1 ? "s" : ""}, ${remainingMin} min remaining)`;
|
|
6776
|
+
} else {
|
|
6777
|
+
const allProfileAuths = auths.filter((a) => profileMatches(a.profileId, profile));
|
|
6778
|
+
status = allProfileAuths.length > 0 ? "expired" : "no authorization";
|
|
6779
|
+
}
|
|
6780
|
+
return { id: s.id, profile: shortProfileName3(profile), status };
|
|
6781
|
+
});
|
|
6742
6782
|
});
|
|
6743
6783
|
const text = integrations.length === 0 ? "No integrations running." : integrations.map(
|
|
6744
6784
|
(i) => `${i.id} [${i.profile ?? "ungated"}] \u2014 ${i.status}`
|
|
@@ -8601,18 +8641,26 @@ var IntegrationManager = class {
|
|
|
8601
8641
|
/**
|
|
8602
8642
|
* Resolve gating config for a tool from the profile's toolGating section.
|
|
8603
8643
|
* Returns the runtime ToolGatingConfig that tool-proxy.ts consumes.
|
|
8644
|
+
*
|
|
8645
|
+
* Area per tool: an override may declare its OWN `profile`, gating that
|
|
8646
|
+
* one tool under a different area than the rest of the connector (e.g.
|
|
8647
|
+
* an ERP's `create_invoice` under `invoicing` while `create_quote` stays
|
|
8648
|
+
* under the manifest's own `sales`). `resolvedProfile` below is what every
|
|
8649
|
+
* downstream consumer reads as this tool's governing profile — falling
|
|
8650
|
+
* back to the manifest-level `profileId` when the override doesn't say.
|
|
8604
8651
|
*/
|
|
8605
8652
|
resolveToolGating(profileId, profileGating, toolName) {
|
|
8606
8653
|
if (!profileId || !profileGating) return null;
|
|
8607
8654
|
if (profileGating.overrides && toolName in profileGating.overrides) {
|
|
8608
8655
|
const override = profileGating.overrides[toolName];
|
|
8609
8656
|
const ext = override ?? {};
|
|
8657
|
+
const resolvedProfile = ext.profile ?? profileId;
|
|
8610
8658
|
if (ext.category === "disabled") {
|
|
8611
|
-
return { profile:
|
|
8659
|
+
return { profile: resolvedProfile, executionMapping: {}, category: "disabled" };
|
|
8612
8660
|
}
|
|
8613
8661
|
if (override === null || ext.category === "read") {
|
|
8614
8662
|
return {
|
|
8615
|
-
profile:
|
|
8663
|
+
profile: resolvedProfile,
|
|
8616
8664
|
executionMapping: {},
|
|
8617
8665
|
category: "read",
|
|
8618
8666
|
boundField: ext.boundField,
|
|
@@ -8627,7 +8675,7 @@ var IntegrationManager = class {
|
|
|
8627
8675
|
};
|
|
8628
8676
|
}
|
|
8629
8677
|
return {
|
|
8630
|
-
profile:
|
|
8678
|
+
profile: resolvedProfile,
|
|
8631
8679
|
executionMapping: override.executionMapping,
|
|
8632
8680
|
staticExecution: override.staticExecution,
|
|
8633
8681
|
// Which argument the receipt binds to. This resolver is an explicit
|