@tinycloud/operations 0.4.0-beta.9 → 0.4.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/coverage.json +6 -0
- package/dist/artifacts.cjs +19 -4
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +1 -1
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +19 -4
- package/dist/artifacts.js.map +1 -1
- package/dist/cli-runtime.cjs +162 -27
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.d.cts +1 -1
- package/dist/cli-runtime.d.ts +1 -1
- package/dist/cli-runtime.js +162 -26
- package/dist/cli-runtime.js.map +1 -1
- package/dist/{contract-CjuEjE-M.d.cts → contract-BRwWJpPs.d.cts} +24 -2
- package/dist/{contract-CjuEjE-M.d.ts → contract-BRwWJpPs.d.ts} +24 -2
- package/dist/delegation-binding.cjs +79 -16
- package/dist/delegation-binding.cjs.map +1 -1
- package/dist/delegation-binding.d.cts +43 -13
- package/dist/delegation-binding.d.ts +43 -13
- package/dist/delegation-binding.js +78 -16
- package/dist/delegation-binding.js.map +1 -1
- package/dist/index.cjs +160 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +160 -27
- package/dist/index.js.map +1 -1
- package/dist/profile.cjs.map +1 -1
- package/dist/profile.d.cts +1 -1
- package/dist/profile.d.ts +1 -1
- package/dist/profile.js.map +1 -1
- package/dist/state.cjs +9 -3
- package/dist/state.cjs.map +1 -1
- package/dist/state.d.cts +7 -0
- package/dist/state.d.ts +7 -0
- package/dist/state.js +9 -3
- package/dist/state.js.map +1 -1
- package/generated/operations.json +2661 -4
- package/package.json +4 -4
package/dist/cli-runtime.d.cts
CHANGED
package/dist/cli-runtime.d.ts
CHANGED
package/dist/cli-runtime.js
CHANGED
|
@@ -40,6 +40,17 @@ function operationError(code, message, options = {}) {
|
|
|
40
40
|
...options.details === void 0 ? {} : { details: options.details }
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
+
function storageFullOperationError(error) {
|
|
44
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
45
|
+
const { code, meta } = error;
|
|
46
|
+
if (code !== "STORAGE_QUOTA_EXCEEDED" && code !== "STORAGE_LIMIT_REACHED") return void 0;
|
|
47
|
+
const account = typeof meta === "object" && meta !== null ? meta.account : void 0;
|
|
48
|
+
return operationError(
|
|
49
|
+
"STORAGE_QUOTA_EXCEEDED",
|
|
50
|
+
code === "STORAGE_LIMIT_REACHED" ? `This write is larger than the TinyCloud storage left, so nothing was written. Reading still works. ${MANAGE_STORAGE}` : `TinyCloud storage is full, so nothing was written. Reading still works. ${MANAGE_STORAGE}`,
|
|
51
|
+
{ retryable: false, ...account === void 0 ? {} : { details: { account } } }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
43
54
|
function isOperationErrorCode(value) {
|
|
44
55
|
return typeof value === "string" && OPERATION_ERROR_CODES.includes(value);
|
|
45
56
|
}
|
|
@@ -65,7 +76,7 @@ function sanitizeOperationError(error) {
|
|
|
65
76
|
...candidate.details === void 0 ? {} : { details: candidate.details }
|
|
66
77
|
});
|
|
67
78
|
}
|
|
68
|
-
var OPERATION_ERROR_CODES, OperationInvocationError;
|
|
79
|
+
var OPERATION_ERROR_CODES, MANAGE_STORAGE, OperationInvocationError;
|
|
69
80
|
var init_errors = __esm({
|
|
70
81
|
"src/errors.ts"() {
|
|
71
82
|
"use strict";
|
|
@@ -88,6 +99,7 @@ var init_errors = __esm({
|
|
|
88
99
|
"ENCRYPTION_NETWORK_UNRESOLVED",
|
|
89
100
|
"NODE_UNREACHABLE",
|
|
90
101
|
"NODE_ERROR",
|
|
102
|
+
"STORAGE_QUOTA_EXCEEDED",
|
|
91
103
|
"KV_NOT_FOUND",
|
|
92
104
|
"KV_PRECONDITION_FAILED",
|
|
93
105
|
"KV_CONFLICT",
|
|
@@ -101,6 +113,7 @@ var init_errors = __esm({
|
|
|
101
113
|
"OUTPUT_INVALID",
|
|
102
114
|
"INTERNAL_ERROR"
|
|
103
115
|
];
|
|
116
|
+
MANAGE_STORAGE = "Do not retry: the owner must free up space or upgrade at https://account.tinycloud.xyz/billing.";
|
|
104
117
|
OperationInvocationError = class extends Error {
|
|
105
118
|
constructor(operationError2) {
|
|
106
119
|
super(operationError2.message);
|
|
@@ -342,8 +355,13 @@ function canonicalizeRecapCaveats(caveats) {
|
|
|
342
355
|
}
|
|
343
356
|
return `[${branches.join(",")}]`;
|
|
344
357
|
}
|
|
358
|
+
function isExplicitOnlyAction(action) {
|
|
359
|
+
return Object.prototype.hasOwnProperty.call(EXPLICIT_ONLY_ACTIONS, action);
|
|
360
|
+
}
|
|
345
361
|
function actionContains(grantedAction, requestedAction) {
|
|
346
|
-
if (grantedAction ===
|
|
362
|
+
if (grantedAction === requestedAction) return true;
|
|
363
|
+
if (isExplicitOnlyAction(requestedAction)) return false;
|
|
364
|
+
if (grantedAction === "*") return true;
|
|
347
365
|
if (!grantedAction.endsWith("/*")) return false;
|
|
348
366
|
const service = grantedAction.slice(0, -2);
|
|
349
367
|
return requestedAction === service || requestedAction.startsWith(`${service}/`);
|
|
@@ -368,10 +386,15 @@ function cloneEntry(entry) {
|
|
|
368
386
|
...entry.expiry !== void 0 ? { expiry: entry.expiry } : {}
|
|
369
387
|
};
|
|
370
388
|
}
|
|
389
|
+
var EXPLICIT_ONLY_ACTIONS;
|
|
371
390
|
var init_capabilities = __esm({
|
|
372
391
|
"../sdk-core/src/capabilities.ts"() {
|
|
373
392
|
"use strict";
|
|
374
393
|
init_manifest();
|
|
394
|
+
EXPLICIT_ONLY_ACTIONS = {
|
|
395
|
+
"tinycloud.kv/sync": true,
|
|
396
|
+
"tinycloud.kv/retain": true
|
|
397
|
+
};
|
|
375
398
|
}
|
|
376
399
|
});
|
|
377
400
|
|
|
@@ -714,7 +737,8 @@ async function acquireProfileLock(profile, options) {
|
|
|
714
737
|
const lockPath = profileLockPath(profile);
|
|
715
738
|
const turnDirectory = profileTurnLockPath(profile);
|
|
716
739
|
const directory = profilePath(profile);
|
|
717
|
-
|
|
740
|
+
if (options.requireProfile && !await exists(profileConfigPath(profile))) throw new ProfileDeletedError(profile);
|
|
741
|
+
if (!options.requireProfile) await mkdir(directory, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
718
742
|
await mkdir(dirname(turnDirectory), { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
719
743
|
for (const path of [tinycloudHomePath(), profilesPath(), directory]) {
|
|
720
744
|
await chmod(path, PRIVATE_DIR_MODE).catch((error) => {
|
|
@@ -723,11 +747,15 @@ async function acquireProfileLock(profile, options) {
|
|
|
723
747
|
}
|
|
724
748
|
const { turn, firstWaitedTurn } = await acquireTurn(profile, turnDirectory, deadline);
|
|
725
749
|
try {
|
|
750
|
+
if (options.requireProfile && !await exists(profileConfigPath(profile))) {
|
|
751
|
+
await rmdir(directory).catch(() => void 0);
|
|
752
|
+
throw new ProfileDeletedError(profile);
|
|
753
|
+
}
|
|
726
754
|
const deletion = await readJson(join(turnDirectory, "deleted.json")).catch(() => null);
|
|
727
755
|
const deletedWhileWaiting = typeof deletion?.slot === "number" && deletion.slot >= firstWaitedTurn;
|
|
728
756
|
while (true) {
|
|
729
757
|
const token = randomUUID();
|
|
730
|
-
if (await publishProfileLock(profile, lockPath, token)) {
|
|
758
|
+
if (await publishProfileLock(profile, lockPath, token, options.requireProfile === true)) {
|
|
731
759
|
return {
|
|
732
760
|
deletedWhileWaiting,
|
|
733
761
|
turnSlot: turn.slot,
|
|
@@ -972,12 +1000,13 @@ async function collectTurns(profile, turn) {
|
|
|
972
1000
|
}
|
|
973
1001
|
}
|
|
974
1002
|
}
|
|
975
|
-
async function publishProfileLock(profile, lockPath, token) {
|
|
1003
|
+
async function publishProfileLock(profile, lockPath, token, requireProfile) {
|
|
976
1004
|
try {
|
|
977
1005
|
await mkdir(lockPath, { mode: PRIVATE_DIR_MODE });
|
|
978
1006
|
} catch (error) {
|
|
979
1007
|
if (isErrno(error, "EEXIST")) return false;
|
|
980
1008
|
if (!isErrno(error, "ENOENT")) throw error;
|
|
1009
|
+
if (requireProfile) throw new ProfileDeletedError(profile);
|
|
981
1010
|
await mkdir(profilePath(profile), { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
982
1011
|
return false;
|
|
983
1012
|
}
|
|
@@ -2545,6 +2574,8 @@ function kvFailure(error, action) {
|
|
|
2545
2574
|
if (error.code === "KV_RESPONSE_TOO_LARGE") {
|
|
2546
2575
|
return { status: "error", error: operationError("KV_RESPONSE_TOO_LARGE", `The TinyCloud KV value exceeds ${MAX_KV_VALUE_BYTES} bytes.`) };
|
|
2547
2576
|
}
|
|
2577
|
+
const storageFull = storageFullOperationError(error);
|
|
2578
|
+
if (storageFull) return { status: "error", error: storageFull };
|
|
2548
2579
|
return nodeFailure(action);
|
|
2549
2580
|
}
|
|
2550
2581
|
function nodeFailure(action) {
|
|
@@ -3163,7 +3194,7 @@ async function executeSqlDml(context, input) {
|
|
|
3163
3194
|
const runtime = runtimeContext2(context);
|
|
3164
3195
|
const space = resolveSqlSpace(runtime, input.space);
|
|
3165
3196
|
const result = await runtimeNode2(runtime).sqlForSpace(space).db(input.database).execute(input.sql, input.params.map(decodeSqlInputValue));
|
|
3166
|
-
if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure();
|
|
3197
|
+
if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure(result.error);
|
|
3167
3198
|
const normalized = normalizeExecuteResult(result.data);
|
|
3168
3199
|
return {
|
|
3169
3200
|
status: "ok",
|
|
@@ -3177,7 +3208,7 @@ async function executeSqlDml(context, input) {
|
|
|
3177
3208
|
};
|
|
3178
3209
|
} catch (error) {
|
|
3179
3210
|
if (error instanceof OperationInvocationError) return { status: "error", error: error.operationError };
|
|
3180
|
-
return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure();
|
|
3211
|
+
return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure(error);
|
|
3181
3212
|
}
|
|
3182
3213
|
}
|
|
3183
3214
|
function isSingleReadQuery(sql) {
|
|
@@ -3354,7 +3385,9 @@ function sqlServiceFailure(error, action) {
|
|
|
3354
3385
|
}
|
|
3355
3386
|
return nodeFailure2(action);
|
|
3356
3387
|
}
|
|
3357
|
-
function sqlMutationFailure() {
|
|
3388
|
+
function sqlMutationFailure(error) {
|
|
3389
|
+
const storageFull = storageFullOperationError(error);
|
|
3390
|
+
if (storageFull) return { status: "error", error: storageFull };
|
|
3358
3391
|
return {
|
|
3359
3392
|
status: "error",
|
|
3360
3393
|
error: operationError(
|
|
@@ -3609,6 +3642,32 @@ ORDER BY type, name`;
|
|
|
3609
3642
|
}
|
|
3610
3643
|
});
|
|
3611
3644
|
|
|
3645
|
+
// src/contract.ts
|
|
3646
|
+
var STORED_GRANT_SKIP_REASONS, DELEGATION_CID_PATTERN;
|
|
3647
|
+
var init_contract = __esm({
|
|
3648
|
+
"src/contract.ts"() {
|
|
3649
|
+
"use strict";
|
|
3650
|
+
STORED_GRANT_SKIP_REASONS = [
|
|
3651
|
+
"malformed",
|
|
3652
|
+
"unbound",
|
|
3653
|
+
"outside_request",
|
|
3654
|
+
"host_mismatch",
|
|
3655
|
+
"expired",
|
|
3656
|
+
"cid_mismatch",
|
|
3657
|
+
"authority_invalid",
|
|
3658
|
+
"proof_missing",
|
|
3659
|
+
"proof_invalid",
|
|
3660
|
+
"owner_mismatch",
|
|
3661
|
+
"audience_mismatch",
|
|
3662
|
+
"resources_mismatch",
|
|
3663
|
+
"unsupported",
|
|
3664
|
+
"activation_rejected",
|
|
3665
|
+
"invalid"
|
|
3666
|
+
];
|
|
3667
|
+
DELEGATION_CID_PATTERN = "^bafkr4i[a-z2-7]{52}$";
|
|
3668
|
+
}
|
|
3669
|
+
});
|
|
3670
|
+
|
|
3612
3671
|
// src/delegation-binding.ts
|
|
3613
3672
|
import { join as join2 } from "path";
|
|
3614
3673
|
import * as nodeSdk3 from "@tinycloud/node-sdk";
|
|
@@ -3634,12 +3693,12 @@ function replayLimit(entry, migrated) {
|
|
|
3634
3693
|
if (binding.success) return binding.data.requested;
|
|
3635
3694
|
return !migrated && kind === "compact" && !("authorityRequest" in entry) ? "signed" : void 0;
|
|
3636
3695
|
}
|
|
3637
|
-
function
|
|
3696
|
+
function bindToRequest(record, requested, source, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3638
3697
|
return {
|
|
3639
3698
|
...record,
|
|
3640
3699
|
authorityRequest: DelegationRequestBindingSchema.parse({
|
|
3641
3700
|
requestId: `${REQUEST_ID_PREFIX[source]}:${record.delegation.cid}`,
|
|
3642
|
-
requested: structuredClone(
|
|
3701
|
+
requested: structuredClone(requested)
|
|
3643
3702
|
}),
|
|
3644
3703
|
authorityRequestAudit: { source, recordedAt, note: BINDING_NOTES[source] }
|
|
3645
3704
|
};
|
|
@@ -3695,23 +3754,40 @@ async function migratedRecord(node, entry, host, recordedAt) {
|
|
|
3695
3754
|
const signed = await signedCapabilities(node, delegation, host);
|
|
3696
3755
|
if (signed === void 0) return void 0;
|
|
3697
3756
|
try {
|
|
3698
|
-
return
|
|
3757
|
+
return bindToRequest({ ...entry, delegation: { ...entry.delegation, cid: delegation.cid } }, signed, "migration", recordedAt);
|
|
3699
3758
|
} catch {
|
|
3700
3759
|
return void 0;
|
|
3701
3760
|
}
|
|
3702
3761
|
}
|
|
3762
|
+
function skipped(reason) {
|
|
3763
|
+
return { status: "skipped", reason };
|
|
3764
|
+
}
|
|
3703
3765
|
async function replayStoredDelegation(node, entry, options) {
|
|
3766
|
+
const kind = storedDelegationKind(entry);
|
|
3704
3767
|
const delegation = normalizeStoredDelegation(entry);
|
|
3705
|
-
if (
|
|
3768
|
+
if (kind === "refused" || delegation === void 0) return skipped("malformed");
|
|
3769
|
+
if (delegation.expiry.getTime() <= Date.now()) return NOT_REPLAYED;
|
|
3770
|
+
if (kind === "other") return skipped("proof_missing");
|
|
3706
3771
|
const limit = replayLimit(entry, options.migrated);
|
|
3707
|
-
if (limit === void 0) return
|
|
3708
|
-
|
|
3772
|
+
if (limit === void 0) return skipped("unbound");
|
|
3773
|
+
let outsideRequest = false;
|
|
3774
|
+
const authorize = limit === "signed" ? () => true : (effective) => {
|
|
3775
|
+
outsideRequest = !delegationWithinRequest(limit, effective, options.resolveSpace);
|
|
3776
|
+
return !outsideRequest;
|
|
3777
|
+
};
|
|
3709
3778
|
try {
|
|
3710
|
-
return
|
|
3711
|
-
|
|
3712
|
-
|
|
3779
|
+
return {
|
|
3780
|
+
status: "installed",
|
|
3781
|
+
delegation: await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, { host: options.host, authorize })
|
|
3782
|
+
};
|
|
3783
|
+
} catch (error) {
|
|
3784
|
+
return skipped(outsideRequest ? "outside_request" : rejectionReason(error));
|
|
3713
3785
|
}
|
|
3714
3786
|
}
|
|
3787
|
+
function rejectionReason(error) {
|
|
3788
|
+
const reason = isRecord4(error) ? error.reason : void 0;
|
|
3789
|
+
return typeof reason === "string" && STORED_GRANT_SKIP_REASONS.includes(reason) ? reason : "invalid";
|
|
3790
|
+
}
|
|
3715
3791
|
async function bindingMigrationRecorded(profile) {
|
|
3716
3792
|
try {
|
|
3717
3793
|
return await readJson(bindingMigrationPath(profile)) !== null;
|
|
@@ -3756,23 +3832,27 @@ function recordKey(entry) {
|
|
|
3756
3832
|
function isRecord4(value) {
|
|
3757
3833
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3758
3834
|
}
|
|
3759
|
-
var REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS;
|
|
3835
|
+
var REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS, NOT_REPLAYED;
|
|
3760
3836
|
var init_delegation_binding = __esm({
|
|
3761
3837
|
"src/delegation-binding.ts"() {
|
|
3762
3838
|
"use strict";
|
|
3763
3839
|
init_artifacts();
|
|
3764
3840
|
init_authority();
|
|
3841
|
+
init_contract();
|
|
3765
3842
|
init_state();
|
|
3766
3843
|
init_secrets();
|
|
3767
3844
|
REQUEST_ID_PREFIX = {
|
|
3768
3845
|
migration: "migrated",
|
|
3769
|
-
"unbound-import": "unbound-import"
|
|
3846
|
+
"unbound-import": "unbound-import",
|
|
3847
|
+
"cli-grant": "cli-grant"
|
|
3770
3848
|
};
|
|
3771
3849
|
BINDING_NOTES = {
|
|
3772
3850
|
migration: "Stored without a request binding before bindings were required. Bound at migration to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them.",
|
|
3773
|
-
"unbound-import": "Imported by `tc auth import` without a stored request. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them."
|
|
3851
|
+
"unbound-import": "Imported by `tc auth import` without a stored request. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them.",
|
|
3852
|
+
"cli-grant": "Granted to this CLI by `tc auth request --grant` or a permission escalation, and checked against the request it answered. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them."
|
|
3774
3853
|
};
|
|
3775
3854
|
MIGRATION_LOCK_TIMEOUT_MS = 250;
|
|
3855
|
+
NOT_REPLAYED = { status: "not-replayed" };
|
|
3776
3856
|
}
|
|
3777
3857
|
});
|
|
3778
3858
|
|
|
@@ -4185,7 +4265,18 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4185
4265
|
));
|
|
4186
4266
|
}
|
|
4187
4267
|
} else {
|
|
4188
|
-
|
|
4268
|
+
try {
|
|
4269
|
+
await node.restoreSession(activeSession);
|
|
4270
|
+
} catch (error) {
|
|
4271
|
+
if (isRecord7(error) && error.code === "AUTH_EXPIRED") {
|
|
4272
|
+
return failed(summary, operationError(
|
|
4273
|
+
"AUTH_REQUIRED",
|
|
4274
|
+
"The stored session has expired or is no longer valid. Sign in again.",
|
|
4275
|
+
{ retryable: false }
|
|
4276
|
+
));
|
|
4277
|
+
}
|
|
4278
|
+
throw error;
|
|
4279
|
+
}
|
|
4189
4280
|
}
|
|
4190
4281
|
const activeSessionDid = normalizeDid(node.sessionDid);
|
|
4191
4282
|
const livePrincipalDid = normalizeDid(node.did);
|
|
@@ -4193,6 +4284,7 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4193
4284
|
const livePermissions = [...node.getVerifiedSessionCapabilities()];
|
|
4194
4285
|
const resolveSpace2 = operationSpaceResolver(node, authenticatedSpace ?? summary.space);
|
|
4195
4286
|
const seenCids = /* @__PURE__ */ new Set();
|
|
4287
|
+
const warnings = [];
|
|
4196
4288
|
if (!explicitPrivateKeyOverride) {
|
|
4197
4289
|
const activator = node;
|
|
4198
4290
|
const migrated = await prepareStoredDelegationReplay(profileName, activator, {
|
|
@@ -4202,20 +4294,25 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4202
4294
|
migrate: activeSession !== void 0
|
|
4203
4295
|
});
|
|
4204
4296
|
for (const entry of await readAdditionalDelegations(profileName)) {
|
|
4205
|
-
const
|
|
4297
|
+
const replay = await replayStoredDelegation(activator, entry, {
|
|
4206
4298
|
host: summary.host,
|
|
4207
4299
|
migrated,
|
|
4208
4300
|
resolveSpace: resolveSpace2
|
|
4209
4301
|
});
|
|
4210
|
-
if (
|
|
4211
|
-
seenCids.
|
|
4212
|
-
|
|
4302
|
+
if (replay.status === "installed") {
|
|
4303
|
+
if (!seenCids.has(replay.delegation.cid)) {
|
|
4304
|
+
seenCids.add(replay.delegation.cid);
|
|
4305
|
+
livePermissions.push(...replay.delegation.effectivePermissions);
|
|
4306
|
+
}
|
|
4307
|
+
} else if (replay.status === "skipped") {
|
|
4308
|
+
warnings.push(skippedGrantWarning(node, entry, replay.reason));
|
|
4213
4309
|
}
|
|
4214
4310
|
}
|
|
4215
4311
|
}
|
|
4216
4312
|
const runtime = {
|
|
4217
4313
|
node,
|
|
4218
|
-
granted: canonicalizeCapabilities(livePermissions)
|
|
4314
|
+
granted: canonicalizeCapabilities(livePermissions),
|
|
4315
|
+
...warnings.length === 0 ? {} : { warnings }
|
|
4219
4316
|
};
|
|
4220
4317
|
return {
|
|
4221
4318
|
ok: true,
|
|
@@ -4239,6 +4336,24 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4239
4336
|
));
|
|
4240
4337
|
}
|
|
4241
4338
|
}
|
|
4339
|
+
function skippedGrantWarning(node, entry, reason) {
|
|
4340
|
+
const grantCid = verifiedStoredCid(node, entry);
|
|
4341
|
+
return { code: "STORED_GRANT_SKIPPED", reason, ...grantCid === void 0 ? {} : { grantCid } };
|
|
4342
|
+
}
|
|
4343
|
+
function verifiedStoredCid(node, entry) {
|
|
4344
|
+
const delegation = isRecord7(entry) && isRecord7(entry.delegation) ? entry.delegation : void 0;
|
|
4345
|
+
const header = isRecord7(delegation?.delegationHeader) ? delegation.delegationHeader : void 0;
|
|
4346
|
+
const cid = delegation?.cid;
|
|
4347
|
+
const computeDelegationCid = isRecord7(node) ? node.computeDelegationCid : void 0;
|
|
4348
|
+
if (typeof cid !== "string" || typeof header?.Authorization !== "string" || typeof computeDelegationCid !== "function") {
|
|
4349
|
+
return void 0;
|
|
4350
|
+
}
|
|
4351
|
+
try {
|
|
4352
|
+
return computeDelegationCid.call(node, header.Authorization) === cid && DELEGATION_CID.test(cid) ? cid : void 0;
|
|
4353
|
+
} catch {
|
|
4354
|
+
return void 0;
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4242
4357
|
function spaceForAuthenticatedPrincipal(principal2) {
|
|
4243
4358
|
if (principal2 === void 0) return void 0;
|
|
4244
4359
|
try {
|
|
@@ -4287,15 +4402,18 @@ function unresolvedSummary(target) {
|
|
|
4287
4402
|
posture: "unauthenticated"
|
|
4288
4403
|
};
|
|
4289
4404
|
}
|
|
4405
|
+
var DELEGATION_CID;
|
|
4290
4406
|
var init_runtime = __esm({
|
|
4291
4407
|
"src/runtime.ts"() {
|
|
4292
4408
|
"use strict";
|
|
4409
|
+
init_contract();
|
|
4293
4410
|
init_authority();
|
|
4294
4411
|
init_errors();
|
|
4295
4412
|
init_profile();
|
|
4296
4413
|
init_secrets();
|
|
4297
4414
|
init_state();
|
|
4298
4415
|
init_delegation_binding();
|
|
4416
|
+
DELEGATION_CID = new RegExp(DELEGATION_CID_PATTERN);
|
|
4299
4417
|
}
|
|
4300
4418
|
});
|
|
4301
4419
|
|
|
@@ -4597,8 +4715,19 @@ var SAFE_ERROR_DETAIL_POLICIES = {
|
|
|
4597
4715
|
DELEGATION_HOST_MISMATCH: {
|
|
4598
4716
|
expectedHost: safeOriginHost,
|
|
4599
4717
|
artifactHost: safeOriginHost
|
|
4718
|
+
},
|
|
4719
|
+
STORAGE_QUOTA_EXCEEDED: {
|
|
4720
|
+
account: safeStorageAccount
|
|
4600
4721
|
}
|
|
4601
4722
|
};
|
|
4723
|
+
function safeStorageAccount(value) {
|
|
4724
|
+
if (!isRecord(value)) return void 0;
|
|
4725
|
+
const { usedBytes, limitBytes, plan } = value;
|
|
4726
|
+
if (!Number.isSafeInteger(usedBytes) || usedBytes < 0 || !Number.isSafeInteger(limitBytes) || limitBytes <= 0) {
|
|
4727
|
+
return void 0;
|
|
4728
|
+
}
|
|
4729
|
+
return typeof plan === "string" && /^[A-Za-z0-9][A-Za-z0-9 _.-]{0,31}$/.test(plan) ? { usedBytes, limitBytes, plan } : { usedBytes, limitBytes };
|
|
4730
|
+
}
|
|
4602
4731
|
function redactSafeErrorDetails(code, details) {
|
|
4603
4732
|
const policy = SAFE_ERROR_DETAIL_POLICIES[code];
|
|
4604
4733
|
if (policy === void 0) return void 0;
|
|
@@ -4684,6 +4813,9 @@ async function invokeLocalAuthorityRetry(operationId, operationVersion, target,
|
|
|
4684
4813
|
unknownInput
|
|
4685
4814
|
);
|
|
4686
4815
|
if (isPreparedError(prepared)) return prepared.result;
|
|
4816
|
+
return withRuntimeWarnings(await retryWithLocalAuthority(prepared), prepared);
|
|
4817
|
+
}
|
|
4818
|
+
async function retryWithLocalAuthority(prepared) {
|
|
4687
4819
|
if (prepared.operation.operationId !== "tinycloud.secrets.get" || prepared.operation.operationVersion !== 1) {
|
|
4688
4820
|
return errorResult(
|
|
4689
4821
|
prepared.operation,
|
|
@@ -4782,6 +4914,10 @@ async function invokeLocalAuthorityRetry(operationId, operationVersion, target,
|
|
|
4782
4914
|
return localAuthorityFailure(prepared);
|
|
4783
4915
|
}
|
|
4784
4916
|
}
|
|
4917
|
+
function withRuntimeWarnings(result, prepared) {
|
|
4918
|
+
const warnings = prepared.runtimeResolution.context.runtime?.warnings;
|
|
4919
|
+
return warnings === void 0 || warnings.length === 0 ? result : { ...result, warnings: [...warnings] };
|
|
4920
|
+
}
|
|
4785
4921
|
function isPreparedError(prepared) {
|
|
4786
4922
|
return "status" in prepared;
|
|
4787
4923
|
}
|