@senticor/hive 1.80.2 → 1.82.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/hive.cjs +167 -26
- package/package.json +1 -1
package/hive.cjs
CHANGED
|
@@ -10376,22 +10376,22 @@ var artifactName = injectedString(
|
|
|
10376
10376
|
true ? "hive-cli" : void 0
|
|
10377
10377
|
) || String(process.env.HIVE_CLI_ARTIFACT_NAME || "hive-cli").trim() || "hive-cli";
|
|
10378
10378
|
var packageVersion = injectedString(
|
|
10379
|
-
true ? "1.
|
|
10379
|
+
true ? "1.82.0" : void 0
|
|
10380
10380
|
) || String(process.env.HIVE_CLI_PACKAGE_VERSION || "").trim() || readPackageVersion();
|
|
10381
10381
|
var releaseVersion = injectedString(
|
|
10382
|
-
true ? "1.
|
|
10382
|
+
true ? "1.82.0" : void 0
|
|
10383
10383
|
) || String(process.env.HIVE_CLI_RELEASE_VERSION || "").trim() || packageVersion || "dev";
|
|
10384
10384
|
var releaseChannel = injectedString(
|
|
10385
10385
|
true ? "final" : void 0
|
|
10386
10386
|
) || String(process.env.HIVE_CLI_RELEASE_CHANNEL || "").trim() || (releaseVersion.includes("-rc.") ? "rc" : releaseVersion === "dev" ? "dev" : "final");
|
|
10387
10387
|
var buildCommit = injectedString(
|
|
10388
|
-
true ? "
|
|
10388
|
+
true ? "2f846d7d534f6f999f7f38cdd33899cc544a2d4d" : void 0
|
|
10389
10389
|
) || String(process.env.HIVE_CLI_BUILD_COMMIT || "").trim() || "unknown";
|
|
10390
10390
|
var buildTimestamp = injectedString(
|
|
10391
|
-
true ? "2026-10-
|
|
10391
|
+
true ? "2026-10-28T23:24:20Z" : void 0
|
|
10392
10392
|
) || String(process.env.HIVE_CLI_BUILD_TIMESTAMP || "").trim() || "unknown";
|
|
10393
10393
|
var ociRef = injectedString(
|
|
10394
|
-
true ? "registry.onstackit.cloud/senticor/hive-cli:1.
|
|
10394
|
+
true ? "registry.onstackit.cloud/senticor/hive-cli:1.82.0" : void 0
|
|
10395
10395
|
) || String(process.env.HIVE_CLI_OCI_REF || "").trim() || `registry.onstackit.cloud/senticor/${artifactName}:${releaseVersion}`;
|
|
10396
10396
|
var RELEASE_INFO = Object.freeze({
|
|
10397
10397
|
packageVersion,
|
|
@@ -32580,6 +32580,127 @@ function canonicalPinKey(tenant) {
|
|
|
32580
32580
|
function rolesFromArgs(args) {
|
|
32581
32581
|
return [.../* @__PURE__ */ new Set([...normalizeCliList(args.roles), ...normalizeCliList(args.role)])];
|
|
32582
32582
|
}
|
|
32583
|
+
async function listMembers(client, tenantId) {
|
|
32584
|
+
const res = await client.get(`/api/admin/orgs/${enc(tenantId)}/members`);
|
|
32585
|
+
ensureOk(res.status, res.data, "list tenant members");
|
|
32586
|
+
const rows = recordOf2(res.data).memberships;
|
|
32587
|
+
return (Array.isArray(rows) ? rows : []).map((row) => {
|
|
32588
|
+
const m = recordOf2(row);
|
|
32589
|
+
const principal = recordOf2(m.principal);
|
|
32590
|
+
return {
|
|
32591
|
+
membershipId: String(m.membershipId ?? ""),
|
|
32592
|
+
membershipStatus: String(m.membershipStatus ?? ""),
|
|
32593
|
+
roles: Array.isArray(m.roles) ? m.roles.map(String).sort() : [],
|
|
32594
|
+
principalId: String(principal.principalId ?? ""),
|
|
32595
|
+
email: String(principal.email ?? "").toLowerCase()
|
|
32596
|
+
};
|
|
32597
|
+
});
|
|
32598
|
+
}
|
|
32599
|
+
function findMember(members2, by) {
|
|
32600
|
+
if (by.principalId) return members2.find((m) => m.principalId === by.principalId);
|
|
32601
|
+
return members2.find((m) => m.email === by.email);
|
|
32602
|
+
}
|
|
32603
|
+
function memberSelector(args) {
|
|
32604
|
+
const principalId = String(args.principalId || "").trim();
|
|
32605
|
+
const email3 = String(args.email || "").trim().toLowerCase();
|
|
32606
|
+
if (principalId && email3) {
|
|
32607
|
+
throw commandError("CONFLICTING_ARGS", EXIT_GUARDRAIL, "Pass --principal-id or --email, not both.");
|
|
32608
|
+
}
|
|
32609
|
+
if (!principalId && !email3) {
|
|
32610
|
+
throw commandError("MEMBER_REQUIRED", 1, "Pass --email <address> or --principal-id <uuid>.");
|
|
32611
|
+
}
|
|
32612
|
+
return principalId ? { principalId } : { email: email3 };
|
|
32613
|
+
}
|
|
32614
|
+
async function requireMember(client, tenantId, args) {
|
|
32615
|
+
const by = memberSelector(args);
|
|
32616
|
+
const member = findMember(await listMembers(client, tenantId), by);
|
|
32617
|
+
if (!member) {
|
|
32618
|
+
throw commandError(
|
|
32619
|
+
"MEMBER_NOT_FOUND",
|
|
32620
|
+
1,
|
|
32621
|
+
`${by.email ?? by.principalId} is not a member of tenant ${tenantId}. Run 'hive org members list'.`
|
|
32622
|
+
);
|
|
32623
|
+
}
|
|
32624
|
+
return member;
|
|
32625
|
+
}
|
|
32626
|
+
var without = (a, b) => a.filter((x) => !b.includes(x));
|
|
32627
|
+
async function forEachRole(roles, action, call) {
|
|
32628
|
+
const done = [];
|
|
32629
|
+
for (const role of roles) {
|
|
32630
|
+
const res = await call(role);
|
|
32631
|
+
if (!isHttpOk(res.status)) {
|
|
32632
|
+
if (done.length) {
|
|
32633
|
+
throw commandError(
|
|
32634
|
+
"PARTIAL_ROLE_CHANGE",
|
|
32635
|
+
3,
|
|
32636
|
+
`${action} '${role}' failed (HTTP ${res.status}) after ${done.join(", ")} succeeded. Re-run with the remaining roles.`
|
|
32637
|
+
);
|
|
32638
|
+
}
|
|
32639
|
+
ensureOk(res.status, res.data, `${action} '${role}'`);
|
|
32640
|
+
}
|
|
32641
|
+
done.push(role);
|
|
32642
|
+
}
|
|
32643
|
+
}
|
|
32644
|
+
async function changeRoles(args, action) {
|
|
32645
|
+
printContextNotice(args, { adminScope: true });
|
|
32646
|
+
const { tenantId } = await resolveTenantId(args);
|
|
32647
|
+
const roles = rolesFromArgs(args);
|
|
32648
|
+
if (!roles.length) throw commandError("ROLE_REQUIRED", 1, "Pass --roles <role-a,role-b> or --role <role-key>.");
|
|
32649
|
+
const { client } = adminCtx(args);
|
|
32650
|
+
const before = await requireMember(client, tenantId, args);
|
|
32651
|
+
const base = `/api/admin/orgs/${enc(tenantId)}/members/${enc(before.principalId)}/roles`;
|
|
32652
|
+
await forEachRole(
|
|
32653
|
+
roles,
|
|
32654
|
+
`${action} tenant role`,
|
|
32655
|
+
(role) => action === "grant" ? client.put(base, { roleKey: role }) : client.del(`${base}/${enc(role)}`)
|
|
32656
|
+
);
|
|
32657
|
+
const after = findMember(await listMembers(client, tenantId), { principalId: before.principalId });
|
|
32658
|
+
const rolesAfter = after?.roles ?? [];
|
|
32659
|
+
const changed = action === "grant" ? without(rolesAfter, before.roles) : without(before.roles, rolesAfter);
|
|
32660
|
+
return {
|
|
32661
|
+
ok: true,
|
|
32662
|
+
tenantId,
|
|
32663
|
+
principalId: before.principalId,
|
|
32664
|
+
// The single-role answer's field, kept for scripts that read it.
|
|
32665
|
+
...roles.length === 1 ? { roleKey: roles[0] } : {},
|
|
32666
|
+
roles,
|
|
32667
|
+
rolesBefore: before.roles,
|
|
32668
|
+
rolesAfter,
|
|
32669
|
+
[action === "grant" ? "rolesAdded" : "rolesRemoved"]: changed,
|
|
32670
|
+
idempotent: changed.length === 0
|
|
32671
|
+
};
|
|
32672
|
+
}
|
|
32673
|
+
async function changeMembership(args, target) {
|
|
32674
|
+
printContextNotice(args, { adminScope: true });
|
|
32675
|
+
const { tenantId } = await resolveTenantId(args);
|
|
32676
|
+
const { client } = adminCtx(args);
|
|
32677
|
+
const before = await requireMember(client, tenantId, args);
|
|
32678
|
+
const path10 = `/api/admin/orgs/${enc(tenantId)}/members`;
|
|
32679
|
+
let res;
|
|
32680
|
+
if (target === "suspended") {
|
|
32681
|
+
res = await client.patch(`${path10}/${enc(before.membershipId)}`, { status: "suspended" });
|
|
32682
|
+
} else if (target === "revoked") {
|
|
32683
|
+
res = await client.del(`${path10}/${enc(before.membershipId)}`);
|
|
32684
|
+
} else {
|
|
32685
|
+
if (!before.email) {
|
|
32686
|
+
throw commandError("EMAIL_UNKNOWN", 1, `Member ${before.principalId} has no email, which re-admission needs.`);
|
|
32687
|
+
}
|
|
32688
|
+
res = await client.post(path10, { email: before.email, roles: [] });
|
|
32689
|
+
}
|
|
32690
|
+
ensureOk(res.status, res.data, `${target === "active" ? "reactivate" : target === "revoked" ? "revoke" : "suspend"} membership`);
|
|
32691
|
+
const after = findMember(await listMembers(client, tenantId), { principalId: before.principalId });
|
|
32692
|
+
return {
|
|
32693
|
+
ok: true,
|
|
32694
|
+
tenantId,
|
|
32695
|
+
principalId: before.principalId,
|
|
32696
|
+
email: before.email || null,
|
|
32697
|
+
membershipId: before.membershipId,
|
|
32698
|
+
membershipStatusBefore: before.membershipStatus,
|
|
32699
|
+
membershipStatus: after?.membershipStatus ?? target,
|
|
32700
|
+
rolesAfter: after?.roles ?? [],
|
|
32701
|
+
idempotent: before.membershipStatus === target
|
|
32702
|
+
};
|
|
32703
|
+
}
|
|
32583
32704
|
function ensureAuthorized(status2, action) {
|
|
32584
32705
|
if (status2 === 401 || status2 === 403) {
|
|
32585
32706
|
throw commandError(
|
|
@@ -32689,9 +32810,45 @@ var org = defineCommand({
|
|
|
32689
32810
|
if (args.displayName) body.displayName = args.displayName;
|
|
32690
32811
|
if (args.kind) body.kind = args.kind;
|
|
32691
32812
|
const { client, fmt } = adminCtx(args);
|
|
32813
|
+
const email3 = String(args.email).trim().toLowerCase();
|
|
32814
|
+
const before = findMember(await listMembers(client, tenantId), { email: email3 });
|
|
32692
32815
|
const res = await client.post(`/api/admin/orgs/${enc(tenantId)}/members`, body);
|
|
32693
32816
|
ensureOk(res.status, res.data, "admit tenant member");
|
|
32694
|
-
|
|
32817
|
+
const after = findMember(await listMembers(client, tenantId), { email: email3 });
|
|
32818
|
+
const rolesBefore = before?.roles ?? [];
|
|
32819
|
+
const rolesAfter = after?.roles ?? [];
|
|
32820
|
+
const rolesAdded = without(rolesAfter, rolesBefore);
|
|
32821
|
+
return output({
|
|
32822
|
+
...recordOf2(res.data),
|
|
32823
|
+
created: !before,
|
|
32824
|
+
membershipStatusBefore: before?.membershipStatus ?? null,
|
|
32825
|
+
membershipStatus: after?.membershipStatus ?? null,
|
|
32826
|
+
rolesBefore,
|
|
32827
|
+
rolesAfter,
|
|
32828
|
+
rolesAdded,
|
|
32829
|
+
idempotent: Boolean(before) && before?.membershipStatus === "active" && rolesAdded.length === 0
|
|
32830
|
+
}, fmt);
|
|
32831
|
+
}
|
|
32832
|
+
}),
|
|
32833
|
+
suspend: defineCommand({
|
|
32834
|
+
meta: { name: "suspend", description: "Suspend a membership (--email or --principal-id); reactivate undoes it" },
|
|
32835
|
+
args: orgArgs,
|
|
32836
|
+
async run({ args }) {
|
|
32837
|
+
return output(await changeMembership(args, "suspended"), adminCtx(args).fmt);
|
|
32838
|
+
}
|
|
32839
|
+
}),
|
|
32840
|
+
revoke: defineCommand({
|
|
32841
|
+
meta: { name: "revoke", description: "Remove a person from the tenant (--email or --principal-id); their roles go too" },
|
|
32842
|
+
args: orgArgs,
|
|
32843
|
+
async run({ args }) {
|
|
32844
|
+
return output(await changeMembership(args, "revoked"), adminCtx(args).fmt);
|
|
32845
|
+
}
|
|
32846
|
+
}),
|
|
32847
|
+
reactivate: defineCommand({
|
|
32848
|
+
meta: { name: "reactivate", description: "Make a suspended or revoked membership active again (--email or --principal-id)" },
|
|
32849
|
+
args: orgArgs,
|
|
32850
|
+
async run({ args }) {
|
|
32851
|
+
return output(await changeMembership(args, "active"), adminCtx(args).fmt);
|
|
32695
32852
|
}
|
|
32696
32853
|
})
|
|
32697
32854
|
}
|
|
@@ -32701,33 +32858,17 @@ var org = defineCommand({
|
|
|
32701
32858
|
args: orgArgs,
|
|
32702
32859
|
subCommands: {
|
|
32703
32860
|
grant: defineCommand({
|
|
32704
|
-
meta: { name: "grant", description: "Grant
|
|
32861
|
+
meta: { name: "grant", description: "Grant tenant roles to a member (--roles a,b; --email or --principal-id)" },
|
|
32705
32862
|
args: orgArgs,
|
|
32706
32863
|
async run({ args }) {
|
|
32707
|
-
|
|
32708
|
-
const { tenantId } = await resolveTenantId(args);
|
|
32709
|
-
req(args, "principalId");
|
|
32710
|
-
const role = rolesFromArgs(args)[0];
|
|
32711
|
-
if (!role) throw commandError("ROLE_REQUIRED", 1, "Pass --role <role-key>.");
|
|
32712
|
-
const { client, fmt } = adminCtx(args);
|
|
32713
|
-
const res = await client.put(`/api/admin/orgs/${enc(tenantId)}/members/${enc(args.principalId)}/roles`, { roleKey: role });
|
|
32714
|
-
ensureOk(res.status, res.data, "grant tenant role");
|
|
32715
|
-
return output({ ...recordOf2(res.data), idempotent: true }, fmt);
|
|
32864
|
+
return output(await changeRoles(args, "grant"), adminCtx(args).fmt);
|
|
32716
32865
|
}
|
|
32717
32866
|
}),
|
|
32718
32867
|
revoke: defineCommand({
|
|
32719
|
-
meta: { name: "revoke", description: "Revoke
|
|
32868
|
+
meta: { name: "revoke", description: "Revoke tenant roles from a member (--roles a,b; --email or --principal-id)" },
|
|
32720
32869
|
args: orgArgs,
|
|
32721
32870
|
async run({ args }) {
|
|
32722
|
-
|
|
32723
|
-
const { tenantId } = await resolveTenantId(args);
|
|
32724
|
-
req(args, "principalId");
|
|
32725
|
-
const role = rolesFromArgs(args)[0];
|
|
32726
|
-
if (!role) throw commandError("ROLE_REQUIRED", 1, "Pass --role <role-key>.");
|
|
32727
|
-
const { client, fmt } = adminCtx(args);
|
|
32728
|
-
const res = await client.del(`/api/admin/orgs/${enc(tenantId)}/members/${enc(args.principalId)}/roles/${enc(role)}`);
|
|
32729
|
-
ensureOk(res.status, res.data, "revoke tenant role");
|
|
32730
|
-
return output(res.data, fmt);
|
|
32871
|
+
return output(await changeRoles(args, "revoke"), adminCtx(args).fmt);
|
|
32731
32872
|
}
|
|
32732
32873
|
})
|
|
32733
32874
|
}
|