@tinycloud/cli 1.1.0-beta.6 → 1.1.0-beta.8
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.js +96 -20
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +146 -47
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +3 -3
- package/skills/tc-cli/AUTH.md +14 -1
- package/skills/tc-cli/REFERENCE.md +20 -0
package/dist/legacy-entry.js
CHANGED
|
@@ -260,7 +260,7 @@ var init_formatter = __esm({
|
|
|
260
260
|
// src/output/errors.ts
|
|
261
261
|
import { readFileSync, readdirSync } from "fs";
|
|
262
262
|
import { join as join2 } from "path";
|
|
263
|
-
import { ProfileLockTimeoutError } from "@tinycloud/operations/state";
|
|
263
|
+
import { ProfileDeletedError, ProfileLockTimeoutError } from "@tinycloud/operations/state";
|
|
264
264
|
function setActiveProfileName(name) {
|
|
265
265
|
activeProfileName = name;
|
|
266
266
|
}
|
|
@@ -286,6 +286,9 @@ function wrapError(error) {
|
|
|
286
286
|
{ hint: "Wait for the other command to finish and retry. A crashed process's lock is reclaimed automatically after 30 s." }
|
|
287
287
|
);
|
|
288
288
|
}
|
|
289
|
+
if (error instanceof ProfileDeletedError) {
|
|
290
|
+
return new CLIError("PROFILE_NOT_FOUND", message);
|
|
291
|
+
}
|
|
289
292
|
if (message.includes("Not signed in") || message.includes("AUTH_EXPIRED") || message.includes("Session expired")) {
|
|
290
293
|
return new CLIError("AUTH_REQUIRED", message, ExitCode.AUTH_REQUIRED);
|
|
291
294
|
}
|
|
@@ -644,6 +647,8 @@ import { join as join3 } from "path";
|
|
|
644
647
|
import {
|
|
645
648
|
profilePath,
|
|
646
649
|
readSession,
|
|
650
|
+
recordProfileDeletion,
|
|
651
|
+
refuseWriteToDeletedProfile,
|
|
647
652
|
removeSession,
|
|
648
653
|
withProfileLock,
|
|
649
654
|
writeSession
|
|
@@ -758,10 +763,12 @@ var init_profiles = __esm({
|
|
|
758
763
|
* removed while holding the profile lock, so another writer's critical
|
|
759
764
|
* section never sees them vanish midway: session and key first, settings
|
|
760
765
|
* last, so a crash midway never leaves a session or key without its
|
|
761
|
-
* profile.
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
766
|
+
* profile. The deletion is then recorded, so a store write that waited for
|
|
767
|
+
* the lock meanwhile refuses rather than recreating a profile with only a
|
|
768
|
+
* session in it. `.lock` itself is left to the lock's release; the
|
|
769
|
+
* then-empty directory is removed afterwards unless another writer took
|
|
770
|
+
* the lock (or wrote) meanwhile. A profile directory that is a symlink is
|
|
771
|
+
* unlinked, its target left alone.
|
|
765
772
|
* Throws if the name is not one path segment or names the default profile.
|
|
766
773
|
*/
|
|
767
774
|
static async deleteProfile(name) {
|
|
@@ -782,11 +789,12 @@ var init_profiles = __esm({
|
|
|
782
789
|
`Cannot delete the default profile "${name}". Change the default first with \`tc profile default <other>\`.`
|
|
783
790
|
);
|
|
784
791
|
}
|
|
785
|
-
const
|
|
786
|
-
if (error.code === "ENOENT") return
|
|
792
|
+
const kind = await lstat(profileDir).then((stats) => stats.isSymbolicLink() ? "link" : "present", (error) => {
|
|
793
|
+
if (error.code === "ENOENT") return "missing";
|
|
787
794
|
throw error;
|
|
788
795
|
});
|
|
789
|
-
if (
|
|
796
|
+
if (kind === "missing") return;
|
|
797
|
+
if (kind === "link") {
|
|
790
798
|
await rm2(profileDir, { force: true });
|
|
791
799
|
return;
|
|
792
800
|
}
|
|
@@ -796,6 +804,7 @@ var init_profiles = __esm({
|
|
|
796
804
|
if (entry !== ".lock" && entry !== "profile.json") await rm2(join3(profileDir, entry), { recursive: true, force: true });
|
|
797
805
|
}
|
|
798
806
|
await rm2(join3(profileDir, "profile.json"), { force: true });
|
|
807
|
+
await recordProfileDeletion(name);
|
|
799
808
|
});
|
|
800
809
|
await rmdir(profileDir).catch((error) => {
|
|
801
810
|
if (error.code !== "ENOENT" && error.code !== "ENOTEMPTY" && error.code !== "EEXIST") throw error;
|
|
@@ -808,9 +817,14 @@ var init_profiles = __esm({
|
|
|
808
817
|
static async getKey(name) {
|
|
809
818
|
return readJson(join3(PROFILES_DIR, name, "key.json"));
|
|
810
819
|
}
|
|
811
|
-
/**
|
|
820
|
+
/**
|
|
821
|
+
* Saves a JWK key under the profile lock (0600, in an owner-only profile
|
|
822
|
+
* directory). Refused (PROFILE_NOT_FOUND) if the profile was deleted while
|
|
823
|
+
* this waited for the lock, rather than leaving a key-only profile.
|
|
824
|
+
*/
|
|
812
825
|
static async setKey(name, jwk) {
|
|
813
826
|
await _ProfileManager.withLock(name, async () => {
|
|
827
|
+
await refuseWriteToDeletedProfile(name);
|
|
814
828
|
await writeJson(join3(await _ProfileManager.ensureProfileDir(name), "key.json"), jwk);
|
|
815
829
|
});
|
|
816
830
|
}
|
|
@@ -1779,7 +1793,8 @@ import {
|
|
|
1779
1793
|
profileStoreMetadataPath,
|
|
1780
1794
|
readAdditionalDelegations,
|
|
1781
1795
|
readAuthRequests,
|
|
1782
|
-
|
|
1796
|
+
refuseWriteToDeletedProfile as refuseWriteToDeletedProfile2,
|
|
1797
|
+
updateProfileStore,
|
|
1783
1798
|
withProfileLock as withProfileLock2,
|
|
1784
1799
|
writeJsonAtomic
|
|
1785
1800
|
} from "@tinycloud/operations/state";
|
|
@@ -13123,17 +13138,15 @@ function didWithoutFragment(did) {
|
|
|
13123
13138
|
async function loadAdditionalDelegations(profile) {
|
|
13124
13139
|
return readAdditionalDelegations(profile);
|
|
13125
13140
|
}
|
|
13126
|
-
async function
|
|
13127
|
-
await
|
|
13141
|
+
async function appendAdditionalDelegations(profile, entries) {
|
|
13142
|
+
const { mergeDelegationsWithoutRequest } = await import("@tinycloud/operations/delegation-binding");
|
|
13143
|
+
await updateProfileStore(profile, "additional-delegations", (stored) => ({
|
|
13144
|
+
records: mergeDelegationsWithoutRequest(stored, entries.map((entry) => ({ ...entry }))),
|
|
13145
|
+
result: void 0
|
|
13146
|
+
}));
|
|
13128
13147
|
}
|
|
13129
13148
|
async function appendAdditionalDelegation(profile, entry) {
|
|
13130
|
-
await
|
|
13131
|
-
profile,
|
|
13132
|
-
"additional-delegations",
|
|
13133
|
-
entry.delegation.cid,
|
|
13134
|
-
entry,
|
|
13135
|
-
(candidate) => candidate.delegation.cid
|
|
13136
|
-
);
|
|
13149
|
+
await appendAdditionalDelegations(profile, [entry]);
|
|
13137
13150
|
}
|
|
13138
13151
|
async function loadPermissionRequestArtifacts(profile) {
|
|
13139
13152
|
const raw = await readAuthRequests(profile);
|
|
@@ -13147,10 +13160,8 @@ async function appendPermissionRequestArtifact(profile, artifact) {
|
|
|
13147
13160
|
await writeSharedRecords(profile, "auth-requests", next);
|
|
13148
13161
|
});
|
|
13149
13162
|
}
|
|
13150
|
-
async function replaceSharedRecords(profile, store, entries) {
|
|
13151
|
-
await withProfileLock2(profile, () => writeSharedRecords(profile, store, entries));
|
|
13152
|
-
}
|
|
13153
13163
|
async function writeSharedRecords(profile, store, entries) {
|
|
13164
|
+
await refuseWriteToDeletedProfile2(profile);
|
|
13154
13165
|
const path = store === "additional-delegations" ? additionalDelegationsPath(profile) : permissionRequestsPath(profile);
|
|
13155
13166
|
await writeJsonAtomic(path, entries);
|
|
13156
13167
|
await writeJsonAtomic(profileStoreMetadataPath(profile, store), { formatVersion: 1 });
|
|
@@ -13163,13 +13174,48 @@ async function getLastPermissionRequestArtifact(profile) {
|
|
|
13163
13174
|
const existing = await loadPermissionRequestArtifacts(profile);
|
|
13164
13175
|
return existing.at(-1) ?? null;
|
|
13165
13176
|
}
|
|
13166
|
-
async function replayAdditionalDelegations(node, profile) {
|
|
13177
|
+
async function replayAdditionalDelegations(node, profile, options) {
|
|
13178
|
+
const {
|
|
13179
|
+
operationSpaceResolver,
|
|
13180
|
+
prepareStoredDelegationReplay,
|
|
13181
|
+
replayStoredDelegation,
|
|
13182
|
+
storedDelegationKind
|
|
13183
|
+
} = await import("@tinycloud/operations/delegation-binding");
|
|
13184
|
+
const activator = node;
|
|
13185
|
+
const migrated = await prepareStoredDelegationReplay(profile, activator, {
|
|
13186
|
+
host: options.host,
|
|
13187
|
+
migrate: options.migrate
|
|
13188
|
+
});
|
|
13189
|
+
const resolveSpace = operationSpaceResolver(node, options.ownerSpace);
|
|
13167
13190
|
const entries = await loadAdditionalDelegations(profile);
|
|
13168
|
-
for (const
|
|
13191
|
+
for (const stored of entries) {
|
|
13192
|
+
const kind = storedDelegationKind(stored);
|
|
13193
|
+
if (kind === "compact" || kind === "signed-login") {
|
|
13194
|
+
const installed = await replayStoredDelegation(activator, stored, {
|
|
13195
|
+
host: options.host,
|
|
13196
|
+
migrated,
|
|
13197
|
+
resolveSpace
|
|
13198
|
+
});
|
|
13199
|
+
if (installed === void 0 && process.env.TC_DEBUG_REPLAY === "1") {
|
|
13200
|
+
process.stderr.write("[replay] skipping a stored delegation refused by validation or its request binding\n");
|
|
13201
|
+
}
|
|
13202
|
+
continue;
|
|
13203
|
+
}
|
|
13204
|
+
if (kind === "refused") {
|
|
13205
|
+
if (process.env.TC_DEBUG_REPLAY === "1") {
|
|
13206
|
+
process.stderr.write("[replay] skipping a malformed stored record or one bound to a request it cannot be held to\n");
|
|
13207
|
+
}
|
|
13208
|
+
continue;
|
|
13209
|
+
}
|
|
13210
|
+
const entry = stored;
|
|
13169
13211
|
const expiry = entry.delegation.expiry instanceof Date ? entry.delegation.expiry : new Date(entry.delegation.expiry);
|
|
13170
13212
|
if (expiry.getTime() <= Date.now()) continue;
|
|
13171
13213
|
try {
|
|
13172
|
-
await node.useRuntimeDelegation({
|
|
13214
|
+
await node.useRuntimeDelegation({
|
|
13215
|
+
...entry.delegation,
|
|
13216
|
+
delegationHeader: { Authorization: entry.delegation.delegationHeader.Authorization },
|
|
13217
|
+
expiry
|
|
13218
|
+
});
|
|
13173
13219
|
} catch (err2) {
|
|
13174
13220
|
if (process.env.TC_DEBUG_REPLAY === "1") {
|
|
13175
13221
|
process.stderr.write(`[replay] skipping ${entry.delegation.cid}: ${err2.message}
|
|
@@ -13474,6 +13520,7 @@ async function createSDKInstance(ctx, options) {
|
|
|
13474
13520
|
host: ctx.host,
|
|
13475
13521
|
privateKey: effectivePrivateKey
|
|
13476
13522
|
});
|
|
13523
|
+
let restoredOwnSession2 = false;
|
|
13477
13524
|
if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
13478
13525
|
await node2.restoreSession({
|
|
13479
13526
|
delegationHeader: session.delegationHeader,
|
|
@@ -13486,16 +13533,22 @@ async function createSDKInstance(ctx, options) {
|
|
|
13486
13533
|
siwe: session.siwe,
|
|
13487
13534
|
signature: session.signature
|
|
13488
13535
|
});
|
|
13536
|
+
restoredOwnSession2 = true;
|
|
13489
13537
|
} else {
|
|
13490
13538
|
await node2.signIn();
|
|
13491
13539
|
}
|
|
13492
|
-
await replayAdditionalDelegations(node2, ctx.profile
|
|
13540
|
+
await replayAdditionalDelegations(node2, ctx.profile, {
|
|
13541
|
+
host: ctx.host,
|
|
13542
|
+
ownerSpace: profile.spaceId,
|
|
13543
|
+
migrate: restoredOwnSession2 && options?.privateKey === void 0
|
|
13544
|
+
});
|
|
13493
13545
|
return node2;
|
|
13494
13546
|
}
|
|
13495
13547
|
const node = new TinyCloudNode({
|
|
13496
13548
|
host: ctx.host,
|
|
13497
13549
|
privateKey: options?.privateKey
|
|
13498
13550
|
});
|
|
13551
|
+
let restoredOwnSession = false;
|
|
13499
13552
|
if (options?.privateKey) {
|
|
13500
13553
|
await node.signIn();
|
|
13501
13554
|
} else if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
@@ -13510,10 +13563,16 @@ async function createSDKInstance(ctx, options) {
|
|
|
13510
13563
|
siwe: session.siwe,
|
|
13511
13564
|
signature: session.signature
|
|
13512
13565
|
});
|
|
13566
|
+
restoredOwnSession = true;
|
|
13513
13567
|
}
|
|
13514
|
-
await replayAdditionalDelegations(node, ctx.profile
|
|
13568
|
+
await replayAdditionalDelegations(node, ctx.profile, {
|
|
13569
|
+
host: ctx.host,
|
|
13570
|
+
ownerSpace: profile?.spaceId,
|
|
13571
|
+
migrate: restoredOwnSession
|
|
13572
|
+
});
|
|
13515
13573
|
return node;
|
|
13516
13574
|
}
|
|
13575
|
+
var BOOTSTRAP_PROFILE_FIELDS = ["sessionDid", "spaceId"];
|
|
13517
13576
|
async function bootstrapDelegatedSession(ctx, delegation) {
|
|
13518
13577
|
const written = await ProfileManager.withLock(ctx.profile, async () => {
|
|
13519
13578
|
const previousProfile = await ProfileManager.getProfile(ctx.profile);
|
|
@@ -13563,13 +13622,13 @@ async function bootstrapDelegatedSession(ctx, delegation) {
|
|
|
13563
13622
|
throw error;
|
|
13564
13623
|
});
|
|
13565
13624
|
const session = await ProfileManager.getSession(ctx.profile);
|
|
13566
|
-
if (
|
|
13625
|
+
if (profile === null || BOOTSTRAP_PROFILE_FIELDS.some((field) => profile[field] !== written.profile[field]) || JSON.stringify(session) !== JSON.stringify(written.session)) {
|
|
13567
13626
|
return `Profile "${ctx.profile}" changed while the import was pending (another login, logout or profile update), so its newer state was kept and the provisional session was not rolled back.`;
|
|
13568
13627
|
}
|
|
13569
13628
|
return restoreBeforeBootstrap(ctx.profile, written.previousProfile);
|
|
13570
13629
|
}, { timeoutMs: PROFILE_COMMIT_LOCK_TIMEOUT_MS }).catch((error) => (
|
|
13571
13630
|
// The lock or a read failed: the import's error stays the one reported.
|
|
13572
|
-
`Rolling back the provisional session of profile "${ctx.profile}" could not run (${
|
|
13631
|
+
`Rolling back the provisional session of profile "${ctx.profile}" could not run (${failureName(error)}); check \`tc --profile ${ctx.profile} context\`.`
|
|
13573
13632
|
));
|
|
13574
13633
|
throw annotate(cause, note);
|
|
13575
13634
|
};
|
|
@@ -13585,15 +13644,27 @@ async function restoreBeforeBootstrap(profileName, previousProfile) {
|
|
|
13585
13644
|
const failures = [];
|
|
13586
13645
|
for (const write of [
|
|
13587
13646
|
() => ProfileManager.clearSession(profileName),
|
|
13588
|
-
() => ProfileManager.
|
|
13647
|
+
() => ProfileManager.updateProfile(profileName, (current) => {
|
|
13648
|
+
const restored = { ...current };
|
|
13649
|
+
for (const field of BOOTSTRAP_PROFILE_FIELDS) {
|
|
13650
|
+
if (previousProfile[field] === void 0) delete restored[field];
|
|
13651
|
+
else restored[field] = previousProfile[field];
|
|
13652
|
+
}
|
|
13653
|
+
return restored;
|
|
13654
|
+
})
|
|
13589
13655
|
]) {
|
|
13590
13656
|
await write().catch((error) => {
|
|
13591
|
-
failures.push(
|
|
13657
|
+
failures.push(failureName(error));
|
|
13592
13658
|
});
|
|
13593
13659
|
}
|
|
13594
13660
|
if (failures.length === 0) return void 0;
|
|
13595
13661
|
return `Rolling back the provisional session of profile "${profileName}" failed too (${failures.join("; ")}); check \`tc --profile ${profileName} context\`.`;
|
|
13596
13662
|
}
|
|
13663
|
+
function failureName(error) {
|
|
13664
|
+
if (error instanceof SyntaxError) return "a profile file is not valid JSON";
|
|
13665
|
+
if (typeof error === "object" && error !== null && "code" in error && typeof error.code === "string") return error.code;
|
|
13666
|
+
return error instanceof Error ? error.name : "unknown error";
|
|
13667
|
+
}
|
|
13597
13668
|
function annotate(error, note) {
|
|
13598
13669
|
if (note === void 0) return error;
|
|
13599
13670
|
const cause = wrapError(error);
|
|
@@ -13605,7 +13676,7 @@ async function ensureAuthenticated(ctx, options) {
|
|
|
13605
13676
|
}
|
|
13606
13677
|
const profile = await ProfileManager.getProfile(ctx.profile).catch(() => null);
|
|
13607
13678
|
if (profile?.authMethod === "local" && profile.privateKey) {
|
|
13608
|
-
return createSDKInstance(ctx
|
|
13679
|
+
return createSDKInstance(ctx);
|
|
13609
13680
|
}
|
|
13610
13681
|
const session = await ProfileManager.getSession(ctx.profile);
|
|
13611
13682
|
if (!session) {
|
|
@@ -15496,6 +15567,15 @@ function registerAuthCommand(program) {
|
|
|
15496
15567
|
return;
|
|
15497
15568
|
}
|
|
15498
15569
|
const imported = normalizeDelegationImport(parsed);
|
|
15570
|
+
const { activateUnboundCompactImport, storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
|
|
15571
|
+
const kind = storedDelegationKind({ delegation: imported.delegation });
|
|
15572
|
+
if (kind === "refused") {
|
|
15573
|
+
throw new CLIError(
|
|
15574
|
+
"INVALID_AUTH_IMPORT",
|
|
15575
|
+
"Imported delegation must carry exactly one string Authorization header.",
|
|
15576
|
+
ExitCode.USAGE_ERROR
|
|
15577
|
+
);
|
|
15578
|
+
}
|
|
15499
15579
|
let node;
|
|
15500
15580
|
try {
|
|
15501
15581
|
node = await ensureAuthenticated(ctx);
|
|
@@ -15505,18 +15585,33 @@ function registerAuthCommand(program) {
|
|
|
15505
15585
|
if (session || resolveProfilePosture(profile) !== "delegate-session") throw error;
|
|
15506
15586
|
node = (await bootstrapDelegatedSession(ctx, imported.delegation)).node;
|
|
15507
15587
|
}
|
|
15508
|
-
await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
|
|
15509
|
-
imported.delegation,
|
|
15510
|
-
imported.permissions
|
|
15511
|
-
));
|
|
15512
15588
|
const targetsSessionKey = typeof imported.delegation.delegateDID === "string" && principalDidEquals(imported.delegation.delegateDID, node.sessionDid);
|
|
15513
15589
|
let activated = false;
|
|
15514
|
-
|
|
15515
|
-
|
|
15590
|
+
let permissions = imported.permissions;
|
|
15591
|
+
if (targetsSessionKey && kind === "compact") {
|
|
15592
|
+
const record = await activateUnboundCompactImport(
|
|
15593
|
+
node,
|
|
15594
|
+
imported.delegation,
|
|
15595
|
+
ctx.host
|
|
15596
|
+
);
|
|
15597
|
+
await appendAdditionalDelegation(ctx.profile, record);
|
|
15598
|
+
permissions = record.permissions;
|
|
15516
15599
|
activated = true;
|
|
15600
|
+
} else {
|
|
15601
|
+
await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
|
|
15602
|
+
imported.delegation,
|
|
15603
|
+
imported.permissions
|
|
15604
|
+
));
|
|
15605
|
+
if (targetsSessionKey) {
|
|
15606
|
+
await node.useRuntimeDelegation({
|
|
15607
|
+
...imported.delegation,
|
|
15608
|
+
delegationHeader: { Authorization: imported.delegation.delegationHeader.Authorization }
|
|
15609
|
+
});
|
|
15610
|
+
activated = true;
|
|
15611
|
+
}
|
|
15517
15612
|
}
|
|
15518
15613
|
await appendGrantHistory(ctx.profile, {
|
|
15519
|
-
addedCaps:
|
|
15614
|
+
addedCaps: permissions,
|
|
15520
15615
|
source: "cli",
|
|
15521
15616
|
delegationCid: imported.delegation.cid,
|
|
15522
15617
|
expiry: imported.delegation.expiry.toISOString()
|
|
@@ -15527,7 +15622,7 @@ function registerAuthCommand(program) {
|
|
|
15527
15622
|
kind: "tinycloud.auth.delegation",
|
|
15528
15623
|
requestId: imported.requestId ?? null,
|
|
15529
15624
|
delegationCid: imported.delegation.cid,
|
|
15530
|
-
permissions
|
|
15625
|
+
permissions,
|
|
15531
15626
|
expiry: imported.delegation.expiry.toISOString()
|
|
15532
15627
|
});
|
|
15533
15628
|
} catch (error) {
|
|
@@ -15901,8 +15996,6 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
|
|
|
15901
15996
|
for (const { delegation } of grants) await node.useRuntimeDelegation(delegation);
|
|
15902
15997
|
if (grants.length === 0) return;
|
|
15903
15998
|
await ProfileManager.withLock(profileName, async () => {
|
|
15904
|
-
const existing = await loadAdditionalDelegations(profileName);
|
|
15905
|
-
const replacing = new Set(grants.map(({ delegation }) => delegation.cid));
|
|
15906
15999
|
for (const { delegation, effective } of grants) {
|
|
15907
16000
|
await appendGrantHistory(profileName, {
|
|
15908
16001
|
addedCaps: effective,
|
|
@@ -15911,10 +16004,10 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
|
|
|
15911
16004
|
expiry: delegation.expiry.toISOString()
|
|
15912
16005
|
});
|
|
15913
16006
|
}
|
|
15914
|
-
await
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
|
|
16007
|
+
await appendAdditionalDelegations(
|
|
16008
|
+
profileName,
|
|
16009
|
+
grants.map(({ delegation, effective }) => storedAdditionalDelegation(delegation, effective))
|
|
16010
|
+
);
|
|
15918
16011
|
});
|
|
15919
16012
|
}
|
|
15920
16013
|
async function ensureDelegationAuthority(params) {
|
|
@@ -29981,7 +30074,13 @@ async function readHasKey(name, issues) {
|
|
|
29981
30074
|
}
|
|
29982
30075
|
async function readDelegations(name, issues) {
|
|
29983
30076
|
try {
|
|
29984
|
-
|
|
30077
|
+
const entries = await loadAdditionalDelegations(name);
|
|
30078
|
+
const { storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
|
|
30079
|
+
const readable = entries.filter((entry) => storedDelegationKind(entry) !== "refused");
|
|
30080
|
+
if (readable.length < entries.length) {
|
|
30081
|
+
issues.push(`delegations: ${entries.length - readable.length} unreadable stored record(s) skipped`);
|
|
30082
|
+
}
|
|
30083
|
+
return readable;
|
|
29985
30084
|
} catch (error) {
|
|
29986
30085
|
issues.push(`delegations: ${messageFromError(error)}`);
|
|
29987
30086
|
return [];
|