@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/index.cjs
CHANGED
|
@@ -42,6 +42,17 @@ function operationError(code, message, options = {}) {
|
|
|
42
42
|
...options.details === void 0 ? {} : { details: options.details }
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
function storageFullOperationError(error) {
|
|
46
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
47
|
+
const { code, meta } = error;
|
|
48
|
+
if (code !== "STORAGE_QUOTA_EXCEEDED" && code !== "STORAGE_LIMIT_REACHED") return void 0;
|
|
49
|
+
const account = typeof meta === "object" && meta !== null ? meta.account : void 0;
|
|
50
|
+
return operationError(
|
|
51
|
+
"STORAGE_QUOTA_EXCEEDED",
|
|
52
|
+
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}`,
|
|
53
|
+
{ retryable: false, ...account === void 0 ? {} : { details: { account } } }
|
|
54
|
+
);
|
|
55
|
+
}
|
|
45
56
|
function isOperationErrorCode(value) {
|
|
46
57
|
return typeof value === "string" && OPERATION_ERROR_CODES.includes(value);
|
|
47
58
|
}
|
|
@@ -67,7 +78,7 @@ function sanitizeOperationError(error) {
|
|
|
67
78
|
...candidate.details === void 0 ? {} : { details: candidate.details }
|
|
68
79
|
});
|
|
69
80
|
}
|
|
70
|
-
var OPERATION_ERROR_CODES, OperationInvocationError;
|
|
81
|
+
var OPERATION_ERROR_CODES, MANAGE_STORAGE, OperationInvocationError;
|
|
71
82
|
var init_errors = __esm({
|
|
72
83
|
"src/errors.ts"() {
|
|
73
84
|
"use strict";
|
|
@@ -90,6 +101,7 @@ var init_errors = __esm({
|
|
|
90
101
|
"ENCRYPTION_NETWORK_UNRESOLVED",
|
|
91
102
|
"NODE_UNREACHABLE",
|
|
92
103
|
"NODE_ERROR",
|
|
104
|
+
"STORAGE_QUOTA_EXCEEDED",
|
|
93
105
|
"KV_NOT_FOUND",
|
|
94
106
|
"KV_PRECONDITION_FAILED",
|
|
95
107
|
"KV_CONFLICT",
|
|
@@ -103,6 +115,7 @@ var init_errors = __esm({
|
|
|
103
115
|
"OUTPUT_INVALID",
|
|
104
116
|
"INTERNAL_ERROR"
|
|
105
117
|
];
|
|
118
|
+
MANAGE_STORAGE = "Do not retry: the owner must free up space or upgrade at https://account.tinycloud.xyz/billing.";
|
|
106
119
|
OperationInvocationError = class extends Error {
|
|
107
120
|
constructor(operationError2) {
|
|
108
121
|
super(operationError2.message);
|
|
@@ -344,8 +357,13 @@ function canonicalizeRecapCaveats(caveats) {
|
|
|
344
357
|
}
|
|
345
358
|
return `[${branches.join(",")}]`;
|
|
346
359
|
}
|
|
360
|
+
function isExplicitOnlyAction(action) {
|
|
361
|
+
return Object.prototype.hasOwnProperty.call(EXPLICIT_ONLY_ACTIONS, action);
|
|
362
|
+
}
|
|
347
363
|
function actionContains(grantedAction, requestedAction) {
|
|
348
|
-
if (grantedAction ===
|
|
364
|
+
if (grantedAction === requestedAction) return true;
|
|
365
|
+
if (isExplicitOnlyAction(requestedAction)) return false;
|
|
366
|
+
if (grantedAction === "*") return true;
|
|
349
367
|
if (!grantedAction.endsWith("/*")) return false;
|
|
350
368
|
const service = grantedAction.slice(0, -2);
|
|
351
369
|
return requestedAction === service || requestedAction.startsWith(`${service}/`);
|
|
@@ -370,10 +388,15 @@ function cloneEntry(entry) {
|
|
|
370
388
|
...entry.expiry !== void 0 ? { expiry: entry.expiry } : {}
|
|
371
389
|
};
|
|
372
390
|
}
|
|
391
|
+
var EXPLICIT_ONLY_ACTIONS;
|
|
373
392
|
var init_capabilities = __esm({
|
|
374
393
|
"../sdk-core/src/capabilities.ts"() {
|
|
375
394
|
"use strict";
|
|
376
395
|
init_manifest();
|
|
396
|
+
EXPLICIT_ONLY_ACTIONS = {
|
|
397
|
+
"tinycloud.kv/sync": true,
|
|
398
|
+
"tinycloud.kv/retain": true
|
|
399
|
+
};
|
|
377
400
|
}
|
|
378
401
|
});
|
|
379
402
|
|
|
@@ -698,7 +721,8 @@ async function acquireProfileLock(profile, options) {
|
|
|
698
721
|
const lockPath = profileLockPath(profile);
|
|
699
722
|
const turnDirectory = profileTurnLockPath(profile);
|
|
700
723
|
const directory = profilePath(profile);
|
|
701
|
-
|
|
724
|
+
if (options.requireProfile && !await exists(profileConfigPath(profile))) throw new ProfileDeletedError(profile);
|
|
725
|
+
if (!options.requireProfile) await (0, import_promises.mkdir)(directory, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
702
726
|
await (0, import_promises.mkdir)((0, import_node_path.dirname)(turnDirectory), { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
703
727
|
for (const path of [tinycloudHomePath(), profilesPath(), directory]) {
|
|
704
728
|
await (0, import_promises.chmod)(path, PRIVATE_DIR_MODE).catch((error) => {
|
|
@@ -707,11 +731,15 @@ async function acquireProfileLock(profile, options) {
|
|
|
707
731
|
}
|
|
708
732
|
const { turn, firstWaitedTurn } = await acquireTurn(profile, turnDirectory, deadline);
|
|
709
733
|
try {
|
|
734
|
+
if (options.requireProfile && !await exists(profileConfigPath(profile))) {
|
|
735
|
+
await (0, import_promises.rmdir)(directory).catch(() => void 0);
|
|
736
|
+
throw new ProfileDeletedError(profile);
|
|
737
|
+
}
|
|
710
738
|
const deletion = await readJson((0, import_node_path.join)(turnDirectory, "deleted.json")).catch(() => null);
|
|
711
739
|
const deletedWhileWaiting = typeof deletion?.slot === "number" && deletion.slot >= firstWaitedTurn;
|
|
712
740
|
while (true) {
|
|
713
741
|
const token = (0, import_node_crypto.randomUUID)();
|
|
714
|
-
if (await publishProfileLock(profile, lockPath, token)) {
|
|
742
|
+
if (await publishProfileLock(profile, lockPath, token, options.requireProfile === true)) {
|
|
715
743
|
return {
|
|
716
744
|
deletedWhileWaiting,
|
|
717
745
|
turnSlot: turn.slot,
|
|
@@ -956,12 +984,13 @@ async function collectTurns(profile, turn) {
|
|
|
956
984
|
}
|
|
957
985
|
}
|
|
958
986
|
}
|
|
959
|
-
async function publishProfileLock(profile, lockPath, token) {
|
|
987
|
+
async function publishProfileLock(profile, lockPath, token, requireProfile) {
|
|
960
988
|
try {
|
|
961
989
|
await (0, import_promises.mkdir)(lockPath, { mode: PRIVATE_DIR_MODE });
|
|
962
990
|
} catch (error) {
|
|
963
991
|
if (isErrno(error, "EEXIST")) return false;
|
|
964
992
|
if (!isErrno(error, "ENOENT")) throw error;
|
|
993
|
+
if (requireProfile) throw new ProfileDeletedError(profile);
|
|
965
994
|
await (0, import_promises.mkdir)(profilePath(profile), { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
966
995
|
return false;
|
|
967
996
|
}
|
|
@@ -2532,6 +2561,8 @@ function kvFailure(error, action) {
|
|
|
2532
2561
|
if (error.code === "KV_RESPONSE_TOO_LARGE") {
|
|
2533
2562
|
return { status: "error", error: operationError("KV_RESPONSE_TOO_LARGE", `The TinyCloud KV value exceeds ${MAX_KV_VALUE_BYTES} bytes.`) };
|
|
2534
2563
|
}
|
|
2564
|
+
const storageFull = storageFullOperationError(error);
|
|
2565
|
+
if (storageFull) return { status: "error", error: storageFull };
|
|
2535
2566
|
return nodeFailure(action);
|
|
2536
2567
|
}
|
|
2537
2568
|
function nodeFailure(action) {
|
|
@@ -3150,7 +3181,7 @@ async function executeSqlDml(context, input) {
|
|
|
3150
3181
|
const runtime = runtimeContext2(context);
|
|
3151
3182
|
const space = resolveSqlSpace(runtime, input.space);
|
|
3152
3183
|
const result = await runtimeNode2(runtime).sqlForSpace(space).db(input.database).execute(input.sql, input.params.map(decodeSqlInputValue));
|
|
3153
|
-
if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure();
|
|
3184
|
+
if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure(result.error);
|
|
3154
3185
|
const normalized = normalizeExecuteResult(result.data);
|
|
3155
3186
|
return {
|
|
3156
3187
|
status: "ok",
|
|
@@ -3164,7 +3195,7 @@ async function executeSqlDml(context, input) {
|
|
|
3164
3195
|
};
|
|
3165
3196
|
} catch (error) {
|
|
3166
3197
|
if (error instanceof OperationInvocationError) return { status: "error", error: error.operationError };
|
|
3167
|
-
return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure();
|
|
3198
|
+
return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure(error);
|
|
3168
3199
|
}
|
|
3169
3200
|
}
|
|
3170
3201
|
function isSingleReadQuery(sql) {
|
|
@@ -3341,7 +3372,9 @@ function sqlServiceFailure(error, action) {
|
|
|
3341
3372
|
}
|
|
3342
3373
|
return nodeFailure2(action);
|
|
3343
3374
|
}
|
|
3344
|
-
function sqlMutationFailure() {
|
|
3375
|
+
function sqlMutationFailure(error) {
|
|
3376
|
+
const storageFull = storageFullOperationError(error);
|
|
3377
|
+
if (storageFull) return { status: "error", error: storageFull };
|
|
3345
3378
|
return {
|
|
3346
3379
|
status: "error",
|
|
3347
3380
|
error: operationError(
|
|
@@ -3598,6 +3631,32 @@ ORDER BY type, name`;
|
|
|
3598
3631
|
}
|
|
3599
3632
|
});
|
|
3600
3633
|
|
|
3634
|
+
// src/contract.ts
|
|
3635
|
+
var STORED_GRANT_SKIP_REASONS, DELEGATION_CID_PATTERN;
|
|
3636
|
+
var init_contract = __esm({
|
|
3637
|
+
"src/contract.ts"() {
|
|
3638
|
+
"use strict";
|
|
3639
|
+
STORED_GRANT_SKIP_REASONS = [
|
|
3640
|
+
"malformed",
|
|
3641
|
+
"unbound",
|
|
3642
|
+
"outside_request",
|
|
3643
|
+
"host_mismatch",
|
|
3644
|
+
"expired",
|
|
3645
|
+
"cid_mismatch",
|
|
3646
|
+
"authority_invalid",
|
|
3647
|
+
"proof_missing",
|
|
3648
|
+
"proof_invalid",
|
|
3649
|
+
"owner_mismatch",
|
|
3650
|
+
"audience_mismatch",
|
|
3651
|
+
"resources_mismatch",
|
|
3652
|
+
"unsupported",
|
|
3653
|
+
"activation_rejected",
|
|
3654
|
+
"invalid"
|
|
3655
|
+
];
|
|
3656
|
+
DELEGATION_CID_PATTERN = "^bafkr4i[a-z2-7]{52}$";
|
|
3657
|
+
}
|
|
3658
|
+
});
|
|
3659
|
+
|
|
3601
3660
|
// src/delegation-binding.ts
|
|
3602
3661
|
function bindingMigrationPath(profile) {
|
|
3603
3662
|
return (0, import_node_path2.join)(profilePath(profile), "delegation-binding-migration.json");
|
|
@@ -3621,12 +3680,12 @@ function replayLimit(entry, migrated) {
|
|
|
3621
3680
|
if (binding.success) return binding.data.requested;
|
|
3622
3681
|
return !migrated && kind === "compact" && !("authorityRequest" in entry) ? "signed" : void 0;
|
|
3623
3682
|
}
|
|
3624
|
-
function
|
|
3683
|
+
function bindToRequest(record, requested, source, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3625
3684
|
return {
|
|
3626
3685
|
...record,
|
|
3627
3686
|
authorityRequest: DelegationRequestBindingSchema.parse({
|
|
3628
3687
|
requestId: `${REQUEST_ID_PREFIX[source]}:${record.delegation.cid}`,
|
|
3629
|
-
requested: structuredClone(
|
|
3688
|
+
requested: structuredClone(requested)
|
|
3630
3689
|
}),
|
|
3631
3690
|
authorityRequestAudit: { source, recordedAt, note: BINDING_NOTES[source] }
|
|
3632
3691
|
};
|
|
@@ -3682,23 +3741,40 @@ async function migratedRecord(node, entry, host, recordedAt) {
|
|
|
3682
3741
|
const signed = await signedCapabilities(node, delegation, host);
|
|
3683
3742
|
if (signed === void 0) return void 0;
|
|
3684
3743
|
try {
|
|
3685
|
-
return
|
|
3744
|
+
return bindToRequest({ ...entry, delegation: { ...entry.delegation, cid: delegation.cid } }, signed, "migration", recordedAt);
|
|
3686
3745
|
} catch {
|
|
3687
3746
|
return void 0;
|
|
3688
3747
|
}
|
|
3689
3748
|
}
|
|
3749
|
+
function skipped(reason) {
|
|
3750
|
+
return { status: "skipped", reason };
|
|
3751
|
+
}
|
|
3690
3752
|
async function replayStoredDelegation(node, entry, options) {
|
|
3753
|
+
const kind = storedDelegationKind(entry);
|
|
3691
3754
|
const delegation = normalizeStoredDelegation(entry);
|
|
3692
|
-
if (
|
|
3755
|
+
if (kind === "refused" || delegation === void 0) return skipped("malformed");
|
|
3756
|
+
if (delegation.expiry.getTime() <= Date.now()) return NOT_REPLAYED;
|
|
3757
|
+
if (kind === "other") return skipped("proof_missing");
|
|
3693
3758
|
const limit = replayLimit(entry, options.migrated);
|
|
3694
|
-
if (limit === void 0) return
|
|
3695
|
-
|
|
3759
|
+
if (limit === void 0) return skipped("unbound");
|
|
3760
|
+
let outsideRequest = false;
|
|
3761
|
+
const authorize = limit === "signed" ? () => true : (effective) => {
|
|
3762
|
+
outsideRequest = !delegationWithinRequest(limit, effective, options.resolveSpace);
|
|
3763
|
+
return !outsideRequest;
|
|
3764
|
+
};
|
|
3696
3765
|
try {
|
|
3697
|
-
return
|
|
3698
|
-
|
|
3699
|
-
|
|
3766
|
+
return {
|
|
3767
|
+
status: "installed",
|
|
3768
|
+
delegation: await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, { host: options.host, authorize })
|
|
3769
|
+
};
|
|
3770
|
+
} catch (error) {
|
|
3771
|
+
return skipped(outsideRequest ? "outside_request" : rejectionReason(error));
|
|
3700
3772
|
}
|
|
3701
3773
|
}
|
|
3774
|
+
function rejectionReason(error) {
|
|
3775
|
+
const reason = isRecord4(error) ? error.reason : void 0;
|
|
3776
|
+
return typeof reason === "string" && STORED_GRANT_SKIP_REASONS.includes(reason) ? reason : "invalid";
|
|
3777
|
+
}
|
|
3702
3778
|
async function bindingMigrationRecorded(profile) {
|
|
3703
3779
|
try {
|
|
3704
3780
|
return await readJson(bindingMigrationPath(profile)) !== null;
|
|
@@ -3743,7 +3819,7 @@ function recordKey(entry) {
|
|
|
3743
3819
|
function isRecord4(value) {
|
|
3744
3820
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3745
3821
|
}
|
|
3746
|
-
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS;
|
|
3822
|
+
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS, NOT_REPLAYED;
|
|
3747
3823
|
var init_delegation_binding = __esm({
|
|
3748
3824
|
"src/delegation-binding.ts"() {
|
|
3749
3825
|
"use strict";
|
|
@@ -3751,17 +3827,21 @@ var init_delegation_binding = __esm({
|
|
|
3751
3827
|
nodeSdk3 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
3752
3828
|
init_artifacts();
|
|
3753
3829
|
init_authority();
|
|
3830
|
+
init_contract();
|
|
3754
3831
|
init_state();
|
|
3755
3832
|
init_secrets();
|
|
3756
3833
|
REQUEST_ID_PREFIX = {
|
|
3757
3834
|
migration: "migrated",
|
|
3758
|
-
"unbound-import": "unbound-import"
|
|
3835
|
+
"unbound-import": "unbound-import",
|
|
3836
|
+
"cli-grant": "cli-grant"
|
|
3759
3837
|
};
|
|
3760
3838
|
BINDING_NOTES = {
|
|
3761
3839
|
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.",
|
|
3762
|
-
"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."
|
|
3840
|
+
"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.",
|
|
3841
|
+
"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."
|
|
3763
3842
|
};
|
|
3764
3843
|
MIGRATION_LOCK_TIMEOUT_MS = 250;
|
|
3844
|
+
NOT_REPLAYED = { status: "not-replayed" };
|
|
3765
3845
|
}
|
|
3766
3846
|
});
|
|
3767
3847
|
|
|
@@ -4173,7 +4253,18 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4173
4253
|
));
|
|
4174
4254
|
}
|
|
4175
4255
|
} else {
|
|
4176
|
-
|
|
4256
|
+
try {
|
|
4257
|
+
await node.restoreSession(activeSession);
|
|
4258
|
+
} catch (error) {
|
|
4259
|
+
if (isRecord7(error) && error.code === "AUTH_EXPIRED") {
|
|
4260
|
+
return failed(summary, operationError(
|
|
4261
|
+
"AUTH_REQUIRED",
|
|
4262
|
+
"The stored session has expired or is no longer valid. Sign in again.",
|
|
4263
|
+
{ retryable: false }
|
|
4264
|
+
));
|
|
4265
|
+
}
|
|
4266
|
+
throw error;
|
|
4267
|
+
}
|
|
4177
4268
|
}
|
|
4178
4269
|
const activeSessionDid = normalizeDid(node.sessionDid);
|
|
4179
4270
|
const livePrincipalDid = normalizeDid(node.did);
|
|
@@ -4181,6 +4272,7 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4181
4272
|
const livePermissions = [...node.getVerifiedSessionCapabilities()];
|
|
4182
4273
|
const resolveSpace2 = operationSpaceResolver(node, authenticatedSpace ?? summary.space);
|
|
4183
4274
|
const seenCids = /* @__PURE__ */ new Set();
|
|
4275
|
+
const warnings = [];
|
|
4184
4276
|
if (!explicitPrivateKeyOverride) {
|
|
4185
4277
|
const activator = node;
|
|
4186
4278
|
const migrated = await prepareStoredDelegationReplay(profileName, activator, {
|
|
@@ -4190,20 +4282,25 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4190
4282
|
migrate: activeSession !== void 0
|
|
4191
4283
|
});
|
|
4192
4284
|
for (const entry of await readAdditionalDelegations(profileName)) {
|
|
4193
|
-
const
|
|
4285
|
+
const replay = await replayStoredDelegation(activator, entry, {
|
|
4194
4286
|
host: summary.host,
|
|
4195
4287
|
migrated,
|
|
4196
4288
|
resolveSpace: resolveSpace2
|
|
4197
4289
|
});
|
|
4198
|
-
if (
|
|
4199
|
-
seenCids.
|
|
4200
|
-
|
|
4290
|
+
if (replay.status === "installed") {
|
|
4291
|
+
if (!seenCids.has(replay.delegation.cid)) {
|
|
4292
|
+
seenCids.add(replay.delegation.cid);
|
|
4293
|
+
livePermissions.push(...replay.delegation.effectivePermissions);
|
|
4294
|
+
}
|
|
4295
|
+
} else if (replay.status === "skipped") {
|
|
4296
|
+
warnings.push(skippedGrantWarning(node, entry, replay.reason));
|
|
4201
4297
|
}
|
|
4202
4298
|
}
|
|
4203
4299
|
}
|
|
4204
4300
|
const runtime = {
|
|
4205
4301
|
node,
|
|
4206
|
-
granted: canonicalizeCapabilities(livePermissions)
|
|
4302
|
+
granted: canonicalizeCapabilities(livePermissions),
|
|
4303
|
+
...warnings.length === 0 ? {} : { warnings }
|
|
4207
4304
|
};
|
|
4208
4305
|
return {
|
|
4209
4306
|
ok: true,
|
|
@@ -4227,6 +4324,24 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4227
4324
|
));
|
|
4228
4325
|
}
|
|
4229
4326
|
}
|
|
4327
|
+
function skippedGrantWarning(node, entry, reason) {
|
|
4328
|
+
const grantCid = verifiedStoredCid(node, entry);
|
|
4329
|
+
return { code: "STORED_GRANT_SKIPPED", reason, ...grantCid === void 0 ? {} : { grantCid } };
|
|
4330
|
+
}
|
|
4331
|
+
function verifiedStoredCid(node, entry) {
|
|
4332
|
+
const delegation = isRecord7(entry) && isRecord7(entry.delegation) ? entry.delegation : void 0;
|
|
4333
|
+
const header = isRecord7(delegation?.delegationHeader) ? delegation.delegationHeader : void 0;
|
|
4334
|
+
const cid = delegation?.cid;
|
|
4335
|
+
const computeDelegationCid = isRecord7(node) ? node.computeDelegationCid : void 0;
|
|
4336
|
+
if (typeof cid !== "string" || typeof header?.Authorization !== "string" || typeof computeDelegationCid !== "function") {
|
|
4337
|
+
return void 0;
|
|
4338
|
+
}
|
|
4339
|
+
try {
|
|
4340
|
+
return computeDelegationCid.call(node, header.Authorization) === cid && DELEGATION_CID.test(cid) ? cid : void 0;
|
|
4341
|
+
} catch {
|
|
4342
|
+
return void 0;
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4230
4345
|
function spaceForAuthenticatedPrincipal(principal2) {
|
|
4231
4346
|
if (principal2 === void 0) return void 0;
|
|
4232
4347
|
try {
|
|
@@ -4275,17 +4390,19 @@ function unresolvedSummary(target) {
|
|
|
4275
4390
|
posture: "unauthenticated"
|
|
4276
4391
|
};
|
|
4277
4392
|
}
|
|
4278
|
-
var nodeSdk4;
|
|
4393
|
+
var nodeSdk4, DELEGATION_CID;
|
|
4279
4394
|
var init_runtime = __esm({
|
|
4280
4395
|
"src/runtime.ts"() {
|
|
4281
4396
|
"use strict";
|
|
4282
4397
|
nodeSdk4 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
4398
|
+
init_contract();
|
|
4283
4399
|
init_authority();
|
|
4284
4400
|
init_errors();
|
|
4285
4401
|
init_profile();
|
|
4286
4402
|
init_secrets();
|
|
4287
4403
|
init_state();
|
|
4288
4404
|
init_delegation_binding();
|
|
4405
|
+
DELEGATION_CID = new RegExp(DELEGATION_CID_PATTERN);
|
|
4289
4406
|
}
|
|
4290
4407
|
});
|
|
4291
4408
|
|
|
@@ -4590,8 +4707,19 @@ var SAFE_ERROR_DETAIL_POLICIES = {
|
|
|
4590
4707
|
DELEGATION_HOST_MISMATCH: {
|
|
4591
4708
|
expectedHost: safeOriginHost,
|
|
4592
4709
|
artifactHost: safeOriginHost
|
|
4710
|
+
},
|
|
4711
|
+
STORAGE_QUOTA_EXCEEDED: {
|
|
4712
|
+
account: safeStorageAccount
|
|
4593
4713
|
}
|
|
4594
4714
|
};
|
|
4715
|
+
function safeStorageAccount(value) {
|
|
4716
|
+
if (!isRecord(value)) return void 0;
|
|
4717
|
+
const { usedBytes, limitBytes, plan } = value;
|
|
4718
|
+
if (!Number.isSafeInteger(usedBytes) || usedBytes < 0 || !Number.isSafeInteger(limitBytes) || limitBytes <= 0) {
|
|
4719
|
+
return void 0;
|
|
4720
|
+
}
|
|
4721
|
+
return typeof plan === "string" && /^[A-Za-z0-9][A-Za-z0-9 _.-]{0,31}$/.test(plan) ? { usedBytes, limitBytes, plan } : { usedBytes, limitBytes };
|
|
4722
|
+
}
|
|
4595
4723
|
function redactSafeErrorDetails(code, details) {
|
|
4596
4724
|
const policy = SAFE_ERROR_DETAIL_POLICIES[code];
|
|
4597
4725
|
if (policy === void 0) return void 0;
|
|
@@ -4657,9 +4785,13 @@ async function invokeOperation(operationId, operationVersion, invocationTarget,
|
|
|
4657
4785
|
unknownInput
|
|
4658
4786
|
);
|
|
4659
4787
|
if (isPreparedError(prepared)) return prepared.result;
|
|
4660
|
-
return executePreparedInvocation(prepared);
|
|
4788
|
+
return withRuntimeWarnings(await executePreparedInvocation(prepared), prepared);
|
|
4661
4789
|
});
|
|
4662
4790
|
}
|
|
4791
|
+
function withRuntimeWarnings(result, prepared) {
|
|
4792
|
+
const warnings = prepared.runtimeResolution.context.runtime?.warnings;
|
|
4793
|
+
return warnings === void 0 || warnings.length === 0 ? result : { ...result, warnings: [...warnings] };
|
|
4794
|
+
}
|
|
4663
4795
|
function isPreparedError(prepared) {
|
|
4664
4796
|
return "status" in prepared;
|
|
4665
4797
|
}
|